• 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();
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 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
    
    
    
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    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;
                }
            }
    
    
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
  • 相关阅读:
    推荐几个开源类库,超好用,早用找下班
    集群容器部署和管理(Docker&K8S)
    Go语言进化之路:泛型的崛起与复用的新篇章
    hadoop 数据抽取
    (附源码)ssm考试题库管理系统 毕业设计 069043
    Mac 安装 protobuf 和Android Studio 使用
    【贪心算法】:LeetCode860.柠檬水找零
    SpringBoot中Bean无法加载的原因,以及Bean的扫描方式
    Python推导式(列表推导式、元组推导式、字典推导式、集合推导式)
    Windows10环境下Python解析pacp文件
  • 原文地址:https://blog.csdn.net/H2008066215019910120/article/details/134254822