AAOS CarPowerManager

文章目录

      • 提供什么服务? 如何提供的?
      • 基础的carpowerpolicyd的服务

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

  • 作用是什么?

电源管理, 车上面的状态可能有很多中,比如在车库,停车,短时间停车等等。每种模式可能需要的功耗策略都不一样。
就需要一个模块对车的各个部分进行控制。

  • 基本原理

车辆的状态停车、熄火等等状态通过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












on
on
on
on
on
on
on





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;
            }
        }




你可能感兴趣的:(android,CarService)