美文网首页
Bluetooth initialization - enabl

Bluetooth initialization - enabl

作者: MelanDawn | 来源:发表于2022-05-02 20:15 被阅读0次

    1. Bluetooth Enable Overview

    1.1 Bluetooth Enable Entrance

    packages/apps/Bluetooth/src/com/android/bluetooth/btservice/AdapterService.java

        public static class AdapterServiceBinder extends IBluetooth.Stub {
            @Override
            public boolean enable(boolean quietMode) {
                AdapterService service = getService();
    ......
                return service.enable(quietMode);
            }
        }
    
    
    
        public synchronized boolean enable(boolean quietMode) {
    ......
            mQuietmode = quietMode;     // 由上层传递,测试设备的值 false
            mAdapterStateMachine.sendMessage(AdapterState.BLE_TURN_ON);
            return true;
        }
    

    1.2 Bluetooth StateMachine Overview

    packages/apps/Bluetooth/src/com/android/bluetooth/btservice/AdapterState.java
    根据源码注释可知,蓝牙开启的状态转换关系如下图:

    蓝牙启动的状态机转换图.png

    由上图可知,经历 Off、TurningBleOn、BleOn、TurningOn、On 共五个状态,蓝牙处于完全的开启状态。
    五个状态中,仅仅 TurningBleOn 和 TurningOn 是不稳定状态,无论操作成功与否都需要恢复到稳定状态 Off、BleOn、On 三种状态中的一种。

    下面开始分析蓝牙 enable 整体流程,分为 TurningBleOn 和 TurningOn 两个流程分析。
    首先整体介绍 enable 流程中状态机的转化,再分析 TurningBleOn,最后分析 TurningOn。

    packages/apps/Bluetooth/src/com/android/bluetooth/btservice/AdapterState.java

    final class AdapterState extends StateMachine {
    
        // 所有状态的基类
        private abstract class BaseAdapterState extends State {
    
            abstract int getStateValue();
    
            // 进入所有的具体状态时,需要更新状态信息。(若子类未重写)
            @Override
            public void enter() {
                int currState = getStateValue();
                mAdapterService.updateAdapterState(mPrevState, currState);     // 0
                mPrevState = currState;
            }
    ......
        }
    
    
        private class OffState extends BaseAdapterState {
            @Override
            public boolean processMessage(Message msg) {
                switch (msg.what) {
                    case BLE_TURN_ON:
                        transitionTo(mTurningBleOnState);        // 1
                        break;
                }
                return true;
            }
        }
    
    
    
        private class TurningBleOnState extends BaseAdapterState {
    
            @Override
            public void enter() {
                super.enter();
                sendMessageDelayed(BLE_START_TIMEOUT, BLE_START_TIMEOUT_DELAY);
                mAdapterService.bringUpBle();                  // 2
            }
    
            @Override
            public boolean processMessage(Message msg) {
                switch (msg.what) {
                    case BLE_STARTED:
                        transitionTo(mBleOnState);             // 3
                        break;
    ......
                }
                return true;
            }
        }
    
    
    
        private class BleOnState extends BaseAdapterState {
    
            @Override
            public boolean processMessage(Message msg) {
                switch (msg.what) {
                    case USER_TURN_ON:
                        transitionTo(mTurningOnState);        // 4
                        break;
    ......
                }
                return true;
            }
        }
    
    
    
        private class TurningOnState extends BaseAdapterState {
    
            @Override
            public void enter() {
                super.enter();
                sendMessageDelayed(BREDR_START_TIMEOUT, BREDR_START_TIMEOUT_DELAY);
                mAdapterService.startProfileServices();      // 5
            }
    
            @Override
            public boolean processMessage(Message msg) {
                switch (msg.what) {
                    case BREDR_STARTED:
                        transitionTo(mOnState);              // 6
                        break;
    ......
                }
                return true;
            }
        }
    
    
        private class OnState extends BaseAdapterState {
    
            @Override
            public boolean processMessage(Message msg) {
                switch (msg.what) {
                    case USER_TURN_OFF:
                        transitionTo(mTurningOffState);
                        break;
    
                }
                return true;
            }
        }
    }
    

    从以上 0~6 共计 7 个数字注释可知,除了状态转移,状态机主要执行三个方法:

    1. mAdapterService.updateAdapterState(mPrevState, currState); 【//0,通用方法】
    2. mAdapterService.bringUpBle(); 【//2, TurningBleOn】
    3. mAdapterService.startProfileServices(); 【// 5,TurningOn】

    状态机的状态流转过程中会先后执行 bringUpBle() 和 startProfileServices(),但此处还没有涉及到这些方法是如何被触发的,后续需要将这些内容连贯起来。

    updateAdapterState() 方法是状态机的通用方法。先分析其处理流程,再分析状态机的状态变化流程。

    2. Bluetooth StateMachine State Update - updateAdapterState()

    packages/apps/Bluetooth/src/com/android/bluetooth/btservice/AdapterService.java

        void updateAdapterState(int prevState, int newState) {
            mAdapterProperties.setState(newState);
            invalidateBluetoothGetStateCache();
            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();
            }
    
            // 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.get(BLUETOOTH_BTSNOOP_LOG_MODE_PROPERTY, "empty");
                mDefaultSnoopLogSettingAtEnable =
                        Settings.Global.getString(getContentResolver(),
                                Settings.Global.BLUETOOTH_BTSNOOP_DEFAULT_MODE);
                SystemProperties.set(BLUETOOTH_BTSNOOP_DEFAULT_MODE_PROPERTY,
                        mDefaultSnoopLogSettingAtEnable);
            } else if (newState == BluetoothAdapter.STATE_BLE_ON
                       && prevState != BluetoothAdapter.STATE_OFF) {
                String snoopLogSetting =
                        SystemProperties.get(BLUETOOTH_BTSNOOP_LOG_MODE_PROPERTY, "empty");
                String snoopDefaultModeSetting =
                        Settings.Global.getString(getContentResolver(),
                                Settings.Global.BLUETOOTH_BTSNOOP_DEFAULT_MODE);
    
                if (!TextUtils.equals(mSnoopLogSettingAtEnable, snoopLogSetting)
                        || !TextUtils.equals(mDefaultSnoopLogSettingAtEnable,
                                snoopDefaultModeSetting)) {
                    mAdapterStateMachine.sendMessage(AdapterState.BLE_TURN_OFF);
                }
            }
        }
    
    

    3. bringUpBle

    packages/apps/Bluetooth/src/com/android/bluetooth/btservice/AdapterService.java

        void bringUpBle() {
    
            if (getResources().getBoolean(
                    R.bool.config_bluetooth_reload_supported_profiles_when_enabled)) {
                Config.init(getApplicationContext());
            }
    
            mRemoteDevices.reset();
            mAdapterProperties.init(mRemoteDevices);
    
            mBondStateMachine = BondStateMachine.make(this, mAdapterProperties, mRemoteDevices);
    
            mJniCallbacks.init(mBondStateMachine, mRemoteDevices);
    
            try {
                mBatteryStats.noteResetBleScan();
            } catch (RemoteException e) {
                Log.w(TAG, "RemoteException trying to send a reset to BatteryStats");
            }
    
            // 5 Start Gatt service
            setProfileServiceState(GattService.class, BluetoothAdapter.STATE_ON);
        }
    

    3.1 RemoteDevices

    3.2 AdapterProperties

    3.3 BondStateMachine

    3.4 JniCallbacks

    3.5 GattService Initialization

    GattService 初始化详情:GattService Initialization
    根据 GattService 的基类初始化 ProfileService Initialization 的内容可知,Profile 启动之后,在AdapterService 中会记录状态以及可能会触发后续的 蓝牙enable 流程。

    packages/apps/Bluetooth/src/com/android/bluetooth/btservice/AdapterService.java

    public class AdapterService extends Service {
    
            private void processProfileServiceStateChanged(ProfileService profile, int state) {
                switch (state) {
                    case BluetoothAdapter.STATE_ON:
                        ......
                        if (GattService.class.getSimpleName().equals(profile.getName())) {
                            // 启动 GATT service 时,走该分支,继续执行 enable
                            enableNative();
                        } else if (mRegisteredProfiles.size() == Config.getSupportedProfiles().length
                                && mRegisteredProfiles.size() == mRunningProfiles.size()) {
                            // 所有支持的 profile service 启动后,走该分支
                            ......
                        }
                        break;
                        ......
                }
            }
        }
    }
    

    以上代码内容,不仅是 ProfileService 的通用流程,还是蓝牙enable的整体流程的内容。

    1. 若 GattService 启动完成,则执行 enableNative(),详情:Bluetooth initialization - enable in Bluetooth process - Native(Cpp)
    2. 若所有支持的 profile 启动完成,则执行另外一个分支,具体内容在下文介绍。

    4. startProfileServices

        void startProfileServices() {
            Class[] supportedProfileServices = Config.getSupportedProfiles();
            if (supportedProfileServices.length == 1 && GattService.class.getSimpleName()
                    .equals(supportedProfileServices[0].getSimpleName())) {
                 ...... // 设备只支持 BLE 时走这里,不分析此路径
            } else {
                setAllProfileServiceStates(supportedProfileServices, BluetoothAdapter.STATE_ON);
            }
        }
    
        private void setAllProfileServiceStates(Class[] services, int state) {
            for (Class service : services) {
                if (GattService.class.getSimpleName().equals(service.getSimpleName())) {
                    continue;  // GattService 已经初始化过了,排除之
                }
                setProfileServiceState(service, state);
            }
        }
    
    01-15 21:33:43.404 31081 31081 V AdapterServiceConfig: Adding HeadsetService
    01-15 21:33:43.404 31081 31081 V AdapterServiceConfig: Adding A2dpService
    01-15 21:33:43.404 31081 31081 V AdapterServiceConfig: Adding HidHostService
    01-15 21:33:43.404 31081 31081 V AdapterServiceConfig: Adding PanService
    01-15 21:33:43.404 31081 31081 V AdapterServiceConfig: Adding GattService
    01-15 21:33:43.404 31081 31081 V AdapterServiceConfig: Adding BluetoothMapService
    01-15 21:33:43.404 31081 31081 V AdapterServiceConfig: Adding AvrcpTargetService
    01-15 21:33:43.404 31081 31081 V AdapterServiceConfig: Adding SapService
    01-15 21:33:43.404 31081 31081 V AdapterServiceConfig: Adding HidDeviceService
    01-15 21:33:43.404 31081 31081 V AdapterServiceConfig: Adding BluetoothOppService
    01-15 21:33:43.404 31081 31081 V AdapterServiceConfig: Adding BluetoothPbapService
    01-15 21:33:43.404 31081 31081 V AdapterServiceConfig: Adding HearingAidService 
    

    Android 11 Pixel5 在蓝牙进程初始化时会添加以上这些Service,此处会分别初始化它们(除 GattService之外,GattService 在 bingUpBle 阶段初始化)。
    Profiles 的初始化过程如下:
    Profile Initialization - HeadsetService
    Profile Initialization - A2dpService
    Profile Initialization - HidHostService
    Profile Initialization - HidDeviceService
    Profile Initialization - PanService
    Profile Initialization - SapService
    Profile Initialization - AvrcpTargetService
    Profile Initialization - BluetoothMapService
    Profile Initialization - BluetoothPbapService
    Profile Initialization - BluetoothOppService
    Profile Initialization - HearingAidService

    当所有支持的 Profile 全部注册并启动之后,执行
    packages/apps/Bluetooth/src/com/android/bluetooth/btservice/AdapterService.java

    public class AdapterService extends Service {
    
            private void processProfileServiceStateChanged(ProfileService profile, int state) {
                switch (state) {
                    case BluetoothAdapter.STATE_ON:
                        ......
                        if (GattService.class.getSimpleName().equals(profile.getName())) {
                            // 启动 GATT service 时,走该分支,继续执行 enable
                            ......
                        } else if (mRegisteredProfiles.size() == Config.getSupportedProfiles().length
                                && mRegisteredProfiles.size() == mRunningProfiles.size()) {
                            // 所有支持的 profile service 启动后,走该分支
                            mAdapterProperties.onBluetoothReady();
                            updateUuids();
                            setBluetoothClassFromConfig();
                            initProfileServices();
                            getAdapterPropertyNative(AbstractionLayer.BT_PROPERTY_LOCAL_IO_CAPS);
                            getAdapterPropertyNative(AbstractionLayer.BT_PROPERTY_LOCAL_IO_CAPS_BLE);
                            mAdapterStateMachine.sendMessage(AdapterState.BREDR_STARTED);
                        }
                        break;
                        ......
                }
            }
        }
    }
    

    若所有支持的 profile 启动完成,则执行一些其他的初始化操作。
    随后向状态机发送 BREDR_STARTED 消息,状态机进入 OnState。

    5. Summary

    经过以上分析,蓝牙初始化整体架构如下图:


    Android Bluetooth Enable Arch

    相关文章

      网友评论

          本文标题:Bluetooth initialization - enabl

          本文链接:https://www.haomeiwen.com/subject/lhxqlrtx.html