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;
            }
        }
相关推荐
峥嵘life1 小时前
五一南昌第三天游玩记录:梅景寻芳,母校忆旧,摩天轮揽夜
android
qq_452396232 小时前
第三篇:《JMeter断言:验证接口响应正确性》
android·jmeter
aqi003 小时前
一文速览 HarmonyOS 6.0.1 引入的十个新特性
android·华为·harmonyos·鸿蒙·harmony
橙子199110164 小时前
Android 第三方框架 相关
android
赏金术士4 小时前
JetPack Compose 弹窗、菜单、交互组件(五)
android·kotlin·交互·android jetpack·compose
海天鹰5 小时前
高版本安卓老应用下面空白
android
猫的玖月5 小时前
(七)函数
android·数据库·sql
秋95 小时前
java中对操作mysql8.0.46与MySQL9.7.0有什么区别,并举例说明
android·java·adb