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


    基于Android 11 aosp 源码分析。

     

    目录

    理解

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

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

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

    音量控制

     焦点请求

    设备选择      


    理解

    针对与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
     

    1. AudioService.java::
    2. public String registerAudioPolicy(AudioPolicyConfig policyConfig, IAudioPolicyCallback pcb,
    3. boolean hasFocusListener, boolean isFocusPolicy, boolean isTestFocusPolicy,
    4. boolean isVolumeController, IMediaProjection projection) {
    5. ...
    6. if (isFocusPolicy) {
    7. // 1.0 焦点控制的回调,
    8. ...
    9. mMediaFocusControl.setFocusPolicy(mPolicyCallback, mIsTestFocusPolicy);
    10. }
    11. if (mIsVolumeController) {
    12. // 2.0 音量控制的回调
    13. setExtVolumeController(mPolicyCallback);
    14. }
    15. // 3.0 mix规则
    16. connectMixes(){
    17. ....
    18. AudioSystem.registerPolicyMixes(mMixes, true);
    19. }
    20. }

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

    音量控制

    按音量+-键,系统会触发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中的,用于设备选择的规则。

  • 相关阅读:
    java毕业设计超市商品管理mybatis+源码+调试部署+系统+数据库+lw
    20221130如何修改OBS录屏的存储路径?
    【零基础入门MyBatis系列】第八篇——使用MyBatis的小技巧
    Layui快速入门之第十四节 分页
    R语言ggHoriPlot包绘制地平线图
    vulnhub Potato: 1
    关于前端研发质量提升的建设思路
    SSH实现简单在线听音乐收藏管理系统
    java计算机毕业设计社区物品交易系统源码+系统+数据库+lw文档+mybatis+运行部署
    Cockpit -- 一个通过浏览器监控和管理多台Linux服务器的强大工具
  • 原文地址:https://blog.csdn.net/u012459903/article/details/127788340