Android13 蓝牙协议属性配置详解

发布于:2024-06-16 ⋅ 阅读:(19) ⋅ 点赞:(0)

Android13 蓝牙协议属性配置详解

一、前言

Android系统中蓝牙协议是否使能一般是通过一个属性值,如果这个属性值设置为false,

会导致这个协议的服务未启动,也就是说这个蓝牙功能会没有作用。

比如 Android 蓝牙传输文件协议是opp,如果opp未使能,那么整个系统是不支持蓝牙文件传输的。

在Android13之前的版本,我们可以通过 config.xml 中的 profile_supported_a2dp 属性控制蓝牙的某个协议是否使能。

比如Android13 以前的蓝牙协议使能属性:

    <bool name="profile_supported_a2dp">true</bool>
    <bool name="profile_supported_a2dp_sink">true</bool>
    <bool name="profile_supported_hs_hfp">true</bool>
    <bool name="profile_supported_hfpclient">false</bool>

这些属性是res属性,只能在资源文件中修改,还不方便查询。

但是在Android13 或者更新的版本,很多属性都需要一个新的东西控制使能蓝牙协议了,那就是蓝牙属性profile属性。

Android13 以及更新的版本蓝牙协议使能属性:

bluetooth.profile.a2dp.source.enabled=true
bluetooth.profile.avrcp.target.enabled=true
...
bluetooth.profile.opp.enabled=true
bluetooth.profile.a2dp.sink.enabled=true

这些属性是prop属性,非常方便查询,直接修改的话,估计可以,但是重启会失效。

这个东西如果没有了解过,是无从下手的,蓝牙的profile属性读取和控制在Java代码中是找不到的。

如果想要学习了解,可以继续往下看看。

本文简单参考:https://blog.csdn.net/weixin_47456647/article/details/139493190

二、Android13 蓝牙协议属性配置

蓝牙的协议属性虽然都是prop属性,但是无法代码中并不是直接判断prop属性决定使能,

而是使用Profile提供的接口,判断蓝牙协议是否使能。

1、Profile 属性和暴露接口的定义

system\libsysprop\srcs\android\sysprop\BluetoothProperties.sysprop

注意,下面的代码只是定义蓝牙prop属性和关联Java Api方法的地方,具体赋值是在其他地方。

module: "android.sysprop.BluetoothProperties"
owner: Platform
...
# Whether the Advanced Audio Distribution Profile (A2DP) Sink role is enabled on this device.
# Set by vendors overlay, read at Bluetooth initialization
prop {
    api_name: "isProfileA2dpSinkEnabled" //暴露的api
    type: Boolean
    scope: Public
    access: Readonly
    prop_name: "bluetooth.profile.a2dp.sink.enabled"
}

 //系统Java代码中调用 BluetoothProperties.isProfileA2dpSinkEnabled()就能查到对于的prop属性
 //这也是为啥Java代码中没有直接获取 bluetooth.profile 属性的原因。

# Whether the Advanced Audio Distribution Profile (A2DP) Source role is enabled on this device.
# Set by vendors overlay, read at Bluetooth initialization
prop {
    api_name: "isProfileA2dpSourceEnabled"
    type: Boolean
    scope: Public
    access: Readonly
    prop_name: "bluetooth.profile.a2dp.source.enabled"
}

# BR/EDR Page scan activity configuration
prop {
    api_name: "getClassicPageScanType"
    type: UInt
    scope: Internal
    access: Readonly
    prop_name: "bluetooth.core.classic.page_scan_type"
}

...

这个文件主要就是绑定某些api和prop属性的关联。

可以看到上面定义的access 都是只读,说明直接修改不一定有用。

在系统的java代码中,只要调用静态方法:BluetoothProperties.XXX()就可以判断某个协议属性是否使能了。

2、蓝牙协议属性定义

prop属性的默认值一般是通过XXX.mk文件进行设置默认值的

但是不同的供应商方案的系统可能定义的方式不一样。

比如 aml Android14 311D2方案 修改的路径:

PRODUCT_PROPERTY_OVERRIDES += \
    bluetooth.profile.asha.central.enabled=true \
    bluetooth.profile.gatt.enabled=true \
    bluetooth.profile.hid.host.enabled=true \
    bluetooth.profile.mcp.server.enabled=true \
    bluetooth.profile.opp.enabled=true \
    bluetooth.profile.pan.nap.enabled=true \
    bluetooth.profile.pan.panu.enabled=true

比如 mtk Android14 9679方案 修改的路径:

device\mediatek\mt5879\configs\bluetooth.prop

bluetooth.device.class_of_device=40,4,60
bluetooth.profile.a2dp.source.enabled?=false
bluetooth.profile.avrcp.target.enabled?=true
bluetooth.profile.bas.client.enabled?=true
···
bluetooth.profile.opp.enabled?=false  //默认为false,设置true才能正常传输文件

这种看起来是供应商自定义的,不像上面mk文件定义是原生的。

网上看有些mtk方案也有写在 device.mk里面定义prop属性的,还有些其他方案的会定义在其他xxx.mk

如果不确定定义在哪里,就在源码里面全局搜索一下吧,命令:

//搜索其中一个比较注意的prop属性关键字
grep -nr "bluetooth.profile.avrcp.target.enabled"
//或者
grep -nr "bluetooth.profile.opp.enabled"

还可以搜索过来某些文件进行搜索
find . -name "*.mk" | xargs grep "bluetooth.profile.opp.enabled"
find . -name "*.prop" | xargs grep "bluetooth.profile.opp.enabled"

这样就能知道其他蓝牙协议属性定义的地方了。

大部分方案都是定义在 device、vendor目录下,也有小概率定义在package、hardware、framework、prebuilts等目录。

3、系统代码中判断蓝牙协议是否使能的代码

packages\modules\Bluetooth\android\app\src\com\android\bluetooth\a2dp\A2dpService.java

    //是否支持蓝牙声音功能,蓝牙连接耳机后声音从耳机发出
    public static boolean isEnabled() {
        return BluetoothProperties.isProfileA2dpSourceEnabled().orElse(false);
    }

每个蓝牙协议服务都在类似的判断静态方法,从而判断是否支持该协议。

其他的蓝牙协议服务也是类似的方式进行判断是否使能。

正式代码中未看到有直接判断prop 属性的方式,判断蓝牙是否使能的代码:

boolean isEnableXXX = SystemProperties.getBoolean("XXX", false);

全局搜索后,看到在某个Test的类中有这个使用。所以是不建议这样使用的。

但是也不是不能这样使用,特别是普通应用中,或没有导入framework Jar包的系统应用中都是有可能无法调用到 BluetoothProperties 这个类的,可以使用这个方法进行判断属性的方式判断蓝牙协议是否使能。

三、其他

1、adb 窗口中查看蓝牙协议属性

console:/ # getprop | grep  bluetooth.profile                                  
[bluetooth.profile.a2dp.source.enabled]: [true]
[bluetooth.profile.asha.central.enabled]: [true]
[bluetooth.profile.avrcp.target.enabled]: [true]
[bluetooth.profile.gatt.enabled]: [true]
[bluetooth.profile.hfp.ag.enabled]: [true]
[bluetooth.profile.hid.host.enabled]: [true]
[bluetooth.profile.mcp.server.enabled]: [true]
[bluetooth.profile.opp.enabled]: [true]
[bluetooth.profile.pan.nap.enabled]: [true]
[bluetooth.profile.pan.panu.enabled]: [true]
console:/ # 

getprop 过滤蓝牙相关prop,就能看到所有的蓝牙协议相关属性。

2、动态设置蓝牙prop协议属性有用吗

从打印日志看打开蓝牙的时候蓝牙相关的协议服务会进行重启,

关闭蓝牙蓝牙相关的协议服务会关闭。

所以理论上,动态修改蓝牙prop属性,在关开一次蓝牙,那么就会修改生效。

目前我只试过 bluetooth.profile.opp.enabled 确实是可以动态修改的,其他属性不确定。

3、opp协议为false时蓝牙文件传输相关日志

AML Android14 上 蓝牙相关日志:

06-14 16:22:49.238  8759  8791 I bluetooth: packages/modules/Bluetooth/system/gd/hci/hci_layer.cc:119 drop: Dropping event MAX_SLOTS_CHANGE
06-14 16:22:49.242  8759  8759 I BluetoothPhonePolicy: processDeviceConnected, device=XX:XX:XX:XX:16:0E
06-14 16:22:49.242  8759  8759 D BluetoothDatabase: setConnection: device XX:XX:XX:XX:16:0E and isA2dpDevice=false
06-14 16:22:49.242  8759  8759 D BluetoothDatabase: Updating last connected time for device: XX:XX:XX:XX:16:0E to 2
06-14 16:22:49.242  8759  8759 D BluetoothDatabase: updateDatabase XX:XX:XX:XX:16:0E
06-14 16:22:49.248  8759  8791 I bluetooth: packages/modules/Bluetooth/system/main/shim/acl.cc:558 OnReadClockOffsetComplete: UNIMPLEMENTED
06-14 16:22:49.306  8759  8786 I l2c_csm : packages/modules/Bluetooth/system/stack/l2cap/l2c_csm.cc:338 l2c_csm_closed: Check security for psm 0x0001, status 0
06-14 16:22:49.320  8759  8786 W bt_sdp  : packages/modules/Bluetooth/system/main/bte_logmsg.cc:108 LogMsg: PBAP PSE dynamic version upgrade is not enabled
06-14 16:22:49.325  8759  8786 W bt_sdp  : packages/modules/Bluetooth/system/main/bte_logmsg.cc:108 LogMsg: SDP - Rcvd L2CAP disc, process pend sdp ccb: 0x42
06-14 16:22:49.334  8759  8786 I l2c_csm : packages/modules/Bluetooth/system/stack/l2cap/l2c_csm.cc:338 l2c_csm_closed: Check security for psm 0x0001, status 0
06-14 16:22:49.345  8759  8786 W bt_sdp  : packages/modules/Bluetooth/system/main/bte_logmsg.cc:108 LogMsg: PBAP PSE dynamic version upgrade is not enabled
06-14 16:22:49.351  8759  8786 W bt_sdp  : packages/modules/Bluetooth/system/main/bte_logmsg.cc:108 LogMsg: SDP - Rcvd L2CAP disc, process pend sdp ccb: 0x43

06-14 16:22:53.352  8759  8786 W l2c_link: packages/modules/Bluetooth/system/stack/l2cap/l2c_link.cc:521 l2c_link_timeout: TODO: Remove this callback into bcm_sec_disconnect
06-14 16:22:53.352  8759  8786 I btm_acl : packages/modules/Bluetooth/system/stack/acl/btm_acl.cc:205 hci_btsnd_hcic_disconnect: Disconnecting peer:xx:xx:xx:xx:16:0e reason:HCI_ERR_PEER_USER comment:stack::l2cap::l2c_link::l2c_link_timeout All channels closed
06-14 16:22:53.438  8759  8786 E btm_sco : packages/modules/Bluetooth/system/stack/btm/btm_sco.cc:1137 btm_sco_on_disconnected: Unable to find sco connection
06-14 16:22:53.438  8759  8786 I btm_acl : packages/modules/Bluetooth/system/stack/acl/btm_acl.cc:2740 btm_acl_iso_disconnected: ISO disconnection from GD, handle: 0x0b, reason: 0x16
06-14 16:22:53.439  8759  8786 I btif_av : packages/modules/Bluetooth/system/btif/src/btif_av.cc:3565 btif_av_acl_disconnected: btif_av_acl_disconnected: Peer xx:xx:xx:xx:16:0e : ACL Disconnected

这是手机端发送后,接收端的蓝牙相关日志;

从日志未看出啥明显异常,也没有提示opp服务无法开启,但是只有ACL连接和断开的日志。

这里仅供参考。不同方案上可能有区别。

4、Android11 蓝牙协议详解

https://blog.csdn.net/wenzhi20102321/article/details/125826972

相关协议知识:

拨号网络配置文件 (DUN):
DUN 提供了通过 Bluetooth 无线技术接入 Internet 和其它拨号服务的标准。
最常见的情况是在手机上拨号,从膝上型计算机以无线方式接入 Internet。

OPP:对象存储规范(Object Push Profile),最为常见的,文件的传输都是使用此协议。


HFP:(Hands-free Profile),让蓝牙设备可以控制电话,如接听、挂断、拒接、语音拨号等,拒接、语音拨号要视蓝牙耳机及电话是否支持。


HDP: HDP (Health Device Profile) 蓝牙医疗设备模式   可以创建支持蓝牙的医疗设备,使用蓝牙通信的应用程序,例如心率监视器,血液,温度计和秤。

HID() 人机接口设备配置文件
HID 配置文件定义了 Bluetooth HID(如键盘、指向设备、游戏设备及远程监视设备)使用的协议、程序及功能

HSP(Handset Profile)耳机模式 ,用于支持蓝牙耳机与移动电话之间使用


A2DP: Advanced Audio Distribution Profile (A2DP) 高级音频传输模式  A2DP是能够采用耳机内的芯片来堆栈数据,达到声音的高清晰度。有A2DP的耳机就是蓝牙立体声耳机。
PAN:个人局域网(Personal Area Network)最新为了满足需求而出现的, 在小范围内能够将个人设备(自己的手机 电脑笔记本等)互联而组成的网络。


DP( Service Discovery Protocol )服务发现协议
提供应用程序在蓝牙环境中发现哪个服务可用和决定那些可用服务的特征。

GAP(Generic Access Profile)通用访问应用
一般访问应用规范定义了蓝牙设备如何发现和建立与其他设备的安全(或不安全)连接。
它处理一些一般模式的业务(如询问、命名和搜索)和一些安全性问 题(如担保),
同时还处理一些有关连接的业务(如链路建立、信道和连接建立)。GAP规定的是一些一般性的运行任务。
因此,它具有强制性,并作为所有其它 蓝牙应用规范的基础。

不同的Android版本对蓝牙协议的设置代码不同,但是蓝牙协议的基本知识是一样的。