在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);
}
@Override
public void onStart() {
}
@Override
public 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
/**
* Starts a miscellaneous grab bag of stuff that has yet to be refactored
* and organized.
*/
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
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.bluetooth"
android:sharedUserId="android.uid.bluetooth">
<application
android:name=".btservice.AdapterApp"
android:icon="@mipmap/bt_share"
android:persistent="false"
android:label="@string/app_name"
android:supportsRtl="true"
android:usesCleartextTraffic="false"
android:directBootAware="true"
android:defaultToDeviceProtectedStorage="true">
<uses-library android:name="javax.obex" />
<service
android:process="@string/process"
android:name = ".btservice.AdapterService">
<intent-filter>
<action android:name="android.bluetooth.IBluetooth" />
</intent-filter>
</service>
</manifest>
也就是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
服务端