Android(安卓)-- AdapterService之蓝牙启动过程分析
Android -- AdapterService之蓝牙启动过程分析
前面介绍BluetoothManagerService启动过程enable BT的部分提到,处理ENABLE msg的最终调用主要是call到AdapterService注册IBluetoothCallback回调监听蓝牙使能状态、以及AdapterService::enable()接口开启蓝牙,下面就接着这部分往下看。
AdapterService是Service的子类,Bind service会触发依次调用它的声明周期函数onCreate() -> onBind():
public class AdapterService extends Service {...... static { classInitNative();//native层的init部分 }...... @Override public void onCreate() { super.onCreate(); debugLog("onCreate()"); mRemoteDevices = new RemoteDevices(this, Looper.getMainLooper());//重要类型,它实现了接受stack反馈的device信息变化的回调,比如UUID mRemoteDevices.init(); mBinder = new AdapterServiceBinder(this);//AdapterService内部封装的IBluetooth接口实现者 mAdapterProperties = new AdapterProperties(this);//管理当前Adapter的一些属性,比如配对的device,uuid信息等;有些接口供stack回调上报状态使用 mAdapterStateMachine = AdapterState.make(this);//一个简单的StateMachine,处理开关BT中间的状态切换 mJniCallbacks = new JniCallbacks(this, mAdapterProperties);//stack会通过此对象上报一些bt状态和信息 initNative();//native层的init工作......// Phone policy is specific to phone implementations and hence if a device wants to exclude // it out then it can be disabled by using the flag below. if (getResources().getBoolean(com.android.bluetooth.R.bool.enable_phone_policy)) { Log.i(TAG, "Phone policy enabled"); mPhonePolicy = new PhonePolicy(this, new ServiceFactory());//启动PhonePolicy,它会根据触发重连之前的设备;在available的设备之间处理连接切换等 mPhonePolicy.start(); } else { Log.i(TAG, "Phone policy disabled"); } mActiveDeviceManager = new ActiveDeviceManager(this, new ServiceFactory());//处理Active Device的管理类;比如Android默认可以连接多个sink设备,但只有一个出声,这个就是active的device; //要通过AudioManager的接口告知Audio当前系统哪个device是active的,这样Audio系统才能根据策略选择正确的设备播放音频 mActiveDeviceManager.start(); setAdapterService(this);//保存当前的AdapterServie实例,因为其他的类里可能要获取它......}...... @Override public IBinder onBind(Intent intent) { debugLog("onBind()"); return mBinder; }...... /** * Handlers for incoming service calls */ private AdapterServiceBinder mBinder; /** * The Binder implementation must be declared to be a static class, with * the AdapterService instance passed in the constructor. Furthermore, * when the AdapterService shuts down, the reference to the AdapterService * must be explicitly removed. * * Otherwise, a memory leak can occur from repeated starting/stopping the * service...Please refer to android.os.Binder for further details on * why an inner instance class should be avoided. * */ private static class AdapterServiceBinder extends IBluetooth.Stub { private AdapterService mService; AdapterServiceBinder(AdapterService svc) { mService = svc; } public void cleanup() { mService = null; } public AdapterService getService() { if (mService != null && mService.isAvailable()) { return mService; } return null; }...... @Override public boolean enable() { if ((Binder.getCallingUid() != Process.SYSTEM_UID) && (!Utils.checkCaller())) { Log.w(TAG, "enable() - Not allowed for non-active user and non system user"); return false; } AdapterService service = getService(); if (service == null) { return false; } return service.enable(); }......}}}
从code看出,BluetoothManagerService先获取到IBinder对象,再通过它调用AdapterService的对于方法完成工作。为了较好的跟flow,我们先看初始化部分;其他的细节可以参考注释:
加载AdapterService类时,需要完成的static代码块调用:
static { classInitNative(); }......static void classInitNative(JNIEnv* env, jclass clazz) { jclass jniUidTrafficClass = env->FindClass("android/bluetooth/UidTraffic"); android_bluetooth_UidTraffic.constructor = env->GetMethodID(jniUidTrafficClass, "", "(IJJ)V"); jclass jniCallbackClass = env->FindClass("com/android/bluetooth/btservice/JniCallbacks"); sJniCallbacksField = env->GetFieldID( clazz, "mJniCallbacks", "Lcom/android/bluetooth/btservice/JniCallbacks;");//获取AdapterService中的mJniCallbacks实例,通知上层stack的变化信息 method_stateChangeCallback = env->GetMethodID(jniCallbackClass, "stateChangeCallback", "(I)V");// method_adapterPropertyChangedCallback = env->GetMethodID( jniCallbackClass, "adapterPropertyChangedCallback", "([I[[B)V"); method_discoveryStateChangeCallback = env->GetMethodID( jniCallbackClass, "discoveryStateChangeCallback", "(I)V"); method_devicePropertyChangedCallback = env->GetMethodID( jniCallbackClass, "devicePropertyChangedCallback", "([B[I[[B)V"); method_deviceFoundCallback = env->GetMethodID(jniCallbackClass, "deviceFoundCallback", "([B)V"); method_pinRequestCallback = env->GetMethodID(jniCallbackClass, "pinRequestCallback", "([B[BIZ)V"); method_sspRequestCallback = env->GetMethodID(jniCallbackClass, "sspRequestCallback", "([B[BIII)V"); method_bondStateChangeCallback = env->GetMethodID(jniCallbackClass, "bondStateChangeCallback", "(I[BI)V"); method_aclStateChangeCallback = env->GetMethodID(jniCallbackClass, "aclStateChangeCallback", "(I[BI)V"); method_setWakeAlarm = env->GetMethodID(clazz, "setWakeAlarm", "(JZ)Z"); method_acquireWakeLock = env->GetMethodID(clazz, "acquireWakeLock", "(Ljava/lang/String;)Z"); method_releaseWakeLock = env->GetMethodID(clazz, "releaseWakeLock", "(Ljava/lang/String;)Z"); method_energyInfo = env->GetMethodID( clazz, "energyInfoCallback", "(IIJJJJ[Landroid/bluetooth/UidTraffic;)V"); if (hal_util_load_bt_library((bt_interface_t const**)&sBluetoothInterface)) {//加载bt stack的so,获取操作句柄sBluetoothInterface;用以调用stack的接口完成操作 ALOGE("No Bluetooth Library found"); }}
这部分初始化工作,从code看很清晰;主要做两件事:
- 在Jni层获取AdapterService中的callback接口,当stack上报状态时,需要通过这些接口反馈到framework层
- 解析bt so,获取它暴露给上层的接口,用来将framework的操作请求真正下发到协议栈中。主要是dlopen方式操作so、拿到操作handle的,source code部分主要在Pie_9.0.0_r3\system\bt\main中
bt_interface_t类型定义的都是上层会涉及到的bt操作,如果connect/disconnect、createBond/removeBond等,最终都会此类型将请求下发到协议栈中:
/** Represents the standard Bluetooth DM interface. */typedef struct { /** set to sizeof(bt_interface_t) */ size_t size; /** * Opens the interface and provides the callback routines * to the implemenation of this interface. */ int (*init)(bt_callbacks_t* callbacks); /** Enable Bluetooth. */ int (*enable)(bool guest_mode); /** Disable Bluetooth. */ int (*disable)(void); /** Closes the interface. */ void (*cleanup)(void); /** Remove Bond */ int (*remove_bond)(const RawAddress* bd_addr); /** Cancel Bond */ int (*cancel_bond)(const RawAddress* bd_addr); /** * Get the connection status for a given remote device. * return value of 0 means the device is not connected, * non-zero return status indicates an active connection. */ int (*get_connection_state)(const RawAddress* bd_addr); /** Read Energy info details - return value indicates BT_STATUS_SUCCESS or * BT_STATUS_NOT_READY Success indicates that the VSC command was sent to * controller */ int (*read_energy_info)(); /** * Get the AvrcpTarget Service interface to interact with the Avrcp Service */ bluetooth::avrcp::ServiceInterface* (*get_avrcp_service)(void);} bt_interface_t;
静态初始化块完成后,就是Service::onCreate()的调用,除了前面提到的初始化一些重要的Java对象外,还会做一些Native层的初始化:
static bool initNative(JNIEnv* env, jobject obj) { ALOGV("%s", __func__); android_bluetooth_UidTraffic.clazz = (jclass)env->NewGlobalRef(env->FindClass("android/bluetooth/UidTraffic")); sJniAdapterServiceObj = env->NewGlobalRef(obj); sJniCallbacksObj = env->NewGlobalRef(env->GetObjectField(obj, sJniCallbacksField)); if (!sBluetoothInterface) { return JNI_FALSE; } int ret = sBluetoothInterface->init(&sBluetoothCallbacks);//将需要的一些callback函数注册到stack中,这样stack就可以通过这些函数上报此类事件 if (ret != BT_STATUS_SUCCESS) { ALOGE("Error while setting the callbacks: %d\n", ret); sBluetoothInterface = NULL; return JNI_FALSE; } ret = sBluetoothInterface->set_os_callouts(&sBluetoothOsCallouts);//将需要的一些callback函数注册到stack中,这样stack就可以通过这些函数上报此类事件 if (ret != BT_STATUS_SUCCESS) { ALOGE("Error while setting Bluetooth callouts: %d\n", ret); sBluetoothInterface->cleanup(); sBluetoothInterface = NULL; return JNI_FALSE; }......static bt_callbacks_t sBluetoothCallbacks = { sizeof(sBluetoothCallbacks), adapter_state_change_callback, adapter_properties_callback, remote_device_properties_callback, device_found_callback, discovery_state_changed_callback, pin_request_callback, ssp_request_callback, bond_state_changed_callback, acl_state_changed_callback, callback_thread_event, dut_mode_recv_callback, le_test_mode_recv_callback, energy_info_recv_callback};......static bt_os_callouts_t sBluetoothOsCallouts = { sizeof(sBluetoothOsCallouts), set_wake_alarm_callout, acquire_wake_lock_callout, release_wake_lock_callout,};
将stack需要用到的一些callback函数注册给它,这样在需要的时候,stack就可以通过调用这些函数将信息反馈到上层了。
这条路串起来之后,再回头看AdapterService::enable():
public synchronized boolean enable(boolean quietMode) { enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, "Need BLUETOOTH ADMIN permission"); // Enforce the user restriction for disallowing Bluetooth if it was set. if (mUserManager.hasUserRestriction(UserManager.DISALLOW_BLUETOOTH, UserHandle.SYSTEM)) { debugLog("enable() called when Bluetooth was disallowed"); return false; } debugLog("enable() - Enable called with quiet mode status = " + quietMode); mQuietmode = quietMode; mAdapterStateMachine.sendMessage(AdapterState.BLE_TURN_ON); return true; }
可以看到只是简单的向AdapterState发送一个BLE_TURN_ON msg,随机进入状态机去处理;
/** * This state machine handles Bluetooth Adapter State. * Stable States: * {@link OffState}: Initial State * {@link BleOnState} : Bluetooth Low Energy, Including GATT, is on * {@link OnState} : Bluetooth is on (All supported profiles) * * Transition States: * {@link TurningBleOnState} : OffState to BleOnState * {@link TurningBleOffState} : BleOnState to OffState * {@link TurningOnState} : BleOnState to OnState * {@link TurningOffState} : OnState to BleOnState * * +------ Off <-----+ * | | * v | * TurningBleOn TO---> TurningBleOff * | ^ ^ * | | | * +-----> ----+ | * BleOn | * +------ <---+ O * v | T * TurningOn TO----> TurningOff * | ^ * | | * +-----> On ------+ * */
从上图AdapterState的注释及code,我们知道以下几点:
- AdapterState中所有State的父类都是BaseAdapterState,所以在enter某个状态机时,会先调用此父类的enter()接口;同时,在exit某个状态机时,也会call此父类的exit()接口
- 默认的初始化状态时Off状态,也就是此时BT尚未启动
- 因为AdapterState是管理BT启动的逻辑主要部分,所以向外通知当前BT使能进程的消息,应该在这里触发比较合理
因为在某个状态节点,我们都应该向外通知状态,所以这部分被封装到了父类State中:
AdapterState: private abstract class BaseAdapterState extends State { abstract int getStateValue(); @Override public void enter() { int currState = getStateValue(); infoLog("entered "); mAdapterService.updateAdapterState(mPrevState, currState);//通过AdapterService向外通知BT使能的状态信息 mPrevState = currState; }...... }AdapterService: void updateAdapterState(int prevState, int newState) {//如果某个服务对蓝牙启动状态过程感兴趣,它就应该注册IBluetootCallback对象;跟BluetoothManagerService一样 mAdapterProperties.setState(newState); if (mCallbacks != null) { int n = mCallbacks.beginBroadcast(); debugLog("updateAdapterState() - Broadcasting state " + BluetoothAdapter.nameForState( newState) + " to " + n + " receivers."); for (int i = 0; i < n; i++) { try { mCallbacks.getBroadcastItem(i).onBluetoothStateChange(prevState, newState);//调用onBluetoothStateChange()回调状态变化 } catch (RemoteException e) { debugLog("updateAdapterState() - Callback #" + i + " failed (" + e + ")"); } } mCallbacks.finishBroadcast(); }...... }BluetoothManagerService: 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);//发送MESSAGE_BLUETOOTH_STATE_CHANGE mHandler.sendMessage(msg); } };
这里我们发送的是BLE_TURN_ON msg,看它的处理:
private class OffState extends BaseAdapterState { @Override int getStateValue() { return BluetoothAdapter.STATE_OFF; } @Override public boolean processMessage(Message msg) { switch (msg.what) { case BLE_TURN_ON: transitionTo(mTurningBleOnState); break; default: infoLog("Unhandled message - " + messageString(msg.what)); return false; } return true; } }...... private class TurningBleOnState extends BaseAdapterState { @Override int getStateValue() { return BluetoothAdapter.STATE_BLE_TURNING_ON; } @Override public void enter() { super.enter(); sendMessageDelayed(BLE_START_TIMEOUT, BLE_START_TIMEOUT_DELAY); mAdapterService.bringUpBle(); } @Override public void exit() { removeMessages(BLE_START_TIMEOUT); super.exit(); } @Override public boolean processMessage(Message msg) { switch (msg.what) { case BLE_STARTED: transitionTo(mBleOnState); break; case BLE_START_TIMEOUT: errorLog(messageString(msg.what)); transitionTo(mTurningBleOffState); break; default: infoLog("Unhandled message - " + messageString(msg.what)); return false; } return true; } }...... }
BLE_TURN_ON的消息处理是transferTo TurningBleOnState,它的enter()会调用mAdapterService.bringUpBle():
void bringUpBle() { debugLog("bleOnProcessStart()"); if (getResources().getBoolean( R.bool.config_bluetooth_reload_supported_profiles_when_enabled)) { Config.init(getApplicationContext()); } // Reset |mRemoteDevices| whenever BLE is turned off then on // This is to replace the fact that |mRemoteDevices| was // reinitialized in previous code. // // TODO(apanicke): The reason is unclear but // I believe it is to clear the variable every time BLE was // turned off then on. The same effect can be achieved by // calling cleanup but this may not be necessary at all // We should figure out why this is needed later mRemoteDevices.reset();//RemoteDeivces管理对端设备的一些信息 mAdapterProperties.init(mRemoteDevices);//AdapterProperties管理当前Adapter的一些信息 debugLog("bleOnProcessStart() - Make Bond State Machine"); mBondStateMachine = BondStateMachine.make(this, mAdapterProperties, mRemoteDevices);//创建BondStateMachine对象,它负责管理一个device的配对过程 mJniCallbacks.init(mBondStateMachine, mRemoteDevices);//JniCallbacks主要负责监听来自stack的callback信息,如设备配对状态或设备更新UUID变化时,framework就可以收到回调 try { mBatteryStats.noteResetBleScan(); } catch (RemoteException e) { Log.w(TAG, "RemoteException trying to send a reset to BatteryStats"); } StatsLog.write_non_chained(StatsLog.BLE_SCAN_STATE_CHANGED, -1, null, StatsLog.BLE_SCAN_STATE_CHANGED__STATE__RESET, false, false, false); //Start Gatt service setProfileServiceState(GattService.class, BluetoothAdapter.STATE_ON);//启动GattService服务,BLE设备需要GATT协议交换信息 }
除了创建一些重要对象外,这里主要就是起到GattService了,Ble设备都需要通过GATT协议交换信息;其他可以参考上面的注释。
Bluetooth framework声明的Profile服务基本都是ProfileService的子类,所以参照Android Service的启动过程,某个Profile启动时,会调用到ProfileService的方法:
/** * Base class for a background service that runs a Bluetooth profile */public abstract class ProfileService extends Service { @Override public int onStartCommand(Intent intent, int flags, int startId) { ...... if (state == BluetoothAdapter.STATE_OFF) { doStop();//通知AdapterService的此Profile停止成功 } else if (state == BluetoothAdapter.STATE_ON) { doStart();//通知AdapterService的此Profile启动成功 } } return PROFILE_SERVICE_MODE; } private void doStart() { ...... mAdapterService.addProfile(this);//告知AdapterService此Profile启动成功,更新Profile集合 ...... mAdapterService.onProfileServiceStateChanged(this, BluetoothAdapter.STATE_ON);//通知AdapterService此Profile已启动 } private void doStop() { ...... if (mAdapterService != null) { mAdapterService.onProfileServiceStateChanged(this, BluetoothAdapter.STATE_OFF);//通知AdapterService此Profile已停止 } if (!stop()) { Log.e(mName, "Unable to stop profile"); } if (mAdapterService != null) { mAdapterService.removeProfile(this);//告知AdapterService此Profile停止成功,更新Profile集合 } ...... stopSelf(); }}
接着看AdapterService的处理:
/** * Register a {@link ProfileService} with AdapterService. * * @param profile the service being added. */ public void addProfile(ProfileService profile) { mHandler.obtainMessage(MESSAGE_PROFILE_SERVICE_REGISTERED, profile).sendToTarget(); } /** * Unregister a ProfileService with AdapterService. * * @param profile the service being removed. */ public void removeProfile(ProfileService profile) { mHandler.obtainMessage(MESSAGE_PROFILE_SERVICE_UNREGISTERED, profile).sendToTarget(); } /** * Notify AdapterService that a ProfileService has started or stopped. * * @param profile the service being removed. * @param state {@link BluetoothAdapter#STATE_ON} or {@link BluetoothAdapter#STATE_OFF} */ public void onProfileServiceStateChanged(ProfileService profile, int state) { if (state != BluetoothAdapter.STATE_ON && state != BluetoothAdapter.STATE_OFF) { throw new IllegalArgumentException(BluetoothAdapter.nameForState(state)); } Message m = mHandler.obtainMessage(MESSAGE_PROFILE_SERVICE_STATE_CHANGED); m.obj = profile; m.arg1 = state; mHandler.sendMessage(m); } private static final int MESSAGE_PROFILE_SERVICE_STATE_CHANGED = 1; private static final int MESSAGE_PROFILE_SERVICE_REGISTERED = 2; private static final int MESSAGE_PROFILE_SERVICE_UNREGISTERED = 3; class AdapterServiceHandler extends Handler { @Override public void handleMessage(Message msg) { debugLog("handleMessage() - Message: " + msg.what); switch (msg.what) { case MESSAGE_PROFILE_SERVICE_STATE_CHANGED: debugLog("handleMessage() - MESSAGE_PROFILE_SERVICE_STATE_CHANGED"); processProfileServiceStateChanged((ProfileService) msg.obj, msg.arg1); break; case MESSAGE_PROFILE_SERVICE_REGISTERED: debugLog("handleMessage() - MESSAGE_PROFILE_SERVICE_REGISTERED"); registerProfileService((ProfileService) msg.obj); break; case MESSAGE_PROFILE_SERVICE_UNREGISTERED: debugLog("handleMessage() - MESSAGE_PROFILE_SERVICE_UNREGISTERED"); unregisterProfileService((ProfileService) msg.obj); break; } } private void registerProfileService(ProfileService profile) { if (mRegisteredProfiles.contains(profile)) { Log.e(TAG, profile.getName() + " already registered."); return; } mRegisteredProfiles.add(profile); } private void unregisterProfileService(ProfileService profile) { if (!mRegisteredProfiles.contains(profile)) { Log.e(TAG, profile.getName() + " not registered (UNREGISTERED)."); return; } mRegisteredProfiles.remove(profile); } private void processProfileServiceStateChanged(ProfileService profile, int state) { switch (state) { case BluetoothAdapter.STATE_ON://此时是启动GattService,所以是STATE_ON if (!mRegisteredProfiles.contains(profile)) { Log.e(TAG, profile.getName() + " not registered (STATE_ON)."); return; } if (mRunningProfiles.contains(profile)) {//防止重复启动某个Profile Log.e(TAG, profile.getName() + " already running."); return; } mRunningProfiles.add(profile); if (GattService.class.getSimpleName().equals(profile.getName())) { enableNativeWithGuestFlag();//如果是启动Gatt profile,则向stack下发enable bt的指令 } else if (mRegisteredProfiles.size() == Config.getSupportedProfiles().length && mRegisteredProfiles.size() == mRunningProfiles.size()) {//这里是启动Gatt以外的,在config.xml中声明支持的其他Profile;相当于启动BREDR mode mAdapterProperties.onBluetoothReady(); updateUuids(); setBluetoothClassFromConfig(); mAdapterStateMachine.sendMessage(AdapterState.BREDR_STARTED); } break; case BluetoothAdapter.STATE_OFF: if (!mRegisteredProfiles.contains(profile)) { Log.e(TAG, profile.getName() + " not registered (STATE_OFF)."); return; } if (!mRunningProfiles.contains(profile)) { Log.e(TAG, profile.getName() + " not running."); return; } mRunningProfiles.remove(profile); // If only GATT is left, send BREDR_STOPPED. if ((mRunningProfiles.size() == 1 && (GattService.class.getSimpleName() .equals(mRunningProfiles.get(0).getName())))) { mAdapterStateMachine.sendMessage(AdapterState.BREDR_STOPPED); } else if (mRunningProfiles.size() == 0) { disableNative(); mAdapterStateMachine.sendMessage(AdapterState.BLE_STOPPED); } break; default: Log.e(TAG, "Unhandled profile state: " + state); } } }
处理enable 蓝牙:
private void enableNativeWithGuestFlag() { boolean isGuest = UserManager.get(this).isGuestUser(); if (!enableNative(isGuest)) { Log.e(TAG, "enableNative() returned false"); } }static jboolean enableNative(JNIEnv* env, jobject obj, jboolean isGuest) { ALOGV("%s", __func__); if (!sBluetoothInterface) return JNI_FALSE; int ret = sBluetoothInterface->enable(isGuest == JNI_TRUE ? 1 : 0); return (ret == BT_STATUS_SUCCESS || ret == BT_STATUS_DONE) ? JNI_TRUE : JNI_FALSE;}
前面有介绍到stack的state回调会通过JNICallbacks对象回调上来,enable状态也是如此:
final class JniCallbacks { void stateChangeCallback(int status) { mAdapterService.stateChangeCallback(status); }}AdapterService: void stateChangeCallback(int status) { if (status == AbstractionLayer.BT_STATE_OFF) { debugLog("stateChangeCallback: disableNative() completed"); } else if (status == AbstractionLayer.BT_STATE_ON) {//BT State on mAdapterStateMachine.sendMessage(AdapterState.BLE_STARTED); } else { Log.e(TAG, "Incorrect status " + status + " in stateChangeCallback"); } }
BT启动之后,向AdapterState通知状态,TurningBleOnState收到消息后,就会进入BleOnState;并对外通知状态变化,如之前介绍,是通过AdapterService::updateAdapterState()函数处理:
void updateAdapterState(int prevState, int newState) {//如果某个服务对蓝牙启动状态过程感兴趣,它就应该注册IBluetootCallback对象;跟BluetoothManagerService一样 mAdapterProperties.setState(newState); if (mCallbacks != null) { int n = mCallbacks.beginBroadcast(); debugLog("updateAdapterState() - Broadcasting state " + BluetoothAdapter.nameForState( newState) + " to " + n + " receivers."); for (int i = 0; i < n; i++) { try { mCallbacks.getBroadcastItem(i).onBluetoothStateChange(prevState, newState);//调用onBluetoothStateChange()回调状态变化 } catch (RemoteException e) { debugLog("updateAdapterState() - Callback #" + i + " failed (" + e + ")"); } } mCallbacks.finishBroadcast(); } // Turn the Adapter all the way off if we are disabling and the snoop log setting changed. if (newState == BluetoothAdapter.STATE_BLE_TURNING_ON) { mSnoopLogSettingAtEnable = SystemProperties.getBoolean(BLUETOOTH_BTSNOOP_ENABLE_PROPERTY, false); } else if (newState == BluetoothAdapter.STATE_BLE_ON && prevState != BluetoothAdapter.STATE_OFF) { boolean snoopLogSetting = SystemProperties.getBoolean(BLUETOOTH_BTSNOOP_ENABLE_PROPERTY, false); if (mSnoopLogSettingAtEnable != snoopLogSetting) { mAdapterStateMachine.sendMessage(AdapterState.BLE_TURN_OFF); } } }
在介绍BluetoothManagerService时,我们就提到BMS会向AdapterService注册一个callback来监听BT的状态:
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);//发送MESSAGE_BLUETOOTH_STATE_CHANGE mHandler.sendMessage(msg); } };
处理Msg:
case MESSAGE_BLUETOOTH_STATE_CHANGE: { int prevState = msg.arg1; int newState = msg.arg2; if (DBG) { Slog.d(TAG, "MESSAGE_BLUETOOTH_STATE_CHANGE: " + BluetoothAdapter.nameForState( prevState) + " > " + BluetoothAdapter.nameForState( newState)); } mState = newState; bluetoothStateChangeHandler(prevState, newState);//处理state变化 ...... }
看bluetoothStateChangeHandler()的主要处理:
// Notify all proxy objects first of adapter state change if (newState == BluetoothAdapter.STATE_BLE_ON || newState == BluetoothAdapter.STATE_OFF) { boolean intermediate_off = (prevState == BluetoothAdapter.STATE_TURNING_OFF && newState == BluetoothAdapter.STATE_BLE_ON); if (newState == BluetoothAdapter.STATE_OFF) { // If Bluetooth is off, send service down event to proxy objects, and unbind if (DBG) { Slog.d(TAG, "Bluetooth is complete send Service Down"); } sendBluetoothServiceDownCallback(); unbindAndFinish(); sendBleStateChanged(prevState, newState); // Don't broadcast as it has already been broadcast before isStandardBroadcast = false; } else if (!intermediate_off) {//现在state是BLE_ON // connect to GattService if (DBG) { Slog.d(TAG, "Bluetooth is in LE only mode"); } if (mBluetoothGatt != null || !mContext.getPackageManager() .hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) {//此时GattService只是启动了,BMS还未拿到它的Binder操作句柄 continueFromBleOnState(); } else { if (DBG) { Slog.d(TAG, "Binding Bluetooth GATT service"); } Intent i = new Intent(IBluetoothGatt.class.getName()); doBind(i, mConnection, Context.BIND_AUTO_CREATE | Context.BIND_IMPORTANT, UserHandle.CURRENT);//这里去Bind GattService,然后在BluetoothServiceConnection中触发MESSAGE_BLUETOOTH_SERVICE_CONNECTED msg,并区分是SERVICE_IBLUETOOTHGATT } sendBleStateChanged(prevState, newState); //Don't broadcase this as std intent isStandardBroadcast = false; } else if (intermediate_off) { if (DBG) { Slog.d(TAG, "Intermediate off, back to LE only mode"); } // For LE only mode, broadcast as is sendBleStateChanged(prevState, newState); sendBluetoothStateCallback(false); // BT is OFF for general users // Broadcast as STATE_OFF newState = BluetoothAdapter.STATE_OFF; sendBrEdrDownCallback(); } }
BluetoothManagerService中Bind Profile的内容跟之前介绍的一样,我们直接看处理:
case MESSAGE_BLUETOOTH_SERVICE_CONNECTED: { if (DBG) { Slog.d(TAG, "MESSAGE_BLUETOOTH_SERVICE_CONNECTED: " + msg.arg1); } IBinder service = (IBinder) msg.obj; //保存Service的onBinder()句柄 try { mBluetoothLock.writeLock().lock(); if (msg.arg1 == SERVICE_IBLUETOOTHGATT) { mBluetoothGatt = IBluetoothGatt.Stub.asInterface(Binder.allowBlocking(service));//获取GattService的句柄 continueFromBleOnState();//启动BREDR的profile break; } // else must be SERVICE_IBLUETOOTH}
获取Gatt profile的Binder句柄,并调用continueFromBleOnState()去启动其他的profile:
/** * Call IBluetooth.onLeServiceUp() to continue if Bluetooth should be on. */ private void continueFromBleOnState() { if (DBG) { Slog.d(TAG, "continueFromBleOnState()"); } try { mBluetoothLock.readLock().lock(); if (mBluetooth == null) { Slog.e(TAG, "onBluetoothServiceUp: mBluetooth is null!"); return; } if (isBluetoothPersistedStateOnBluetooth() || !isBleAppPresent()) { // This triggers transition to STATE_ON mBluetooth.onLeServiceUp();//调用onLeServiceUp() persistBluetoothSetting(BLUETOOTH_ON_BLUETOOTH); } } catch (RemoteException e) { Slog.e(TAG, "Unable to call onServiceUp", e); } finally { mBluetoothLock.readLock().unlock(); } }AdapterService: void onLeServiceUp() { mAdapterStateMachine.sendMessage(AdapterState.USER_TURN_ON);//发送USER_TURN_ON }//现在处于BleOnState,处理此消息进入TurningOnStateAdapterState: private class TurningOnState extends BaseAdapterState { @Override int getStateValue() { return BluetoothAdapter.STATE_TURNING_ON; } @Override public void enter() { super.enter(); sendMessageDelayed(BREDR_START_TIMEOUT, BREDR_START_TIMEOUT_DELAY); mAdapterService.startProfileServices(); } ......}//启动配置文件中定义的Profile:AdapterService: void startProfileServices() { debugLog("startCoreServices()"); Class[] supportedProfileServices = Config.getSupportedProfiles(); if (supportedProfileServices.length == 1 && GattService.class.getSimpleName() .equals(supportedProfileServices[0].getSimpleName())) { mAdapterProperties.onBluetoothReady(); updateUuids(); setBluetoothClassFromConfig(); mAdapterStateMachine.sendMessage(AdapterState.BREDR_STARTED); } else { setAllProfileServiceStates(supportedProfileServices, BluetoothAdapter.STATE_ON); } }
最终的处理是启动全部在Bluetooth.apk的config.xml中定义的Profile,Config.getSupportedProfiles()调用拿到的Profile集合就是声明了true的Service:
true false true true false true true true true true true true true true false false false false true false
setAllProfileServiceStates()就是以STATE_ON的状态启动所有这些supported的Profile,它们也都是ProfileService的子类:
private void setAllProfileServiceStates(Class[] services, int state) { for (Class service : services) { if (GattService.class.getSimpleName().equals(service.getSimpleName())) { continue; } setProfileServiceState(service, state); } }
所以也跟GattService启动的flow类似,AdapterService会处理这些Profile的状态变化,这里是STATE_ON:
private void processProfileServiceStateChanged(ProfileService profile, int state) { switch (state) { case BluetoothAdapter.STATE_ON://此时是启动GattService,所以是STATE_ON if (!mRegisteredProfiles.contains(profile)) { Log.e(TAG, profile.getName() + " not registered (STATE_ON)."); return; } if (mRunningProfiles.contains(profile)) {//防止重复启动某个Profile Log.e(TAG, profile.getName() + " already running."); return; } mRunningProfiles.add(profile); if (GattService.class.getSimpleName().equals(profile.getName())) { enableNativeWithGuestFlag();//如果是启动Gatt profile,则向stack下发enable bt的指令 } else if (mRegisteredProfiles.size() == Config.getSupportedProfiles().length && mRegisteredProfiles.size() == mRunningProfiles.size()) {//这里是启动Gatt以外的,在config.xml中声明支持的其他Profile;相当于启动BREDR mode mAdapterProperties.onBluetoothReady();//Profile全部启动完成,初始化变化,并设置当前Bt工作的mode updateUuids();//更新UUID setBluetoothClassFromConfig(); mAdapterStateMachine.sendMessage(AdapterState.BREDR_STARTED);//通知AdapterState,随即进入OnState;BT启动成功 } break;......}
mRegisteredProfiles、mRunningProfiles最终会跟config声明的Profile一致,然后继续做一些设置工作,其中我们可能比较关心的就是设置当前蓝牙的工作模式了:
void onBluetoothReady() { debugLog("onBluetoothReady, state=" + BluetoothAdapter.nameForState(getState()) + ", ScanMode=" + mScanMode); synchronized (mObject) { // Reset adapter and profile connection states setConnectionState(BluetoothAdapter.STATE_DISCONNECTED); mProfileConnectionState.clear(); mProfilesConnected = 0; mProfilesConnecting = 0; mProfilesDisconnecting = 0; // adapterPropertyChangedCallback has already been received. Set the scan mode. setScanMode(AbstractionLayer.BT_SCAN_MODE_CONNECTABLE);//当前设备可以扫描和连接其他设备,其他设备无法扫描到当前设备 // This keeps NV up-to date on first-boot after flash. setDiscoverableTimeout(mDiscoverableTimeout);//设置扫描的超时时长 } }
我们可以在这里设置希望的蓝牙工作模式和扫描超时时长,这样蓝牙的启动工作就基本结束了。
更多相关文章
- 利用Java反射技术调用Android中被隐藏的API
- android TIF启动流程
- Android(安卓)Java中调用js代码,js中调用Java代码
- android 通过设置intent-filter 启动程序
- Android(安卓)OTA升级(2):开启升级过程
- 转:adb shell start中启动activity和service
- Android(安卓)Service使用
- [学习记录]旋转屏幕禁止重新调用oncreat
- Android(安卓)FrameWork 之Binder机制初识