基于Android9.0 Amlogic代码分析, 蓝牙应用通过 Binder 与蓝牙进程进行通信。蓝牙进程使用 JNI 与蓝牙堆栈通信,并向开发者提供对各种蓝牙配置文件的访问权限。下图显示了蓝牙堆栈的常规结构:
fluoride_architecture.png
应用框架
client:
frameworks/base/core/java/android/bluetooth/*
servie:
framework/base/services/core/java/com/android/server/BluetoothService.java
framework/base/services/core/java/com/android/server/BluetoothManagerService.java
这部分主要提供给app调用的api,跟其他系统服务一样,分为client端和service端,通过binder通讯
蓝牙系统服务 蓝牙系统服务(位于 packages/apps/Bluetooth 中)被打包为 Android 应用,并在 Android 框架层实现蓝牙服务和配置文件。此应用通过 JNI 调用原生蓝牙堆栈。
JNI 与 android.bluetooth 相关联的 JNI 代码位于 packages/apps/Bluetooth/jni 中。当发生特定蓝牙操作时(例如发现设备时),JNI 代码会调用蓝牙堆栈。
蓝牙堆栈 AOSP 中提供了默认蓝牙堆栈(位于 system/bt 中)。该堆栈实现常规蓝牙 HAL,并通过扩展程序和更改配置对其进行自定义
供应商实现 供应商设备使用硬件接口设计语言 (HIDL) 与蓝牙堆栈交互。
android 蓝牙framework层跟其他系统服务有点不同,framework层的service主要是跟bluetooth app的sercive进行绑定,大部分功能逻辑都是在bluetooth app实现
mManagerService在打开蓝牙的时候会间接调用到handleEnable方法,handleEnable的dobind会绑定BluetoothService,回调到BluetoothServiceConnection方法中把service赋值给mBluetooth,这样我们就可以拿到Bluetooth app里的service(AdapterService)进行操作了
//打开蓝牙的时候会间接调用到handleEnable方法
private void handleEnable(boolean quietMode) {
mQuietEnable = quietMode;
try {
mBluetoothLock.writeLock().lock();
if ((mBluetooth == null) && (!mBinding)) {
//绑定bluetooth app Service
if (!doBind(i, mConnection, Context.BIND_AUTO_CREATE | Context.BIND_IMPORTANT,
UserHandle.CURRENT)) {
mHandler.removeMessages(MESSAGE_TIMEOUT_BIND);
} else {
mBinding = true;
}
} else if (mBluetooth != null) {
}
} finally {
mBluetoothLock.writeLock().unlock();
}
}
boolean doBind(Intent intent, ServiceConnection conn, int flags, UserHandle user) {
ComponentName comp = intent.resolveSystemService(mContext.getPackageManager(), 0);
intent.setComponent(comp);
if (comp == null || !mContext.bindServiceAsUser(intent, conn, flags, user)) {
Slog.e(TAG, "Fail to bind to: " + intent);
return false;
}
return true;
}
private BluetoothServiceConnection mConnection = new BluetoothServiceConnection();
private class BluetoothServiceConnection implements ServiceConnection {
public void onServiceConnected(ComponentName componentName, IBinder service) {
String name = componentName.getClassName();
if (DBG) {
Slog.d(TAG, "BluetoothServiceConnection: " + name);
}
//service绑定成功后,会回调。第一步是先绑定AdapterService,
//之后通过AdapterService 去启动GattService,并且
Message msg = mHandler.obtainMessage(MESSAGE_BLUETOOTH_SERVICE_CONNECTED);
if (name.equals("com.android.bluetooth.btservice.AdapterService")) {
msg.arg1 = SERVICE_IBLUETOOTH;
} else if (name.equals("com.android.bluetooth.gatt.GattService")) {
msg.arg1 = SERVICE_IBLUETOOTHGATT;
} else {
Slog.e(TAG, "Unknown service connected: " + name);
return;
}
msg.obj = service;
mHandler.sendMessage(msg);
}
public void onServiceDisconnected(ComponentName componentName) {
}
}
case MESSAGE_BLUETOOTH_SERVICE_CONNECTED: {
if (DBG) {
Slog.d(TAG, "MESSAGE_BLUETOOTH_SERVICE_CONNECTED: " + msg.arg1);
}
IBinder service = (IBinder) msg.obj;
try {
mBluetoothLock.writeLock().lock();
if (msg.arg1 == SERVICE_IBLUETOOTHGATT) {
mBluetoothGatt =
IBluetoothGatt.Stub.asInterface(Binder.allowBlocking(service));
continueFromBleOnState();
break;
} // else must be SERVICE_IBLUETOOTH
//Remove timeout
mHandler.removeMessages(MESSAGE_TIMEOUT_BIND);
mBinding = false;
mBluetoothBinder = service;
mBluetooth = IBluetooth.Stub.asInterface(Binder.allowBlocking(service));
//Do enable request
try {
if (!mQuietEnable) {
if (!mBluetooth.enable()) {
Slog.e(TAG, "IBluetooth.enable() returned false");
}
} else {
if (!mBluetooth.enableNoAutoConnect()) {
Slog.e(TAG, "IBluetooth.enableNoAutoConnect() returned false");
}
}
}
和bluetooth app service绑定成功后,BluetoothManagerService会获取到bluetooth app 两个service binder对象 mBluetooth 绑定的是 AdapterService mBluetoothGatt 绑定的是 GattService
frame_app.png
总结:
相对详细的流程看下节分析
Bluetooth apk是蓝牙功能逻辑具体的实现。常规打开关闭功能在AdapterService入口实现。这些方法最后跟踪都会跟踪到native方法上
上层或设置同过enable接口打开蓝牙时,会调用到AdapterService.java的接口enable,大体时序图如下所示:
SequenceDiagram1.png
AdapterService通过AdapterState进行状态转换
private AdapterState mAdapterStateMachine;
public synchronized boolean enable(boolean quietMode) {
...
mAdapterStateMachine.sendMessage(AdapterState.BLE_TURN_ON);
}
AdapterState.java代码片段
private TurningOnState mTurningOnState = new TurningOnState();
private TurningBleOnState mTurningBleOnState = new TurningBleOnState();
private TurningOffState mTurningOffState = new TurningOffState();
private TurningBleOffState mTurningBleOffState = new TurningBleOffState();
private OnState mOnState = new OnState();
private OffState mOffState = new OffState();
private BleOnState mBleOnState = new BleOnState();
private AdapterState(AdapterService service) {
super(TAG);
addState(mOnState);
addState(mBleOnState);
addState(mOffState);
addState(mTurningOnState);
addState(mTurningOffState);
addState(mTurningBleOnState);
addState(mTurningBleOffState);
mAdapterService = service;
setInitialState(mOffState);
}
AdapterState 是一个状态机,状态机改变状态时就会执行类的一些行为。构造函数默认是mOffState,收到BLE_TURN_ON消息。那么第一个地方就是OffState的processMessage处理BLE_TURN_ON,消息也是再直接传递到TurningBleOnState
AdapterState.java代码片段
private class OffState extends BaseAdapterState {
...
@Override
public boolean processMessage(Message msg) {
switch (msg.what) {
case BLE_TURN_ON:
transitionTo(mTurningBleOnState);
break;
}
}
private class TurningBleOnState extends BaseAdapterState {
...
@Override
public void enter() {
super.enter();
sendMessageDelayed(BLE_START_TIMEOUT, BLE_START_TIMEOUT_DELAY);
mAdapterService.bringUpBle();
}
这里会调用到AdapterService,开始启动ble 服务
void bringUpBle() {
...
//Start Gatt service
setProfileServiceState(GattService.class, BluetoothAdapter.STATE_ON);
}
private void setProfileServiceState(Class service, int state) {
Log.e(TAG, "setProfileServiceStat :" + service.getSimpleName());
Intent intent = new Intent(this, service);
intent.putExtra(EXTRA_ACTION, ACTION_SERVICE_STATE_CHANGED);
intent.putExtra(BluetoothAdapter.EXTRA_STATE, state);
startService(intent);
}
bluetooth apk里面很多service都时继承自ProfileService, 这里通过启动startService会调用到ProfileService的onStartCommand,service启动完后会回调到AdapterService
ProfileService.java 代码片段
private void doStart() {
// 回调到 AdapterService MESSAGE_PROFILE_SERVICE_REGISTERED
mAdapterService.addProfile(this);
//调用到对应子类的的 start方法
mProfileStarted = start();
if (!mProfileStarted) {
Log.e(mName, "Error starting profile. start() returned false.");
return;
}
// 回调到 AdapterService MESSAGE_PROFILE_SERVICE_REGISTERED
mAdapterService.onProfileServiceStateChanged(this, BluetoothAdapter.STATE_ON);
}
这是第一步先启动GattService。
在蓝牙打开成功之后,JNI层会通过JniCallbacks的stateChangeCallback方法把消息回调给AdapterService处理,AdapterService则继续把消息给到状态机处理:
AdapterService.java代码片段:
void stateChangeCallback(int status) {
if (status == AbstractionLayer.BT_STATE_OFF) {
debugLog("stateChangeCallback: disableNative() completed");
mAdapterStateMachine.sendMessage(AdapterState.BLE_STOPPED);
} else if (status == AbstractionLayer.BT_STATE_ON) {
mAdapterStateMachine.sendMessage(AdapterState.BLE_STARTED);
} else {
Log.e(TAG, "Incorrect status " + status + " in stateChangeCallback");
}
}
此时的AdapterState处于TurningBleOnState状态,TurningBleOnState在接收到BLE_STARTED消息后,迁入到BleOnState状态:
AdapterState.java代码片段:
private class TurningBleOnState extends BaseAdapterState {
.......
@Override
public boolean processMessage(Message msg) {
switch (msg.what) {
case BLE_STARTED:
transitionTo(mBleOnState);
break;
........
}
每一个状态的迁移,都会触发AdapterService的updateAdapterState,这个方法内部会把状态改变回调给远程的监听者:
AdapterState.java代码片段:
private abstract class BaseAdapterState extends State {
abstract int getStateValue();
@Override
public void enter() {
int currState = getStateValue();
infoLog("entered ");
mAdapterService.updateAdapterState(mPrevState, currState);
mPrevState = currState;
}
AdapterService.java代码片段:
void updateAdapterState(int prevState, int newState) {
mAdapterProperties.setState(newState);
if (mCallbacks != null) {
int n = mCallbacks.beginBroadcast();
debugLog("updateAdapterState() - Broadcasting state " + BluetoothAdapter.nameForState(
newState) + " to " + n + " receivers.");
for (int i = 0; i < n; i++) {
try {
mCallbacks.getBroadcastItem(i).onBluetoothStateChange(prevState, newState); //远程回调
} catch (RemoteException e) {
debugLog("updateAdapterState() - Callback #" + i + " failed (" + e + ")");
}
}
mCallbacks.finishBroadcast();
}
这里会远程回调到BluetoothManagerService里面的监听接口,经过handler消息处理机制会调用到bluetoothStateChangeHandler方法:
BluetoothManagerService.java代码片段
private class BluetoothHandler extends Handler {
...
@Override
public void handleMessage(Message msg) {
case MESSAGE_BLUETOOTH_SERVICE_CONNECTED: {
IBinder service = (IBinder) msg.obj;
try {
mBluetoothLock.writeLock().lock();
if (msg.arg1 == SERVICE_IBLUETOOTHGATT) {
mBluetoothGatt = IBluetoothGatt.Stub.asInterface(Binder.allowBlocking(service));
continueFromBleOnState();
break;
}
private void continueFromBleOnState() {
...
mBluetooth.onLeServiceUp();
}
mBluetooth.onLeServiceUp() 调用到了AdapterService
AdapterService.java 代码片段
void onLeServiceUp() {
mAdapterStateMachine.sendMessage(AdapterState.USER_TURN_ON);
}
接着是跟上面启动gattService的流程差不多, 通过状态机切换,调用到AdapterService,启动
AdapterState.java代码片段
private class TurningOnState extends BaseAdapterState {
@Override
public void enter() {
...
mAdapterService.startProfileServices();
}
AdapterService.java 代码片段
void startProfileServices() {
Class[] supportedProfileServices = Config.getSupportedProfiles();
...
setAllProfileServiceStates(supportedProfileServices, BluetoothAdapter.STATE_ON);
}
}
private void setAllProfileServiceStates(Class[] services, int state) {
for (Class service : services) {
if (GattService.class.getSimpleName().equals(service.getSimpleName())) {
continue;
}
setProfileServiceState(service, state);
}
}
private void setProfileServiceState(Class service, int state) {
Intent intent = new Intent(this, service);
intent.putExtra(EXTRA_ACTION, ACTION_SERVICE_STATE_CHANGED);
intent.putExtra(BluetoothAdapter.EXTRA_STATE, state);
startService(intent);
}
这里用for循环,启动supportedProfileServices里面的所有service, 这里的service都是继承自ProfileService, 每个service启动完后都会回调到AdapterService,当所有service都启动完后会走到下面else if的流程
private void processProfileServiceStateChanged(ProfileService profile, int state) {
switch (state) {
case BluetoothAdapter.STATE_ON:
if (GattService.class.getSimpleName().equals(profile.getName())) {
enableNativeWithGuestFlag();
} else if (mRegisteredProfiles.size() == Config.getSupportedProfiles().length - 1
&& mRegisteredProfiles.size() == mRunningProfiles.size()) {
mAdapterProperties.onBluetoothReady();
updateUuids();
setBluetoothClassFromConfig();
mAdapterStateMachine.sendMessage(AdapterState.BREDR_STARTED);
}
break;
图片来自https://blog.csdn.net/yus201120/article/details/119038589
beac4f61a8a842d08d0ecc0eb70207cd.png
参考: https://source.android.google.cn/devices/bluetooth?hl=zh-cn https://www.jianshu.com/p/b15314d91df0 https://blog.csdn.net/yus201120/article/details/119038589