Android 蓝牙启动状态机

Bluetooth状态转换图如下:

                               (BluetootOn)<----------------------<-
 40  *                           |    ^    -------------------->-  |
 41  *                           |    |                         |  |
 42  *                 TURN_OFF  |    | SCAN_MODE_CHANGED    m1 |  | USER_TURN_ON
 43  *         AIRPLANE_MODE_ON  |    |                         |  |
 44  *                           V    |                         |  |
 45  *                         (Switching)                   (PerProcessState)
 46  *                           |    ^                         |  |
 47  *     POWER_STATE_CHANGED & |    | TURN_ON(_CONTINUE)      |  |
 48  * ALL_DEVICES_DISCONNECTED  |    |                     m2  |  |
 49  *                           V    |------------------------<   | SCAN_MODE_CHANGED
 50  *                          (HotOff)-------------------------->- PER_PROCESS_TURN_ON
 51  *                           /    ^
 52  *                          /     |  SERVICE_RECORD_LOADED
 53  *                         |      |
 54  *              TURN_COLD  |   (Warmup)
 55  *                               ^
 56  *                               |  TURN_HOT/TURN_ON
 57  *                           |    |  AIRPLANE_MODE_OFF(when Bluetooth was on before)
 58  *                           V    |
 59  *                           (PowerOff)   <----- initial state

涉及到的文件:

./frameworks/base/core/java/android/server/BluetoothAdapterStateMachine.java
./frameworks/base/core/java/com/android/internal/util/StateMachine.java

BluetoothAdapterStateMachine继承了StateMachine


先看状态机如何被启动的:

基本流程就是这样.


1.BluetoothAdapterStateMachine的初始化动作:


 mBluetoothOn = new BluetoothOn();
        mSwitching = new Switching();
        mHotOff = new HotOff();
        mWarmUp = new WarmUp();
        mPowerOff = new PowerOff();
        mPerProcessState = new PerProcessState();

        addState(mBluetoothOn);
        addState(mSwitching);
        addState(mHotOff);
        addState(mWarmUp);
        addState(mPowerOff);
        addState(mPerProcessState);

        setInitialState(mPowerOff);
        mPublicState = BluetoothAdapter.STATE_OFF;

在BluetoothAdapterStateMachine的构造函数中添加了,Switching、HotOff()、WarnUp、PowerOff、PerProcessState等几种状态。

并设置了初始状态为PowerOff。有一个mPublicState的变量,这个变量保存状态机最终向外公布的状态。

由上面可以看出,添加的这几个状态都是独立的,没有父状态, 所以转换相对就比较简单了。


2.状态机的转换。

首先进入了PowerOff的状态, 有用户打打开蓝牙,或设置了了开机启动蓝牙,就会收到USER_TURN_ON的消息。这里以开机启动蓝牙为例, 阐释消息如何传递的。

SystemServer:bluetooth.enable();------>BluetoothService:enable()------>mBluetoothState.sendMessage(BluetoothAdapterStateMachine.USER_TURN_ON, saveSetting);------>

StateMachine:sendMessage()------>mSmHandler.sendMessage(obtainMessage(what,obj));(SmHandler为StateMachine的内部类)--------->SmHandler:handleMessage-------->

SmHandler:processMsg()------->BluetoothAdapterStateMachine:PowerOff:processMessage()。(一)


在PowerOff:processMessage中处理USER_TURN_ON这个消息,做了一些蓝牙启动的准备的动作(调用prepareBluetooth()) ,并且transitionTo(mWarmUp);并且设置了目标状态为WarmUp,这个函数最终是给

SmHandler:mDestState赋值 赋值后SmHandler:mDestState = (mWarmUp)。并且deferMessage(obtainMessage(TURN_ON_CONTINUE));(这个函数会将消息放入SmHandle:mDeferredMessages

中,当实现状态切换的时候会全部派发出去。mDeferredMessages是一个ArrayList)。


接(一)。------->SmHandler:performTransitions----->BluetoothAdapterStateMachine:PowerOff:exit(),BluetoothAdapterStateMachine:WarmUp:enter()(进入了WarmUp了),moveDeferredMessageAtFrontOfQueue();(这个函数

会将mDeferredMessages中存放的消息全部发送出去并清空,比如在现在的流程这里有个TURN_ON_CONTINUE)。----->和上面USER_TURN_ON的消息传递流程一样------>BluetoothAdapterStateMachine:WarmUp:processMessage()(处理TURN_ON_CONTINUE)------>WarmUp:deferMessage(message)(该message为TURN_ON_CONTINUE);(这里是为了等待prepareBluetooth()
这个函数完成,当prepareBluetooth()函数完成后将会发送一个SERVICE_RECORD_LOADED的消息)------>SmHandler:performTransitions()------------->BluetoothAdapterStateMachine:Warmup:exit(),

BluetoothAdapterStateMachine:HotOff:enter()(进入了HotOff了),moveDeferredMessageAtFrontOfQueue();(将会发送TURN_ON_CONTINUE消息)------------>

BluetoothAdapterStateMachine:HotOff:processMessage()-------->mBluetoothService.switchConnectable(true);(这个函数里面发送了一个BluetoothAdapterStateMachine.SCAN_MODE_CHANGED的消息),transitionTo(mSwitching);(设置了目标状态SmHandler:mDestState的值为Switching)-------->SmHandler:performTransitions()---------->

BluetoothAdapterStateMachine:WarmUp:exit(),BluetoothAdapterStateMachine:HotOff:enter()(进入了HotOff了),moveDeferredMessageAtFrontOfQueue();---------->和上面USER_TURN_ON的消息传递流程一样------------->

BluetoothAdapterStateMachine:Switching:processMessage()(处理SCAN_MODE_CHANGED)-------->做一些蓝牙的启动工作后,transitionTo(mBluetoothOn);(目标状态为BluetoothOn)------->SmHandler:performTransitions()---->

BluetoothAdapterStateMachine:Switching:exit(),BluetoothAdapterStateMachine:BluetoothOn:enter()(进入了BluetoothOn状态了),moveDeferredMessageAtFrontOfQueue();。


蓝牙的整个启动过程状态机就是这样,由于不涉及到父状态,所以整个过程还是比较简单的,其他过程可以类比。对于这边文章大家可以参考我的前一篇 Android中的状态机。









你可能感兴趣的:(Android 蓝牙启动状态机)