目录
- 1、SystemServer
- 2、BluetoothService
- 3、BluetoothManagerService
首先我们要知道,主要系统服务都是在 SystemServer 启动的,蓝牙也是如此:
1、SystemServer
源码路径:/frameworks/base/services/java/com/android/server/SystemServer.java
private void startOtherServices(@NonNull TimingsTraceAndSlog t) { | |
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 { | |
t.traceBegin("StartBluetoothService"); | |
mSystemServiceManager.startService(BluetoothService.class); | |
t.traceEnd(); | |
} | |
} |
SystemServer 在启动其他服务的方法里,启动了 BluetoothService。
2、BluetoothService
class BluetoothService extends SystemService { | |
private BluetoothManagerService mBluetoothManagerService; | |
public BluetoothService(Context context) { | |
super(context); | |
//创建BluetoothManagerService的实例 | |
mBluetoothManagerService = new BluetoothManagerService(context); | |
} | |
...... | |
public void onBootPhase(int phase) { | |
if (phase == SystemService.PHASE_SYSTEM_SERVICES_READY) { | |
//将BluetoothManagerService实例发布到系统中,这样就可以Context根据BT的service名去获取它的Binder代理操作API了 | |
publishBinderService(BluetoothAdapter.BLUETOOTH_MANAGER_SERVICE, | |
mBluetoothManagerService); | |
} else if (phase == SystemService.PHASE_ACTIVITY_MANAGER_READY) { | |
//此时系统应该启动到一个比较晚的阶段了,可以使用AMS去Bind需要的Service了 | |
mBluetoothManagerService.handleOnBootPhase(); | |
} | |
} | |
...... | |
} |
可以看到,真正获取的服务是BluetoothManagerService 而非 BluetoothService。可以通过 ServiceManager.getService(BLUETOOTH_MANAGER _SERVICE) 获取蓝牙服务。
onBootPhase(int):这个函数应该是 systemserver 在启动的时候会多次调用,参数代表当前启动进行到了什么阶段,用户定义的 service 针对各个阶段需要做怎样的处理或者是不做任何处理。
3、BluetoothManagerService
BluetoothManagerService(Context context) { | |
//创建内部处理msg的handler | |
mHandler = new BluetoothHandler(IoThread.get().getLooper()); | |
mContext = context; | |
...... | |
//false表示此次enable需要触发auto connect device和保存状态,BluetoothAdapter::enableNoAutoConnect()可以改变此状态 | |
mQuietEnableExternal = false; | |
mEnableExternal = false; | |
...... | |
IntentFilter filter = new IntentFilter(); | |
//监听App通过接口修改BT 名称的广播 | |
filter.addAction(BluetoothAdapter.ACTION_LOCAL_NAME_CHANGED); | |
//监听bt地址改变的广播 | |
filter.addAction(BluetoothAdapter.ACTION_BLUETOOTH_ADDRESS_CHANGED); | |
//监听当前设置需要restore回上一次设置的广播,此时需要重新保存name和addr为上一次的信息 | |
filter.addAction(Intent.ACTION_SETTING_RESTORED); | |
filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY); | |
mContext.registerReceiver(mReceiver, filter); | |
//从数据库中加载本机Bt的local name和address | |
loadStoredNameAndAddress(); | |
//查看上一次关机时,BT是否为enable状态;如果是,这次开机也需要enable BT | |
if (isBluetoothPersistedStateOn()) { | |
if (DBG) { | |
Slog.d(TAG, "Startup: Bluetooth persisted state is ON."); | |
} | |
mEnableExternal = true;//表明开机过程中需要enable BT | |
} | |
} |
在服务启动到一定阶段就会回调到 SystemService 的 onBootPhase(int) 方法,即 2 中的该方法,然后调用 BMS 中的 handleOnBootPhase() 方法。
public void handleOnBootPhase() { | |
...... | |
final boolean isSafeMode = mContext.getPackageManager().isSafeMode(); | |
if (mEnableExternal && isBluetoothPersistedStateOnBluetooth() && && !isSafeMode) { | |
sendEnableMsg(mQuietEnableExternal/*默认false,表示此次enable需要自动连接device/保存enable状态*/, | |
BluetoothProtoEnums.ENABLE_DISABLE_REASON_SYSTEM_BOOT, | |
mContext.getPackageName()); | |
} else if (!isNameAndAddressSet()) { | |
Message getMsg = mHandler.obtainMessage(MESSAGE_GET_NAME_AND_ADDRESS); | |
mHandler.sendMessage(getMsg); | |
} | |
...... | |
} |
handleOnBootPhase()的内容比较单一,根据一些flag判断是否需要enable BT;而enable蓝牙这里是通过触发send msg实现。
private void sendEnableMsg(boolean quietMode, int reason, String packageName) { | |
//发送MESSAGE_ENABLE msg | |
mHandler.sendMessage(mHandler.obtainMessage(MESSAGE_ENABLE, quietMode ? : 0, 0)); | |
addActiveLog(reason, packageName, true); | |
mLastEnabledTime = SystemClock.elapsedRealtime(); | |
} | |
case MESSAGE_ENABLE: | |
int quietEnable = msg.arg; | |
mQuietEnable = (quietEnable ==);//此时为false | |
//mBluetooth是后面绑定Bt apk中AdapterService时拿到的Binder代理对象;用以把操作bypass到BT核心框架中 | |
if (mBluetooth == null) { | |
handleEnable(mQuietEnable); | |
} else {//如果mBluetooth不是null,说明之前已经启动过了;此时是Restart flow,以MESSAGE_RESTART_BLUETOOTH_SERVICE触发 | |
mWaitForEnableRetry =; | |
Message enableDelayedMsg = mHandler.obtainMessage(MESSAGE_HANDLE_ENABLE_DELAYED); | |
mHandler.sendMessageDelayed(enableDelayedMsg, ENABLE_DISABLE_DELAY_MS); | |
} | |
break; |
handleEnable() 去 Bind AdapterService 拿到它的Binder句柄。同样的在调用 BluetoothManagerService 中的 enable()、disable()等方法时,也是调到 handleEnable() 方法,从而最终调用 AdapterService 中的 enable()、disable() 方法。
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; | |
} | |
} | |
} finally { | |
mBluetoothLock.writeLock().unlock(); | |
} | |
} |
然后我们看一下 doBind() 方法中的 mConnection 参数:
private BluetoothServiceConnection mConnection = new BluetoothServiceConnection(); | |
private class BluetoothServiceConnection implements ServiceConnection { | |
public void onServiceConnected(ComponentName componentName, IBinder service) { | |
String name = componentName.getClassName(); | |
Message msg = mHandler.obtainMessage(MESSAGE_BLUETOOTH_SERVICE_CONNECTED); | |
if (name.equals("com.android.bluetooth.btservice.AdapterService")) { | |
msg.arg = SERVICE_IBLUETOOTH; | |
} else if (name.equals("com.android.bluetooth.gatt.GattService")) { | |
msg.arg = SERVICE_IBLUETOOTHGATT; | |
} else { | |
Slog.e(TAG, "Unknown service connected: " + name); | |
return; | |
} | |
msg.obj = service; | |
mHandler.sendMessage(msg); | |
} | |
public void onServiceDisconnected(ComponentName componentName) { | |
// Called if we unexpectedly disconnect. | |
String name = componentName.getClassName(); | |
Message msg = mHandler.obtainMessage(MESSAGE_BLUETOOTH_SERVICE_DISCONNECTED); | |
if (name.equals("com.android.bluetooth.btservice.AdapterService")) { | |
msg.arg = SERVICE_IBLUETOOTH; | |
} else if (name.equals("com.android.bluetooth.gatt.GattService")) { | |
msg.arg = SERVICE_IBLUETOOTHGATT; | |
} else { | |
Slog.e(TAG, "Unknown service disconnected: " + name); | |
return; | |
} | |
mHandler.sendMessage(msg); | |
} | |
} |
拿到 AdapterService 服务后,发送MESSAGE_BLUETOOTH_SERVICE_CONNECTED消息且 arg1 = SERVICE_IBLUETOOTH。
case MESSAGE_BLUETOOTH_SERVICE_CONNECTED: { | |
IBinder service = (IBinder) msg.obj; | |
try { | |
mBluetoothLock.writeLock().lock(); | |
mBinding = false; | |
mBluetoothBinder = service; | |
mBluetooth = IBluetooth.Stub.asInterface(Binder.allowBlocking(service)); | |
//Register callback object | |
try { | |
mBluetooth.registerCallback(mBluetoothCallback, mContext.getAttributionSource()); | |
} catch (RemoteException re) { | |
Slog.e(TAG, "Unable to register BluetoothCallback", re); | |
} | |
//Inform BluetoothAdapter instances that service is up | |
sendBluetoothServiceUpCallback(); | |
//Do enable request | |
try { | |
if (!mBluetooth.enable(mQuietEnable, mContext.getAttributionSource())) { | |
Slog.e(TAG, "IBluetooth.enable() returned false"); | |
} | |
} catch (RemoteException e) { | |
Slog.e(TAG, "Unable to call enable()", e); | |
} | |
} finally { | |
mBluetoothLock.writeLock().unlock(); | |
} | |
if (!mEnable) { | |
waitForState(Set.of(BluetoothAdapter.STATE_ON)); | |
handleDisable(); | |
waitForState(Set.of(BluetoothAdapter.STATE_OFF, | |
BluetoothAdapter.STATE_TURNING_ON, | |
BluetoothAdapter.STATE_TURNING_OFF, | |
BluetoothAdapter.STATE_BLE_TURNING_ON, | |
BluetoothAdapter.STATE_BLE_ON, | |
BluetoothAdapter.STATE_BLE_TURNING_OFF)); | |
} | |
} |
主要操作:
1、拿到 bind 服务的 onBinder() 句柄,并转成 IBluetooth 类型
2、通过 IBluetooth 类型的 obj,调用 enable() 接口,将 flow 转到 AdapterService 中,做一些初始化、并向 stack 下 enable 蓝牙的 cmd
至此,enable 蓝牙的 flow 就从 BluetoothManagerService 转到 AdapterService 中了;实际上,通过 BluetoothAdapter 下来的大部分 API 调用最终都是调用到 AdapterService,再通过它下cmd 给 stack。
两个常见到的flag:
mEnable:用来标记系统运行时,蓝牙状态的变化,它有些时候跟 mEnableExternal 值一致。但如果蓝牙的状态是因为某些原因,如 stack 崩溃,导致蓝牙需要重启,重新启动时,需要靠这个 flag 来标记这种 case 的 enable/disable 状态。
mEnableExternal:它主要是记录通过用户手动操作导致的BT使能状态,如通过蓝牙功能按钮来 enable/disable 蓝牙。