9. android 动态音频策略的原理

基于Android 11 aosp 源码分析。

目录

理解

AudioManager.java, 提供了注册外部策略的接口:

注入的mAudioPolicy包含了什么信息:

外部策略如何被系统触发:

音量控制

 焦点请求

设备选择      


扫描二维码关注公众号,回复: 14804160 查看本文章

理解

针对与Car,  Android 将音频策略部分,通过提供外部(app 层)注入的方式,放在更加灵活的 app java层来实现。

        以前的android基本为了手机设计,输出设备相对较少也不会给应用来控制,应用只是给一个stream类型,由AudioPolicy在底层根据你的stream类型偷偷地给你选一个设备,现在android要用于车机,发现这些音频设备变多了,手机上的那一套做很难满足需求,为了即保留对原来手机的逻辑支持,有可在车机上自定义更高级的策略玩法,于是想了个办法,把所有设备对应什么用途这些定义不再是直接写在AudioPolicy里面了,而是可以通过函数的方式注入进来,这样这些设备用途的定义,都可以放在更加灵活的app层面来做,并且不光是设备的usage定义,还有音量控制,音频焦点请求等这些逻辑一样,都可以先把回调注入 进来。

如此,对于手机上的场景,可以使用默认的策略,对于汽车,只需要再添加一个app,把新的策略注册进去即可覆盖替换原先的策略。 这个支持app层注册音频规则和控制回调的策略,即动态策略,它包括了 设备选择(mix规则)、音量控制(分频分区域控制音量)、音频焦点申请这三个策略。
 

AudioManager.java, 提供了注册外部策略的接口:

@TestApi @SystemApi @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public int registerAudioPolicy(@NonNull AudioPolicy policy) {

return registerAudioPolicyStatic(policy);

}

 有了这个接口,mix规则就可以放在 app 层实现,通过这个方法注入进去。当然,不是所有app都能随意注册,需要systemapp , 需要MODIFY_AUDIO_ROUTING权限

默认不注册动态策略,也就是传统的手机设备,如果在车机,只需要 加入这么一个系统app,在app层实现动态策略然后注入,底层即可适配。

注入的mAudioPolicy包含了什么信息:

  注入这里的AudioPolicy.java 它和 底层AudioPolicyServer里面的AudioPolicy没什么关系,仅仅是用来包含这个动态策略的一个类而已。AudioManager.java作为java层对外提供的api,大部分时候也只是一个空壳,内部还是通过调用AudioServer.java ,而AudioServer.java再调用音频系统总功能AudioSystem.cpp 在java层的接口AudioSystem.java
AudioServer
 

 AudioService.java::
  public String registerAudioPolicy(AudioPolicyConfig policyConfig, IAudioPolicyCallback pcb,
            boolean hasFocusListener, boolean isFocusPolicy, boolean isTestFocusPolicy,
            boolean isVolumeController, IMediaProjection projection) {
            ...
            if (isFocusPolicy) {
                // 1.0 焦点控制的回调,
                    ...
                    mMediaFocusControl.setFocusPolicy(mPolicyCallback,     mIsTestFocusPolicy);
            }
            
            if (mIsVolumeController) {
                // 2.0 音量控制的回调
                setExtVolumeController(mPolicyCallback);
            }
            
            // 3.0 mix规则
             connectMixes(){
                     ....
                AudioSystem.registerPolicyMixes(mMixes, true);
             }
            }
        

外部策略如何被系统触发:

音量控制

按音量+-键,系统会触发AudioServer.java的 adjustSuggestedStreamVolume(),如果注册了外部音量控制器,就直接由外部控制器处理音量事件。在AudioServer.java中,通过notifyExternalVolumeController() 全部交给外部策略来控制,处理完即返回

 焦点请求

  app通过AudioManager.java接口请求获取焦点 requestAudioFocus(), 如果注入了外部焦点策略,就通知外部策略模块处理焦点请求。

   在MediaFocusControl.java中,通过notifyExtFocusPolicyFocusRequest_syncAf()交给外部策略处理,外部处理完策略,可以通过 AudioManager.java::setFocusRequestResult()

  ( ->AudioServer.java::setFocusRequestResultFromExtPolicy()->MediaFocusControl.java::setFocusRequestResultFromExtPolicy() )

  将结果设置回来,由AudioManager 把结果发给引用层通知app其焦点发送变化,如果是有framework强制duck的,AudioMnager在发送结果的同时还会让MediFocusControl执行duck操作,外部策略只需要处理焦点策略逻辑。


设备选择      

        则是AudioSystem.registerPolicyMixes() 直接注册到AudioPolicy中的,用于设备选择的规则。

猜你喜欢

转载自blog.csdn.net/u012459903/article/details/127788340