AAOS CarPowerManager

文章目录

提供什么服务? 如何提供的?

  • 作用是什么?

电源管理, 车上面的状态可能有很多中,比如在车库,停车,短时间停车等等。每种模式可能需要的功耗策略都不一样。

就需要一个模块对车的各个部分进行控制。

  • 基本原理

车辆的状态停车、熄火等等状态通过vehicle hal 通知到carpowerservice, 在service 中去控制各个模块的on off。

(音频模块的on off 是通过设置stric mode 的方式 控制carauioservice, 具体就是不是safe 和emergency的音频流类型 请求焦点都会失败,也就是这些类型的声音类型都播放不出来)

基础的carpowerpolicyd的服务

  • 对应的carpowerpolicyd.rc文件
    属于early_hal. service名字为carpowerpolicyd
  • 对应的main函数

启动CarPowerPolicyServer,传递是外部创建好的looper,启动调用iniit进行初始化。

init包括PolicyManager的init、componetHandlder的注册、然后将服务注册到serviceMananger。最后调用ConnetcToVhal。

    mHandlerLooper = looper;
    mPolicyManager.init();
    mComponentHandler.init();
    mSilentModeHandler.init();

connectToVhal();
  • PolicyManager的init
  1. mRegisteredPowerPolicies构造,主要是构造两个默认的regular的powerPolicy

    一个policy 的id是kSystemPolicyIdAllOn,这里所有component都是on的状态。

    一个polocy的id是kSystemPolicyIdInitialOn,这里打开kInitialOnComponents里面定义的Component。

  2. mPreemptivePowerPolicies的构造,这个是抢占式的powerPolicy。

    也是创建两个powerPolicy 分别为 kSystemPolicyIdNoUserInteraction、kSystemPolicyIdSuspendToRam

    两个policy都有默认的

  3. 从文件中读取powerpolicy配置

    是从/vendor/etc/automotive/power_policy.xml读取配置,其中配置是按照具体的policy id 和 模块的open 和on

    读取的配置存储在

    mRegisteredPowerPolicies 和 mPolicyGroups。

    其中mRegisteredPowerPolicies存储 policy的名字policy_id_other_untouched和具体的policy。

    mPolicyGroups存储policyGroup的名字

  • connect to vhal
  1. vhal的连接 获取vehicle的服务,连接不上时候 会间隔200ms进行尝试,最多尝试25次。也就是1s连接不上就直接返回失败了。
  2. 配置默认的powerpolicy, 这个powerpolicy是之前init从文件power_policy.xml中读取到的。
  3. subscribe
    VehicleProperty::POWER_POLICY_GROUP_REQ
    VehicleProperty::POWER_POLICY_REQ
    这两个属性,当vhal有这两个属性变化的时间上报的时候,获取属性的值,并设置对应的powerpolicy。

其存储的xml

<powerPolicy version="1.0">

<policyGroups>
<policyGroup id="mixed_policy_group">
<defaultPolicy state="WaitForVHAL" id="policy_id_other_on"/>
<noDefaultPolicy state="On"/>
</policyGroup>
</policyGroups>

<policy id="policy_id_other_untouched">
<otherComponents behavior="untouched"/>
<component id="POWER_COMPONENT_AUDIO">on</component>
<component id="POWER_COMPONENT_DISPLAY">on</component>
<component id="POWER_COMPONENT_BLUETOOTH">on</component>
<component id="POWER_COMPONENT_WIFI">on</component>
<component id="POWER_COMPONENT_VOICE_INTERACTION">on</component>
<component id="POWER_COMPONENT_VISUAL_INTERACTION">on</component>
<component id="POWER_COMPONENT_TRUSTED_DEVICE_DETECTION">on</component>
</policies>

</powerPolicy>

CarPowerManagerService 与其他服务和 HAL 协调电源状态。CPMS 实现上述状态机,并在发生电源状态转换时向每个观察者发送通知。carPower服务会通过VHAL 和硬件的MCU进行通信。

###  整体的框架

carPowerManager(java/c++) ------> CarPowerManagerService

跟CarAudioSevice框架类型,提供给外部的carPowerMananger,(java和c++两套接口)。

然后通过AIDL调用到CarPowerManangerService 中。

  • 常用接口 设置carPowerPolicy的监听
    carAudioService 根据电源的状态做相应的处理。
    获取service 然后设置监听。 当power policy发生变化的时候回调到onPolicyChanged
    在onPolicyChanged 中 将音频关闭,通过CarAudioService设置标志位,让不是safe 和 emergancy
    的音频 请求焦点都失败。

同样 在 CarMediaService 中也会监听powerchange的事件,对于powerpolicy中componet状态变化进行处理。 比如component off状态的,设置状态为pause。在播放的MediaSession进行暂停。

    void startListeningForPolicyChanges() {
        if (mCarPowerManagementService == null) {
            Slog.w(TAG, "Cannot find CarPowerManagementService");
            mCarAudioService.setAudioEnabled(/* isAudioEnabled= */ true);
            return;
        }
        CarPowerPolicyFilter filter = new CarPowerPolicyFilter.Builder()
                .setComponents(AUDIO).build();
        mCarPowerManagementService.addPowerPolicyListener(filter, mChangeListener);
        initializePowerState();
    }

    private final ICarPowerPolicyListener mChangeListener =
            new ICarPowerPolicyListener.Stub() {
                @Override
                public void onPolicyChanged(CarPowerPolicy policy,
                        CarPowerPolicy accumulatedPolicy) {
                    synchronized (mLock) {
                        if (mIsAudioEnabled != accumulatedPolicy.isComponentEnabled(AUDIO)) {
                            updateAudioPowerStateLocked(accumulatedPolicy);
                        }
                    }
                }
            };


    @GuardedBy("mLock")
    private void updateAudioPowerStateLocked(CarPowerPolicy policy) {
        mIsAudioEnabled = policy.isComponentEnabled(AUDIO);
        Slog.w(TAG, "Policy mIsAudioEnabled" + mIsAudioEnabled);
        mCarAudioService.setAudioEnabled(mIsAudioEnabled);
    }
}

    void setAudioEnabled(boolean isAudioEnabled) {
        if (Slogf.isLoggable(CarLog.TAG_AUDIO, Log.DEBUG)) {
            Slogf.d(CarLog.TAG_AUDIO, "Setting isAudioEnabled to %b", isAudioEnabled);
        }
        mFocusHandler.setRestrictFocus(/* isFocusRestricted= */ !isAudioEnabled);
        if (mUseCarVolumeGroupMuting) {
            mCarVolumeGroupMuting.setRestrictMuting(/* isMutingRestricted= */ !isAudioEnabled);
        }
        // TODO(b/176258537) if not using group volume, then set master mute accordingly
    }

carAudioFocus.java

    void setRestrictFocus(boolean isFocusRestricted) {
        synchronized (mLock) {
            mIsFocusRestricted = isFocusRestricted;
            if (mIsFocusRestricted) {
                abandonNonCriticalFocusLocked();
            }
        }
    }

    public void onAudioFocusRequest(AudioFocusInfo afi, int requestResult) {
        int response;
        AudioPolicy policy;
        AudioFocusInfo replacedDelayedAudioFocusInfo = null;
        synchronized (mLock) {
            policy = mAudioPolicy;
            response = evaluateFocusRequestLocked(afi);
        }
        // Post our reply for delivery to the original focus requester
        mAudioManager.setFocusRequestResult(afi, response, policy);
        logFocusEvent("onAudioFocusRequest for client " + afi.getClientId()
                + " with gain type " + focusEventToString(afi.getGainRequest())
                + " resulted in " + focusRequestResponseToString(response));
    }


    private int evaluateFocusRequestLocked(AudioFocusInfo afi) {
        Slog.i(TAG, "Evaluating  + focusEventToString(afi.getGainRequest())
                + " request for client " + afi.getClientId()
                + " with usage " + afi.getAttributes().usageToString());
         
        Slog.i(TAG, "mIsFocusRestricted  " + mIsFocusRestricted);      
        if (mIsFocusRestricted) {
            int audioContext = CarAudioContext.getContextForAttributes(afi.getAttributes());
            if (!isCriticalAudioContext(audioContext)) {
                Slog.i(TAG, "audioContext " + audioContext + "request failed");
                return AudioManager.AUDIOFOCUS_REQUEST_FAILED;
            }
        }
相关推荐
帅得不敢出门9 小时前
安卓设备adb执行AT指令控制电话卡
android·adb·sim卡·at指令·电话卡
我又来搬代码了11 小时前
【Android】使用productFlavors构建多个变体
android
德育处主任12 小时前
Mac和安卓手机互传文件(ADB)
android·macos
芦半山12 小时前
Android“引用们”的底层原理
android·java
迃-幵13 小时前
力扣:225 用队列实现栈
android·javascript·leetcode
大风起兮云飞扬丶13 小时前
Android——从相机/相册获取图片
android
Rverdoser13 小时前
Android Studio 多工程公用module引用
android·ide·android studio
aaajj14 小时前
[Android]从FLAG_SECURE禁止截屏看surface
android
@OuYang14 小时前
android10 蓝牙(二)配对源码解析
android
Liknana14 小时前
Android 网易游戏面经
android·面试