Android蓝牙-设备类型之getMajorDeviceClass

废话

做蓝牙framework已经一年多了,前段时间不太忙,自己做了一个蓝牙demo,遇到坑也不少,在这里记录一下,以便以后碰到能迅速查阅
设备连接的时候需要通过设备的类型来创建不同的profile:
int deviceType = device.getBluetoothClass().getMajorDeviceClass();
下面来一步步分析底层是怎么得到这个deviceType

先看device.getBluetoothClass(),
找到framework/base/core/java/android/bluetooth/BluetoothDevice.java

图一
这个方法返回一个BluetoothClass
找到 framework/base/core/java/android/Bluetooth/BluetoothClass.java

图二
返回了一个mClass&Device.Major.BITMASK
接下来先看Device.Major.BITMASK是哪里来的,都是些设备类型computer,phone …,感兴趣可以看看下面还有具体的类型computer,phone等都又做了细分,都是16进制的数

图三
接下来找mClass是从哪里来的
图四
很明显是构造方法传过来的,回头上去看第一个图,从new BluetoothClass(classInt) 传过来的,
Int classInt = sService.getRemoteClass(this)而classInt是从sService.getRemoteClass(this),
接下来找到sService是谁,是AdapterService,怎么来的特别复杂,涉及到跨进程,
可以专门写一篇来解释,如果有空的话,
下面打开
package/apps/Bluetooth/src/com/android/Bluetooth/btservice/AdapterService.java
图五
Return service.getRemoteClass(device),这个service就是它自己,继续看
图六
又出来一个DeviceProperties,从RemoteDevices里get来的,接着打开
package/apps/Bluetooth/src/com/android/Bluetooth/btservice/RemoteDevices.java

图七
图八
DeviceProperties是通过device的address从集合里面取的,而上上上张图片上RemoteClass
是通过deviceProperties.getBluetoothClass()来的,下面看看DeviceProperties里面都有啥

图九
可以看到getBluetoothClass返回了一个mBluetoothClass,继续追寻,这个mBluetoothClass是在什么地方赋值的

图10
由于这个方法特别长,只截取一部分,方法名为devicePropertyChangedCallback(),
此方法是底层扫描到设备同过jni回调上来的,只要扫描到设备,底层会回调2个方法,devicePropertyChangedCallback()和deviceFoundCallback(),以下是方法的截图,

图11
图12
从deviceFoundCallback()方法可以看出,framework收到底层驱动的回调就会发送一个
ACTION_FOUND广播,携带着扫描到的设备的信息,而devicePropertyChangedCallback()中将底层返回来的设备信息解析存入DeviceProperties供调用,以下是扫描到单个设备后的打印信息

图13
可以看出扫描到设备,先调用的是devicePropertyChangedCallback,将设备信息解析储存,然后调用的
deviceFoundCallback将携带设备信息的广播发出去

经过测试OPPO R11s的MajorDeviceClass是512,电脑的是256, 从上面的截图上看Phone和computer分别是0x0200和0x0100,他们&上Device.Major.BITMASK的 0x1f00 ,转换成10进制,正好是512和256