android蓝牙模块IBluetooth与IBluetoothManager详解

android蓝牙模块IBluetooth与IBluetoothManager详解

在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

package="com.android.bluetooth"

android:sharedUserId="android.uid.bluetooth">

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">

android:process="@string/process"

android:name = ".btservice.AdapterService">

也就是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服务端

相关推荐