作者:MelanDawn
链接:https://www.jianshu.com/p/010c37d5743d
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
1. overview
蓝牙初始化框图如上:
- 蓝牙处于关闭状态时,进程 com.android.bluetooth 不存在。
- 以设置打开蓝牙为例,蓝牙初始化(即 enable)的流程是 com.android.settings(设置进程) ----> system_server(系统服务进程)----> com.android.bluetooth(蓝牙进程)
- 蓝牙进程启动之后,设置应用将直接与蓝牙进程通信,无需再经过系统服务进程。
2. Settings Process - 触发开启蓝牙
// frameworks/base/core/java/android/bluetooth/BluetoothAdapter.java
/**
* Turn on the local Bluetooth adapter—do not use without explicit
* user action to turn on Bluetooth.
* <p>This powers on the underlying Bluetooth hardware, and starts all
* Bluetooth system services.
* <p class="caution"><strong>Bluetooth should never be enabled without
* direct user consent</strong>. If you want to turn on Bluetooth in order
* to create a wireless connection, you should use the {@link
* #ACTION_REQUEST_ENABLE} Intent, which will raise a dialog that requests
* user permission to turn on Bluetooth. The {@link #enable()} method is
* provided only for applications that include a user interface for changing
* system settings, such as a "power manager" app.</p>
* <p>This is an asynchronous call: it will return immediately, and
* clients should listen for {@link #ACTION_STATE_CHANGED}
* to be notified of subsequent adapter state changes. If this call returns
* true, then the adapter state will immediately transition from {@link
* #STATE_OFF} to {@link #STATE_TURNING_ON}, and some time
* later transition to either {@link #STATE_OFF} or {@link
* #STATE_ON}. If this call returns false then there was an
* immediate problem that will prevent the adapter from being turned on -
* such as Airplane mode, or the adapter is already turned on.
*
* @return true to indicate adapter startup has begun, or false on immediate error
*/
@RequiresLegacyBluetoothAdminPermission
@RequiresBluetoothConnectPermission
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public boolean enable() {
if (isEnabled()) {
if (DBG) {
Log.d(TAG, "enable(): BT already enabled!");
}
return true;
}
try {
return mManagerService.enable(mAttributionSource);
} catch (RemoteException e) {
Log.e(TAG, "", e);
}
return false;
}
3. System_server Process
3.1 启动蓝牙进程
frameworks/base/services/core/java/com/android/server/BluetoothManagerService.java
public boolean enableNoAutoConnect(AttributionSource attributionSource) {
final String packageName = attributionSource.getPackageName();
if (!checkBluetoothPermissions(attributionSource, "enableNoAutoConnect", false)) {
if (DBG) {
Slog.d(TAG, "enableNoAutoConnect(): not enabling - bluetooth disallowed");
}
return false;
}
if (DBG) {
Slog.d(TAG, "enableNoAutoConnect(): mBluetooth =" + mBluetooth + " mBinding = "
+ mBinding);
}
int callingAppId = UserHandle.getAppId(Binder.getCallingUid());
if (callingAppId != Process.NFC_UID) {
throw new SecurityException("no permission to enable Bluetooth quietly");
}
synchronized (mReceiver) {
mQuietEnableExternal = true;
mEnableExternal = true;
sendEnableMsg(true,
BluetoothProtoEnums.ENABLE_DISABLE_REASON_APPLICATION_REQUEST, packageName);
}
return true;
}
此处传递的 quietMode = false;
private void sendEnableMsg(boolean quietMode, int reason, String packageName) {
sendEnableMsg(quietMode, reason, packageName, false);
}
private void sendEnableMsg(boolean quietMode, int reason, String packageName, boolean isBle) {
mHandler.sendMessage(mHandler.obtainMessage(MESSAGE_ENABLE, quietMode ? 1 : 0,
isBle ? 1 : 0));
addActiveLog(reason, packageName, true);
mLastEnabledTime = SystemClock.elapsedRealtime();
}
private class BluetoothHandler extends Handler {
......
@Override
public void handleMessage(Message msg) {
case MESSAGE_ENABLE:
......
mQuietEnable = (msg.arg1 == 1); // mQuietEnable = false;
if (mBluetooth == null) {
handleEnable(mQuietEnable);
}
......
break;
首次开启时,由于 com.android.bluetooth 还未启动,因此 mBluetooth == null,故会执行绑定服务的操作。
private void handleEnable(boolean quietMode) {
mQuietEnable = quietMode; // false
try {
if ((mBluetooth == null) && (!mBinding)) {
......
Intent i = new Intent(IBluetooth.class.getName());
if (!doBind(i, mConnection,
Context.BIND_AUTO_CREATE | Context.BIND_IMPORTANT,
UserHandle.CURRENT)) {
} else {
mBinding = true;
}
} else if (mBluetooth != null) {
......
}
}
}
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)) {
return false;
}
return true;
}
绑定的是 IBluetooth 这个服务,由以下配置信息可知,绑定的是 AdapterService.java,该绑定过程会启动 com.android.bluetooth 进程。
packages/apps/Bluetooth/AndroidManifest.xml
<service android:process="@string/process"
android:name=".btservice.AdapterService"
android:exported="true">
<intent-filter>
<action android:name="android.bluetooth.IBluetooth"/>
</intent-filter>
</service>
蓝牙进程的启动过程由 蓝牙进程初始化 来分析,此文继续分析服务被绑定成功后的回调。
3.2 绑定 AdapterService 成功后的回调
// 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();
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);
}
......
}
private BluetoothServiceConnection mConnection = new BluetoothServiceConnection();
以上源码主要是创建了 MESSAGE_BLUETOOTH_SERVICE_CONNECTED 消息,下面开始处理该消息。
private class BluetoothHandler extends Handler {
......
@Override
public void handleMessage(Message msg) {
case MESSAGE_BLUETOOTH_SERVICE_CONNECTED: {
IBinder service = (IBinder) msg.obj;
try {
mBluetoothLock.writeLock().lock();
if (msg.arg1 == SERVICE_IBLUETOOTHGATT) {
......
return;
} // else must be SERVICE_IBLUETOOTH
......
mBinding = false;
mBluetoothBinder = service;
// 0. 获取蓝牙进程蓝牙适配器服务的代理对象
mBluetooth = IBluetooth.Stub.asInterface(Binder.allowBlocking(service));
......
// 1. 向蓝牙进程注册回调函数,以达到双向通信的目的
try {
mBluetooth.registerCallback(mBluetoothCallback);
} catch (RemoteException re) {
Slog.e(TAG, "Unable to register BluetoothCallback", re);
}
// 2. Inform BluetoothAdapter instances that service is up
sendBluetoothServiceUpCallback();
// 3. Do enable request
try {
if (!mBluetooth.enable(mQuietEnable)) {
Slog.e(TAG, "IBluetooth.enable() returned false");
}
} catch (RemoteException e) {
Slog.e(TAG, "Unable to call enable()", e);
}
处理 MESSAGE_BLUETOOTH_SERVICE_CONNECTED 消息,从源码可知:
首先,获取并保存蓝牙进程入口的代理对象:mBluetooth;
其次,
- 向蓝牙进程注册回调,用于蓝牙进程向系统服务进程发送消息;
- 执行应用层注册到系统服务进程的回调,向已注册的应用进程提供 蓝牙进程入口的代理对象;
- 向蓝牙进程发起执行 enable 操作的请求。
3.2.1 registerCallback
3.2.1.1 Register Flow
AdapterService 存储该回调对象,在合适的时候触发回调。
// packages/apps/Bluetooth/src/com/android/bluetooth/btservice/AdapterService.java
public class AdapterService extends Service {
private RemoteCallbackList<IBluetoothCallback> mCallbacks =
new RemoteCallbackList<IBluetoothCallback>();
public static class AdapterServiceBinder extends IBluetooth.Stub {
public void registerCallback(IBluetoothCallback callback) {
AdapterService service = getService();
......
service.mCallbacks.register(callback);
}
}
3.2.1.2 Callback Implementation
// frameworks/base/services/core/java/com/android/server/BluetoothManagerService.java
private final IBluetoothCallback mBluetoothCallback = new IBluetoothCallback.Stub() {
@Override
public void onBluetoothStateChange(int prevState, int newState) throws RemoteException {
Message msg =
mHandler.obtainMessage(MESSAGE_BLUETOOTH_STATE_CHANGE, prevState, newState);
mHandler.sendMessage(msg);
}
};
从以上源码可知,蓝牙进程调用该回调以通知系统服务进程蓝牙的状态变化信息。
private class BluetoothHandler extends Handler {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MESSAGE_BLUETOOTH_STATE_CHANGE: {
int prevState = msg.arg1;
int newState = msg.arg2;
mState = newState;
bluetoothStateChangeHandler(prevState, newState);
......
break;
}
bluetoothStateChangeHandler() 负责更新状态,并发送状态变化的广播。
3.2.1.3 Callback Invoke Example
回调方法执行的源码如下
packages/apps/Bluetooth/src/com/android/bluetooth/btservice/AdapterService.java
void updateAdapterState(int prevState, int newState) {
......
if (mCallbacks != null) {
int n = mCallbacks.beginBroadcast();
for (int i = 0; i < n; i++) {
try {
mCallbacks.getBroadcastItem(i).onBluetoothStateChange(prevState, newState);
} catch (RemoteException e) {
......
}
}
mCallbacks.finishBroadcast();
}
// frameworks/base/core/java/android/os/RemoteCallbackList.java
public class RemoteCallbackList<E extends IInterface> {
public int beginBroadcast() {
synchronized (mCallbacks) {
final int N = mBroadcastCount = mCallbacks.size();
if (N <= 0) {
return 0;
}
Object[] active = mActiveBroadcast;
if (active == null || active.length < N) {
mActiveBroadcast = active = new Object[N];
}
for (int i=0; i<N; i++) {
active[i] = mCallbacks.valueAt(i);
}
return N;
}
}
public void finishBroadcast() {
synchronized (mCallbacks) {
Object[] active = mActiveBroadcast;
if (active != null) {
final int N = mBroadcastCount;
for (int i=0; i<N; i++) {
active[i] = null;
}
}
mBroadcastCount = -1;
}
}
}
3.2.2 sendBluetoothServiceUpCallback
frameworks/base/services/core/java/com/android/server/BluetoothManagerService.java
private final RemoteCallbackList<IBluetoothManagerCallback> mCallbacks =
new RemoteCallbackList<IBluetoothManagerCallback>();;
private void sendBluetoothServiceUpCallback() {
synchronized (mCallbacks) {
try {
int n = mCallbacks.beginBroadcast();
for (int i = 0; i < n; i++) {
try {
mCallbacks.getBroadcastItem(i).onBluetoothServiceUp(mBluetooth);
} catch (RemoteException e) {
Slog.e(TAG, "Unable to call onBluetoothServiceUp() on callback #" + i, e);
}
}
} finally {
mCallbacks.finishBroadcast();
}
}
}
BluetoothManagerService 回调应用层注册的回调对象的方法 onBluetoothServiceUp(),将蓝牙进程入口的代理对象发送到该应用。
frameworks/base/core/java/android/bluetooth/BluetoothDevice.java
public final class BluetoothDevice implements Parcelable {
static IBluetoothManagerCallback sStateChangeCallback = new IBluetoothManagerCallback.Stub() {
public void onBluetoothServiceUp(IBluetooth bluetoothService)
throws RemoteException {
synchronized (BluetoothDevice.class) {
if (sService == null) {
sService = bluetoothService;
}
}
}
......
}
}
3.2.3 Bluetooth Process enable
蓝牙进程继续执行 enable 操作的内容较多,链接如下。
Bluetooth initialization - enable in Bluetooth process
用一张图总结下:
评论