Bluedroid和Bluez相比,有如下优点:
- 层次结构清晰。各个profile对上层接口统一,便于增加新的profile;增加了HAL层,便于移植。
- 去掉了DBus,Framework的Java代码直接调用到Bluedroid的Native代码。
目前有一些Android 4.1或4.2的设备是支持BLE的,但是都是采用的Vendor自己的解决方案,比如Bluetooth stack采用Bluez 5.x,再提供Vendor BLE Android SDK. 现在Android 4.3已经发布,从未来发展趋势来看,如果有人要学习Bluetooth in Android,建议不要再研究Bluez,最好转向Bluedroid。
以下是Android 4.2中Bluetooth相关代码之分布:
android.bluetooth | frameworks/base/core/java/android/bluetooth | implements public API for the Bluetooth adapter and profiles |
Bluetooth system service | packages/apps/Bluetooth/src | implements service and profiles at the Android fraework layer |
Bluetooth JNI | packages/apps/Bluetooth/jni | defines Bluetooth adapter and profiles service JNI: calls into HAL and receives callback from HAL |
Bluetooth HAL | hardware/libhardware/include/hardware/bt_*.h files | defines the standard interface that the android.bluetooth adapter and profiles APIs |
Bluetooth stack | external/bluetooth/bluedroid | implement bluetooth stack: core and profiles |
以Pan profile为例,我们可以看看代码的具体分布和类及文件的命名方式:
android.bluetooth | frameworks | public class BluetoothPan implements BluetoothProfile |
Bluetooth System Service | packages/apps | public class PanService extends ProfileService |
Bluetooth JNI | packages/apps | com_android_bluetooth_pan.cpp |
Bluetooth HAL | hardware/libhardware | include/hardware/bt_pan.h |
Bluetooth stack | external/bluetooth | bluedroid/btif/src/btif_pan.c(implements bt_pan.h) |
bluedroid/bta/pan (Broadcom BTA) | ||
bluedroid/stack/pan (Broadcom BTE) |
AVRCP(Audio/Video Remote Control Profile)提供了如下主要功能:
- 通过蓝牙耳机(比如Sony WM600,SBH50)或车载控制台控制手机上音乐播放
- 在蓝牙耳机或车载控制台上显示手机上音乐播放的状态,歌名,歌手等信息
- 在蓝牙耳机或车载控制台上浏览手机上的音乐文件,显示播放列表
以下是基于Android 4.2代码,对Bluetooth BR/EDR Enable process的分析。BluetoothAdapter类代表的是local device Bluetooth adapter,而BluetoothDevice类代表的是remote Bluetooth device。在Android 4.3中引入了一个新的类BluetoothManager,它是一个high level manager,被用于”to obtain an instance of an BluetoothAdapter and conduct overall Bluetooth Management“。
Bluetooth Enable process比较复杂,层次比较多,最好的分析方法是:对照logcat输出的Bluetooth相关log来阅读代码。首先从总体上介绍以下Enable process。UI上的入口是Settings,拨动Bluetooth开关,就启动了Bluetooth Enable process,最后由Bluedroid去enable Bluetooth hardware。当Bluetooth hardware enabled,这个enabled消息会一层层从Bluedroid上传到UI层,Settings收到这个消息就可以更新Bluetooth开关的状态了。具体过程如下图:
- Settings的BluetoothEnabler类(对应于UI上看到的Bluetooth开关),得到代表local device的BluetoothAdapter,再调用BluetoothAdapter::enable()。
- BluetoothAdapter基本上是个wrapper,不做具体的事情的。它直接调用BluetoothManagerService::enable()。
- BluetoothManagerService利用Binder机制会去connect AdapterService,最终会导致AdapterService::enable()被调用。BluetoothManagerService还会向AdapterService注册callback函数,用于接收Adapter State Change消息。
- AdapterService维护着一个状态机AdapterState,所有工作都是通过驱动状态机来完成的。AdapterState收到AdapterService发过来的USER_TURN_ON消息,就会调用AdapterService::processStart()来启动Profie Services的初始化和Bluetooth hardware enable process。此时Bluetooth Adapter的状态是BluetoothAdapter.STATE_TURNING_ON。
- 每一个profile都有一个service。每个profile service启动完成后,都会通知AdapterService。当AdapterService::processProfileServiceStateChanged()确认所有的profile services都启动完成了,就会给状态机AdapterState发AdapterState.STARTED消息。
- 状态机AdapterState::PendingCommandState::processMessage()收到AdapterState.STARTED消息后就立刻调用AdapterService::enableNative()。
- AdapterService::enableNative()就是用来enable Bluetooth的Bluetooth JNI接口。enableNative()会调用Bluetooth HAL的enable()。
- Bluedroid用btif_enable_bluetooth()来实现了Bluetooth HAL的enable()。
- 当Bluedroid真正完成了enable Bluetooth hardware,就通过btif_enable_bluetooth_evt()中的HAL_CBACK调用Bluetooth JNI的adapter_state_change_callback(),这样就把BT_STATE_ON消息传递给了状态机AdapterState。
- AdapterState会把Bluetooth Adapter的状态转换到BluetoothAdapter.STATE_ON,并通过AdapterState::notifyAdapterStateChanged()通知AdapterService。
- AdapterService::updateAdapterState()会通过callback函数通知BluetoothManagerService,Adapter状态改变了。
- BluetoothManagerService确认状态发生了改变就会发出一个BluetoothAdapter.ACTION_STATE_CHANGE的intent。
- Settings的BluetoothEnabler收到这个intent之后,就会去更新UI上Bluetooth开关的状态。