蓝牙主要分为两种模式,一种是媒体输出(Source)端,一种是媒体输入(Sink)端。也可以理解为服务端(Server)与客户端(Client)的关系。
蓝牙配置文件(Bluetooth Profile):是适用于设备间蓝牙通信的无线接口规范。从 Android 3.0 开始,Bluetooth API 便支持使用蓝牙配置文件。举个例子:免提配置文件。如果手机要与无线耳机进行连接,则两台设备都必须支持免提配置文件。
一、蓝牙协议配置文件
1、文件路径
A:手机(Source),配置路径
packages/apps/Bluetooth/res/values/config.xml
B:蓝牙耳机、车载等设备(Sink),配置路径
packages/services/Car/car_product/overlay/packages/apps/Bluetooth/res/values/config.xml
C:高通配置路径
device/qcom/common/product/overlay/packages/apps/Bluetooth/res/values/config.xml
对于手机这类设备的Android系统中蓝牙协议配置就是 A+C 共同作用的结果,而对于车载设备的 Android 系统中蓝牙协议配置则是 A+B+C 共同作用的结果。
对于手机设备:A<C
对于车载蓝牙设备:A<B<C
2、 overlay介绍
android overlay 机制允许在不修改 packages 中 apk 的情况下,来自定义 framework 和package 中的资源文件,实现资源的定制。来达到显示不同的 ui 的目的(例如MIUI)。
原理是在通过AAPT打包成APK时,通过-S命令多增加了一个资源目录(overlay目录),我们平时打包APK只是通过AAPT -S指定了一个资源目录,而Overlay又额外增加了一个资源目录。AAPT -S命令可以指定多个资源目录,overlay的资源将替换原res中的重名文件。
同时还需要配置多个 mk 中的变量,这里对 overlay 机制就不做过多介绍,只需要知道他是一个资源覆盖的机制就可以了。这道了这些对于上面的路径就可以看出来,B、C 中 overlay 后面所覆盖的路径都是 A(packages/apps/Bluetooth/res/values/config.xml)路径。
参考:Android overlay机制
二、配置文件解析
1、手机(Source)的配置文件
<resources>
<!-- 设备的角色(hfp client / hfp server)-->
<bool name="profile_supported_hs_hfp">true</bool>
<bool name="profile_supported_hfpclient">false</bool>
<bool name="profile_supported_hfp_incallservice">true</bool>
<!-- 蓝牙音频模式(Source or Sink) -->
<bool name="profile_supported_a2dp">true</bool>
<bool name="profile_supported_a2dp_sink">false</bool>
<!-- 文件传输功能 -->
<bool name="profile_supported_opp">true</bool>
<!-- 作为Source端,控制手机的声音播放,暂停,音量大小等功能 -->
<bool name="profile_supported_avrcp_target">true</bool>
<!-- 作为sink端,控制手机的声音播放,暂停,音量大小等功能 -->
<bool name="profile_supported_avrcp_controller">false</bool>
<bool name="profile_supported_hid_host">true</bool>
<bool name="profile_supported_pan">true</bool>
<bool name="profile_supported_pbap">true</bool>
<bool name="profile_supported_gatt">true</bool>
<bool name="pbap_include_photos_in_vcard">true</bool>
<bool name="pbap_use_profile_for_owner_vcard">true</bool>
<bool name="profile_supported_map">true</bool>
<bool name="profile_supported_sap">false</bool>
<bool name="profile_supported_pbapclient">false</bool>
<bool name="profile_supported_mapmce">false</bool>
<bool name="profile_supported_hid_device">true</bool>
<!-- 启用电话策略 -->
<bool name="enable_phone_policy">true</bool>
</resources>
上面仅列出 config.xml 的部分代码,根据命名很好理解对应的协议是否启用。
2、车机(Sink)的配置文件
<resources>
<!-- 禁用源配置文件(通常用于电话) -->
<bool name="profile_supported_a2dp">false</bool>
<bool name="profile_supported_avrcp_target">false</bool>
<bool name="profile_supported_hs_hfp">false</bool>
<bool name="profile_supported_hid_device">false</bool>
<bool name="profile_supported_hid_host">false</bool>
<bool name="profile_supported_pbap">false</bool>
<bool name="profile_supported_map">false</bool>
<bool name="profile_supported_hdp">false</bool>
<bool name="profile_supported_opp">false</bool>
<bool name="profile_supported_sap">false</bool>
<bool name="enable_phone_policy">false</bool>
<!-- 启用接收器配置文件(通常用于CarKitt) -->
<bool name="profile_supported_hfpclient">true</bool>
<bool name="hfp_client_connection_service_enabled">true</bool>
<bool name="profile_supported_avrcp_controller">true</bool>
<bool name="avrcp_controller_enable_cover_art">true</bool>
<bool name="profile_supported_a2dp_sink">true</bool>
<bool name="profile_supported_pbapclient">true</bool>
<bool name="profile_supported_pan">true</bool>
<bool name="profile_supported_mapmce">true</bool>
</resources>
这里是车载设备 config.xml 的全部代码,其中车载设备的 enable_phone_policy 属性必须设置为 false,以免 CarBluetoothService 中的 Automotive 政策冲突与手机默认连接政策冲突,影响车载设备自动重连功能。
3、高通的配置文件
文件路径:device/qcom/common/product/overlay/packages/apps/Bluetooth/res/values/config.xml
device/qcom/:文件夹下对应着很多高通不同型号的配置文件。
common:通用配置文件夹。
overlay:可以看到,这个文件覆盖的是 /packages/apps/Bluetooth/res/values/config.xml 文件。
高通的这些配置文件,源码中并不存在(device/qcom/ 路径都不存在),都是后续添加的,通过查看 Android 9.0 的项目源码,config.xml 代码如下:
<resources>
<bool name="profile_supported_avrcp_controller">true</bool>
<bool name="profile_supported_a2dp_sink">true</bool>
<bool name="profile_supported_sap">true</bool>
<bool name="profile_supported_hid_device">false</bool>
<bool name="profile_supported_ba">true</bool>
</resources>
同时在 Android 12.0 源码的 /device/amlogic/yukawa/overlay/packages/apps/Bluetooth/res/values/config.xml 中发现蓝牙配置相关信息。代码如下:
<resources>
<bool name="profile_supported_a2dp">false</bool>
<bool name="profile_supported_hs_hfp">false</bool>
<bool name="profile_supported_pbap">false</bool>
<bool name="profile_supported_map">false</bool>
<bool name="profile_supported_hdp">false</bool>
<bool name="profile_supported_opp">false</bool>
<bool name="profile_supported_hfpclient">false</bool>
<bool name="hfp_client_connection_service_enabled">false</bool>
<bool name="profile_supported_pbapclient">false</bool>
<bool name="profile_supported_pan">false</bool>
<bool name="profile_supported_mapmce">false</bool>
<bool name="profile_supported_hid_host">true</bool>
<bool name="profile_supported_avrcp_target">true</bool>
<bool name="profile_supported_avrcp_controller">true</bool>
<bool name="profile_supported_a2dp_sink">true</bool>
</resources>
通过上面的分析,车载安卓系统常用的蓝牙协议:
信息访问协议:profile_supported_mapmce —— MapClientService
电话免提协议:profile_supported_hfpclient —— HeadsetClientService
电话本访问协议:profile_supported_pbapclient —— PbapClientService
高级音频分发协议:profile_supported_a2dp_sink —— A2dpSinkService
音视频远程控制协议:profile_supported_avrcp_controller —— AvrcpControllerService