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看很清晰;主要做两件事:

  1. 在Jni层获取AdapterService中的callback接口,当stack上报状态时,需要通过这些接口反馈到framework层
  2. 解析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,我们知道以下几点:

  1. AdapterState中所有State的父类都是BaseAdapterState,所以在enter某个状态机时,会先调用此父类的enter()接口;同时,在exit某个状态机时,也会call此父类的exit()接口
  2. 默认的初始化状态时Off状态,也就是此时BT尚未启动
  3. 因为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);//设置扫描的超时时长        }    }

我们可以在这里设置希望的蓝牙工作模式和扫描超时时长,这样蓝牙的启动工作就基本结束了。

更多相关文章

  1. 利用Java反射技术调用Android中被隐藏的API
  2. android TIF启动流程
  3. Android(安卓)Java中调用js代码,js中调用Java代码
  4. android 通过设置intent-filter 启动程序
  5. Android(安卓)OTA升级(2):开启升级过程
  6. 转:adb shell start中启动activity和service
  7. Android(安卓)Service使用
  8. [学习记录]旋转屏幕禁止重新调用oncreat
  9. Android(安卓)FrameWork 之Binder机制初识

随机推荐

  1. 《深入探索Android热修复原理》代码热修
  2. Android——layout_marginStart和layout_
  3. Android(安卓)Studio中使用.9(Nine Patch)
  4. android简单的颜色选择器制作
  5. Android(安卓)增强版百分比布局库 Eclips
  6. Android(安卓)Ap 开发 设计模式第三篇:模
  7. android 修改ramdisk.img和init.rc && an
  8. Android(安卓)绘图XML——Shape
  9. android 控件之ProgressBar实现双进度条(
  10. 为 HTC 的 Android(安卓)手机正名