Android系统开启蓝牙源码分析(下)

上篇博客我总结了Android打开蓝牙分为4个阶段,第一阶段就是打开蓝牙的方法从APP调到systemServer再到Bluetooth协议栈,最后走到了hardware蓝牙硬件设备。如下图绿色虚线的流程:
在这里插入图片描述

经过了硬件的一些列操作,正真打开了蓝牙设备,下面继续分析。
第二阶段:(对应图中蓝色虚线流程)
在蓝牙打开成功之后,JNI层会通过JniCallbacks的stateChangeCallback方法把消息回调给AdapterService处理,AdapterService则继续把消息给到状态机处理:

void stateChangeCallback(int status) {
        if (status == AbstractionLayer.BT_STATE_OFF) {
            debugLog("stateChangeCallback: disableNative() completed");
            mAdapterStateMachine.sendMessage(AdapterState.BLE_STOPPED);
        } else if (status == AbstractionLayer.BT_STATE_ON) {
            mAdapterStateMachine.sendMessage(AdapterState.BLE_STARTED);
        } else {
            Log.e(TAG, "Incorrect status " + status + " in stateChangeCallback");
        }
    }

此时的AdapterState处于TurningBleOnState状态,TurningBleOnState在接收到BLE_STARTED消息后,迁入到BleOnState状态:

 private class TurningBleOnState extends BaseAdapterState {
		.......
        @Override
        public boolean processMessage(Message msg) {
            switch (msg.what) {
                case BLE_STARTED:
                    transitionTo(mBleOnState);
                    break;
               ........
    }

每一个状态的迁移,都会触发AdapterService的updateAdapterState,这个方法内部会把状态改变回调给远程的监听者:

void updateAdapterState(int prevState, int newState) {
        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);  //远程回调
                } catch (RemoteException e) {
                    debugLog("updateAdapterState() - Callback #" + i + " failed (" + e + ")");
                }
            }
            mCallbacks.finishBroadcast();
        }

这里会远程回调到BluetoothManagerService里面的监听接口,经过handler消息处理机制会调用到bluetoothStateChangeHandler方法:

private void bluetoothStateChangeHandler(int prevState, int newState) {
	
	if (newState == BluetoothAdapter.STATE_BLE_ON || newState == BluetoothAdapter.STATE_OFF) {
			.......
			continueFromBleOnState();
	}

}
/**
     * Call IBluetooth.onLeServiceUp() to continue if Bluetooth should be on.
     */
    private void continueFromBleOnState() {
 			..........          
            if (isBluetoothPersistedStateOnBluetooth() || !isBleAppPresent()) {
                // This triggers transition to STATE_ON
                mBluetooth.onLeServiceUp();
                persistBluetoothSetting(BLUETOOTH_ON_BLUETOOTH);
            }
      
    }

在这里,正常情况下都会走到mBluetooth.onLeServiceUp()这个方法,至此,第二阶段的流程已经走完。接下来就是进入第三阶段,让Bluetooth继续去完成BLE打开之后的后续的流程。

第三阶段:(对应图中紫色虚线流程)
Bluetooth协议栈的AdapterService在接收到onLeServiceUp的调用之后,会给AdapterState状态机发一条AdapterState.USER_TURN_ON的消息,于是这次操作又交到了AdapterState状态机去处理了。其实我们可以看到,状态机对于整个蓝牙状态的管理是非常重要,同时也让逻辑更加清晰。

void onLeServiceUp() {
        mAdapterStateMachine.sendMessage(AdapterState.USER_TURN_ON);
    }

此时状态机处于BleOnState状态,在接收到USER_TURN_ON后,把状态迁入TurningOnState状态:

 private class BleOnState extends BaseAdapterState {

        @Override
        public boolean processMessage(Message msg) {
            switch (msg.what) {
                case USER_TURN_ON:
                    transitionTo(mTurningOnState);
                    break;

TurningOnState在进入的时候,会去调用AdapterService的startProfileServices方法,从名字就可以看出它是去开启各个ProfileService:

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呢,我们可以了解一下:

private static final ProfileConfig[] PROFILE_SERVICES_AND_FLAGS = {
            new ProfileConfig(HeadsetService.class, R.bool.profile_supported_hs_hfp,
                    (1 << BluetoothProfile.HEADSET)),
            new ProfileConfig(A2dpService.class, R.bool.profile_supported_a2dp,
                    (1 << BluetoothProfile.A2DP)),
            new ProfileConfig(A2dpSinkService.class, R.bool.profile_supported_a2dp_sink,
                    (1 << BluetoothProfile.A2DP_SINK)),
            new ProfileConfig(HidHostService.class, R.bool.profile_supported_hid_host,
                    (1 << BluetoothProfile.HID_HOST)),
            new ProfileConfig(PanService.class, R.bool.profile_supported_pan,
                    (1 << BluetoothProfile.PAN)),
            new ProfileConfig(GattService.class, R.bool.profile_supported_gatt,
                    (1 << BluetoothProfile.GATT)),
            new ProfileConfig(BluetoothMapService.class, R.bool.profile_supported_map,
                    (1 << BluetoothProfile.MAP)),
            new ProfileConfig(HeadsetClientService.class, R.bool.profile_supported_hfpclient,
                    (1 << BluetoothProfile.HEADSET_CLIENT)),
            new ProfileConfig(AvrcpTargetService.class, R.bool.profile_supported_avrcp_target,
                    (1 << BluetoothProfile.AVRCP)),
            new ProfileConfig(AvrcpControllerService.class,
                    R.bool.profile_supported_avrcp_controller,
                    (1 << BluetoothProfile.AVRCP_CONTROLLER)),
            new ProfileConfig(SapService.class, R.bool.profile_supported_sap,
                    (1 << BluetoothProfile.SAP)),
            new ProfileConfig(PbapClientService.class, R.bool.profile_supported_pbapclient,
                    (1 << BluetoothProfile.PBAP_CLIENT)),
            new ProfileConfig(MapClientService.class, R.bool.profile_supported_mapmce,
                    (1 << BluetoothProfile.MAP_CLIENT)),
            new ProfileConfig(HidDeviceService.class, R.bool.profile_supported_hid_device,
                    (1 << BluetoothProfile.HID_DEVICE)),
            new ProfileConfig(BluetoothOppService.class, R.bool.profile_supported_opp,
                    (1 << BluetoothProfile.OPP)),
            new ProfileConfig(BluetoothPbapService.class, R.bool.profile_supported_pbap,
                    (1 << BluetoothProfile.PBAP)),
            new ProfileConfig(HearingAidService.class,
                    com.android.internal.R.bool.config_hearing_aid_profile_supported,
                    (1 << BluetoothProfile.HEARING_AID))
    };

协议还真是不少啊!每一个服务启动后,都会通知到AdapterService,当所有的协议服务都启动完毕之后,也就意味着蓝牙真正的打开了。
第四阶段:(对应图中橙色虚线流程)
在所有ProfileService都启动完毕之后,AdapterService会判断到此条件,然后会给AdapterState状态机发送AdapterState.BREDR_STARTED,然后迁移到OnState状态:

 private void processProfileServiceStateChanged(ProfileService profile, int state) {
            switch (state) {
                case BluetoothAdapter.STATE_ON:
                		........
                    if (GattService.class.getSimpleName().equals(profile.getName())) {
                        enableNative();
                    } else if (mRegisteredProfiles.size() == Config.getSupportedProfiles().length
                            && mRegisteredProfiles.size() == mRunningProfiles.size()) {  //所有ProfileService都启动完毕
                       .......
                        mAdapterStateMachine.sendMessage(AdapterState.BREDR_STARTED);
                    }
                    break;
private class TurningOnState extends BaseAdapterState {
		..........
        @Override
        public boolean processMessage(Message msg) {
            switch (msg.what) {
                case BREDR_STARTED:
                    transitionTo(mOnState);
                    break;

前面已经说了,每次状态的迁移都会通过远程回调接口通知监听者,迁入到OnState也一样。BluetoothManagerService在收到STATE_ON的消息后,在经过Handler消息机制处理后,会走到如下的分支:

else if (newState == BluetoothAdapter.STATE_ON) {
            boolean isUp = (newState == BluetoothAdapter.STATE_ON);
            sendBluetoothStateCallback(isUp);
            sendBleStateChanged(prevState, newState);

显然,这里就是把蓝牙打开的状态通过远程回调接口,以及广播两种方式通知给上层应用。至此,从应用调用打开蓝牙的方法,到收到蓝牙打开的广播,整个蓝牙打开的流程就已经分析完毕!

  • 5
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值