在android原生蓝牙进程中,有两个类需要了解一下,在蓝牙模块经常看到这两个类的影子,分别是IBluetooth与IBluetoothManager其中特别是 IBluetooth.aidl,它的作用比较重要,因此有了解熟悉它的必要,首先它们的位置在/frameworks/base/core/java/android/bluetooth/下,也就是说定义在framework.jar包下,各自的职责分别是:
IBluetooth.aidl:控制蓝牙模块,例如开启扫描/停止扫描;设置蓝牙模块对外名称;操纵远程蓝牙设备,例如向远程设备发起配对过程;
IBluetoothManager.aidl:负责接收其它模块的蓝牙交互请求;大部分能力来自 IBluetooth.aidl;
其实在最开始获取BluetoothAdapter的过程中,IBluetoothManager就已经作为aidl的客户端初始化了,通过获取到的挂在系统服务里的BluetoothManagerService的IBinder服务,然后asInterface成客户端:
代码位置:/frameworks/base/core/java/android/bluetooth/BluetoothAdapter.java
public static synchronized BluetoothAdapter getDefaultAdapter() { if (sAdapter == null) { IBinder b = ServiceManager.getService(BLUETOOTH_MANAGER_SERVICE); if (b != null) { IBluetoothManager managerService = IBluetoothManager.Stub.asInterface(b); sAdapter = new BluetoothAdapter(managerService); } else { Log.e(TAG, "Bluetooth binder is null"); } } return sAdapter;}
在以下代码可以得知,ServcieManager获取的是IBinder对象,这个IBinder是一个aidl的服务端,可以看到,在蓝牙系统服务的引导过程中会将IBluetoothManager的IBinder对象公开,也就是初始化出来,让其它的应用或者服务可以调用到:
代码位置:/frameworks/base/services/core/java/com/android/server/BluetoothService.java
class BluetoothService extends SystemService {private BluetoothManagerService mBluetoothManagerService;public BluetoothService(Context context) { super(context); mBluetoothManagerService = new BluetoothManagerService(context);}@Overridepublic void onStart() {}@Overridepublic void onBootPhase(int phase) { if (phase == SystemService.PHASE_SYSTEM_SERVICES_READY) { publishBinderService(BluetoothAdapter.BLUETOOTH_MANAGER_SERVICE, mBluetoothManagerService); } else if (phase == SystemService.PHASE_ACTIVITY_MANAGER_READY) { mBluetoothManagerService.handleOnBootPhase(); }}}
上面讲到,BluetoothManagerService在蓝牙系统服务引导过程中被运行起来,作为IBinder服务端初始化并被系统服务集统一管理起来
代码位置:/frameworks/base/services/core/java/com/android/server/BluetoothManagerService.java
class BluetoothManagerService extends IBluetoothManager.Stub {}
蓝牙系统服务是SystemServer这个进程启动的,这个开机启动的进程想必做android开发得或多或少都有听说过,简单来说,SystemServer就是系统用来启动原生service的入口。
Android系统在启动过程中,首先启动Zygote进程,接着由zygote进程fork出system_server进程;
SystemServer会启动我们在系统中所需要的一系列service,蓝牙服务便是在这一步骤中被启动起来的,并且在引导过程中将BluetoothManagerService初始化,将其交由系统管理。
源码位置:/frameworks/base/services/java/com/android/server/SystemServer.java
private void startOtherServices() { if (isEmulator) { Slog.i(TAG, "No Bluetooth Service (emulator)"); } else if (mFactoryTestMode == FactoryTest.FACTORY_TEST_LOW_LEVEL) { Slog.i(TAG, "No Bluetooth Service (factory test)"); } else if (!context.getPackageManager().hasSystemFeature (PackageManager.FEATURE_BLUETOOTH)) { Slog.i(TAG, "No Bluetooth Service (Bluetooth Hardware Not Present)"); } else if (disableBluetooth) { Slog.i(TAG, "Bluetooth Service disabled by config"); } else { traceBeginAndSlog("StartBluetoothService"); mSystemServiceManager.startService(BluetoothService.class); traceEnd(); }}
现在,我们来到BluetoothManagerService,既然其开机就会被运行起来,那么我们看其何时会初始化另外一个重要的类IBluetooth,通过查阅源码发现其在以下位置被初始化,这其实是连接上了AdapterServcie后初始化的,也就是说,BluetoothManagerService在被系统蓝牙服务拉起后,会在连接上AdapterServcie这个android原生系统蓝牙进程里的服务后,初始化IBluetooth接口
源码位置:/frameworks/base/services/core/java/com/android/server/BluetoothManagerService.java
case MESSAGE_BLUETOOTH_SERVICE_CONNECTED:{ IBinder service = (IBinder) msg.obj; try { mBinding = false; mBluetoothBinder = service; mBluetooth = IBluetooth.Stub.asInterface(Binder.allowBlocking(service)); //Register callback object try { mBluetooth.registerCallback(mBluetoothCallback); } catch (RemoteException re) { Slog.e(TAG, "Unable to register BluetoothCallback",re); } //Do enable request try { if (mQuietEnable == false) { if (!mBluetooth.enable()) { Slog.e(TAG,"IBluetooth.enable() returned false"); } } else { if (!mBluetooth.enableNoAutoConnect()) { Slog.e(TAG,"IBluetooth.enableNoAutoConnect() returned false"); } } } catch (RemoteException e) { Slog.e(TAG,"Unable to call enable()",e); } } finally { mBluetoothLock.writeLock().unlock(); } break;}
private class BluetoothServiceConnection implements ServiceConnection { public void onServiceConnected(ComponentName componentName, IBinder service) { String name = componentName.getClassName(); if (DBG) Slog.d(TAG, "BluetoothServiceConnection: " + name); 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); }
那什么时候会bind这个AdapterServcie服务呢?是在以下方法,当有enable请求过来的时候
private void handleEnable(boolean quietMode) { mQuietEnable = quietMode; try { mBluetoothLock.writeLock().lock(); if ((mBluetooth == null) && (!mBinding)) { //Start bind timeout and bind Message timeoutMsg=mHandler.obtainMessage(MESSAGE_TIMEOUT_BIND); mHandler.sendMessageDelayed(timeoutMsg,TIMEOUT_BIND_MS); Intent i = new Intent(IBluetooth.class.getName()); if (!doBind(i, mConnection,Context.BIND_AUTO_CREATE | Context.BIND_IMPORTANT, UserHandle.CURRENT)) { mHandler.removeMessages(MESSAGE_TIMEOUT_BIND); } else { mBinding = true; } }
上边这个intent初始化其实就是请求向以下这个adapterservice的绑定,这个服务运行在系统原生的蓝牙进程当中
源码位置:/packages/apps/Bluetooth/AndroidManifest.xml
也就是bluetoothAdapter发起enable请求的时候:
源码位置:/frameworks/base/core/java/android/bluetooth/BluetoothAdapter.java
@RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN) public boolean enable() { if (isEnabled()) { if (DBG) Log.d(TAG, "enable(): BT already enabled!"); return true; } try { return mManagerService.enable(ActivityThread.currentPackageName()); } catch (RemoteException e) {Log.e(TAG, "", e);} return false; }
请求转到BluetoothManagerService这里,方法发送了消息并交由handler处理
源码位置:/frameworks/base/services/core/java/com/android/server/BluetoothManagerService.java
public boolean enable(String packageName) throws RemoteException { synchronized(mReceiver) { mQuietEnableExternal = false; mEnableExternal = true; // waive WRITE_SECURE_SETTINGS permission check sendEnableMsg(false, packageName); } if (DBG) Slog.d(TAG, "enable returning"); return true; }
private void sendEnableMsg(boolean quietMode, String packageName) { mHandler.sendMessage(mHandler.obtainMessage(MESSAGE_ENABLE, quietMode ? 1 : 0, 0)); addActiveLog(packageName, true); }
消息MESSAGE_ENABLE的处理:
case MESSAGE_ENABLE: if (DBG) { Slog.d(TAG, "MESSAGE_ENABLE(" + msg.arg1 + "): mBluetooth = " + mBluetooth); } mHandler.removeMessages(MESSAGE_RESTART_BLUETOOTH_SERVICE); mEnable = true; // Use service interface to get the exact state try { mBluetoothLock.readLock().lock(); if (mBluetooth != null) { int state = mBluetooth.getState(); if (state == BluetoothAdapter.STATE_BLE_ON) { Slog.w(TAG, "BT Enable in BLE_ON State, going to ON"); mBluetooth.onLeServiceUp(); persistBluetoothSetting(BLUETOOTH_ON_BLUETOOTH); break; } } } catch (RemoteException e) { Slog.e(TAG, "", e); } finally { mBluetoothLock.readLock().unlock(); } mQuietEnable = (msg.arg1 == 1); if (mBluetooth == null) { handleEnable(mQuietEnable); }
接着来到handleEnable处,该方法会bind到action名称为android.bluetooth.IBluetooth的服务中,也就是AdapterServcie类
private void handleEnable(boolean quietMode) { try { mBluetoothLock.writeLock().lock(); if ((mBluetooth == null) && (!mBinding)) { //Start bind timeout and bind Message timeoutMsg=mHandler.obtainMessage(MESSAGE_TIMEOUT_BIND); mHandler.sendMessageDelayed(timeoutMsg,TIMEOUT_BIND_MS); Intent i = new Intent(IBluetooth.class.getName()); if (!doBind(i, mConnection,Context.BIND_AUTO_CREATE | Context.BIND_IMPORTANT, UserHandle.CURRENT)) { mHandler.removeMessages(MESSAGE_TIMEOUT_BIND); } else { mBinding = true; } } } 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; }
在连接上了AdapterServcie后,服务连接监听mConnection会回调onServiceConnected方法:
源码位置:/frameworks/base/services/core/java/com/android/server/BluetoothManagerService.java
private class BluetoothServiceConnection implements ServiceConnection { public void onServiceConnected(ComponentName componentName, IBinder service) { String name = componentName.getClassName(); if (DBG) Slog.d(TAG, "BluetoothServiceConnection: " + name); Message msg = mHandler.obtainMessage(MESSAGE_BLUETOOTH_SERVICE_CONNECTED); if (name.equals("com.android.bluetooth.btservice.AdapterService")) { msg.arg1 = SERVICE_IBLUETOOTH; } msg.obj = service; mHandler.sendMessage(msg); }
onServiceConnected方法会发送一个消息,让mHandler处理,初始化IBluetooth并且发起enable方法:
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(); //Remove timeout mHandler.removeMessages(MESSAGE_TIMEOUT_BIND); mBinding = false; mBluetoothBinder = service; //初始化IBluetooth mBluetooth = IBluetooth.Stub.asInterface(Binder.allowBlocking(service)); //Register callback object try { mBluetooth.registerCallback(mBluetoothCallback); } catch (RemoteException re) { Slog.e(TAG, "Unable to register BluetoothCallback",re); } //Inform BluetoothAdapter instances that service is up sendBluetoothServiceUpCallback(); //Do enable request 在这里调用已经初始化完毕的IBluetooth的enable方法,IBluetooth本身就是AdapterService的onBind方法里返回的AdapterServiceBinder try { if (mQuietEnable == false) { if (!mBluetooth.enable()) { Slog.e(TAG,"IBluetooth.enable() returned false"); } } else { if (!mBluetooth.enableNoAutoConnect()) { Slog.e(TAG,"IBluetooth.enableNoAutoConnect() returned false"); } } } catch (RemoteException e) { Slog.e(TAG,"Unable to call enable()",e); } } finally { mBluetoothLock.writeLock().unlock(); } }
也就是这一句,iBluetooth接口被初始化为客户端
mBluetooth = IBluetooth.Stub.asInterface(Binder.allowBlocking(service));
总结:
android系统运行起来后,会由system_server进程运行蓝牙服务BluetoothService,而BluetoothService在引导过程中会初始化并且公布BluetoothManagerService类,一旦BluetoothAdapter接收到外部的蓝牙开启enable请求,就会转发到BluetoothManagerService里,并且BluetoothManagerService会bind到AdapterService,连接成功后,就会通过aidl的方式让AdapterService去调用IBluetooth打开蓝牙,BluetoothManagerService运行在system_server进程,AdapterService运行在系统蓝牙进程,最后,在各自描述一下各个模块:
IBluetoothManager:蓝牙交互代理接口,在BluetoothAdapter里作为aidl客户端存在,负责接收蓝牙的交互请求,如enable
BluetoothManagerService:IBluetoothManager的aidl服务端,被SystemService管理
BluetoothService:运行在system_server进程,负责初始化BluetoothManagerService
IBluetooth:蓝牙的真正交互接口,在BluetoothManagerService中作为aidl客户端存在
AdapterService:android服务,持有IBluetooth的aidl服务端