android 蓝牙的enable流程
本篇介绍从settings enable蓝牙的流程,按照蓝牙的代码的位置分成
APP层
,
Framework层
,
Bluetooth.apk
三个部分。
这里的enable其实只是启动上层协议,使协议处于listen的状态。
蓝牙的driver的启动流程在下一篇博客中。
借用网上的一张图片,该篇只涉及左边半部分。
前提
- 这篇文章的codes和分析的流程基于Android 7.0的Qcom8909平台。
- 该平台支撑传统蓝牙和BLE。
APP
开关是个SwitchBar,监听事件callback到onSwitchChanged,调用mLocalAdapter.setBluetoothEnabled(isChecked),mLocalAdapter是个com.android.settingslib.bluetooth.LocalBluetoothAdapter的一个实例:
public boolean enable() {
return mAdapter.enable();
}
这里的mAdapter是BluetoothAdapter的实例,在LocalBluetoothAdapter的构造函数中初始化。
framework
- 然后到framework层的BluetoothAdapter,该类api多多,简单来说就是分装了面向APP层的几乎所有蓝牙相关的API。
@RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN)
public boolean enable() {
android.util.SeempLog.record(56);
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;
}
private final IBluetoothManager mManagerService;
这个mManagerService是BluetoothManagerService的binder的代理。
- BluetoothManagerService是在SystemServer中被拉起,跑在SystemServer进程中。
public boolean enable(String packageName) throws RemoteException {
final int callingUid = Binder.getCallingUid();
final boolean callerSystem = UserHandle.getAppId(callingUid) == Process.SYSTEM_UID;
if (!callerSystem) {
if (!checkIfCallerIsForegroundUser()) {
Slog.w(TAG, "enable(): not allowed for non-active and non system user");
return false;
}
mContext.enforceCallingOrSelfPermission