一、状态图:
二、代码分析:
1.创建WifiStateMachine的构造函数中添加各个状态:
/*调用stateMachine类的构造方法完成状态机的构造,名字为WifiStateMachine*/ super("WifiStateMachine"); /*添加状态*/ addState(mDefaultState); addState(mInitialState, mDefaultState); addState(mSupplicantStartingState, mDefaultState); addState(mSupplicantStartedState, mDefaultState); addState(mDriverStartingState, mSupplicantStartedState); addState(mDriverStartedState, mSupplicantStartedState); addState(mScanModeState, mDriverStartedState); addState(mConnectModeState, mDriverStartedState); addState(mL2ConnectedState, mConnectModeState); addState(mObtainingIpState, mL2ConnectedState); addState(mVerifyingLinkState, mL2ConnectedState); addState(mConnectedState, mL2ConnectedState); addState(mRoamingState, mL2ConnectedState); addState(mDisconnectingState, mConnectModeState); addState(mDisconnectedState, mConnectModeState); addState(mWpsRunningState, mConnectModeState); addState(mWaitForP2pDisableState, mSupplicantStartedState); addState(mDriverStoppingState, mSupplicantStartedState); addState(mDriverStoppedState, mSupplicantStartedState); addState(mSupplicantStoppingState, mDefaultState); addState(mSoftApStartingState, mDefaultState); addState(mSoftApStartedState, mDefaultState); addState(mTetheringState, mSoftApStartedState); addState(mTetheredState, mSoftApStartedState); addState(mUntetheringState, mSoftApStartedState); /*设置初始状态*/ setInitialState(mInitialState); /*设置状态日志记录*/ setLogRecSize(2000); setLogOnlyTransitions(false); /*开始状态机*/ start();
2.状态切换-开启AP (access point:热点)
(1)TetheredState监听中收到CMD_TETHER_STATE_CHANGE消息后调用setHostApRunning() 开启AP功能,此方法发送CMD_START_AP消息:
public void setHostApRunning(WifiConfiguration wifiConfig, boolean enable) { if (enable) { sendMessage(CMD_START_AP, wifiConfig); } else { sendMessage(CMD_STOP_AP); } }
(2)状态机启动后处于InitialState状态,processMessage()中处理CMD_START_AP消息:
case CMD_START_AP: if (enableSoftAp() == true) {
/*设置AP状态*/ setWifiApState(WIFI_AP_STATE_ENABLING, 0);
/*状态切换mSoftApStartingState*/ transitionTo(mSoftApStartingState); } else { setWifiApState(WIFI_AP_STATE_FAILED, WifiManager.SAP_START_FAILURE_GENERAL); transitionTo(mInitialState); } break;
(3)CMD_START_AP消息处理完后,跳转到mSoftApStartingState进入mSoftApStartingState的enter方法:
class SoftApStartingState extends State { @Override public void enter() { final Message message = getCurrentMessage(); if (message.what == CMD_START_AP) { final WifiConfiguration config = (WifiConfiguration) message.obj; if (config == null) { mWifiApConfigChannel.sendMessage(CMD_REQUEST_AP_CONFIG); } else { mWifiApConfigChannel.sendMessage(CMD_SET_AP_CONFIG, config); /*开启AP*/ startSoftApWithConfig(config); } } else { throw new RuntimeException("Illegal transition to SoftApStartingState: " + message); } } ...... }
(4)startSoftApWithConfig开启AP成功后,会发送CMD_START_AP_SUCCESS:
// Start hostapd on a separate thread new Thread(new Runnable() { public void run() { try { mNwService.startAccessPoint(config, mInterfaceName); } catch (Exception e) { loge("Exception in softap start " + e); try {
// 重置热点 mNwService.stopAccessPoint(mInterfaceName); mNwService.startAccessPoint(config, mInterfaceName); } catch (Exception e1) { loge("Exception in softap re-start " + e1); sendMessage(CMD_START_AP_FAILURE, WifiManager.SAP_START_FAILURE_GENERAL); return; } } if (DBG) log("Soft AP start successful");
// 发送消息 sendMessage(CMD_START_AP_SUCCESS); } }).start(); }
SoftApStartingState中处理CMD_START_AP_SUCCESS消息:
public boolean processMessage(Message message) { switch(message.what) { case CMD_START_AP_SUCCESS: /*设置AP状态*/ setWifiApState(WIFI_AP_STATE_ENABLED); /*跳转到mSoftApStartedState*/ transitionTo(mSoftApStartedState); break; case CMD_START_AP_FAILURE: setWifiApState(WIFI_AP_STATE_FAILED, message.arg1); transitionTo(mInitialState); break;
default: return NOT_HANDLED; } }
(5)CMD_START_AP_SUCCESS消息处理完后,跳转到mSoftApStartedState状态,执行该状态的enter方法。
此状态下收到CMD_TETHER_STATE_CHANGE消息后做进一步处理:
public boolean processMessage(Message message) { switch(message.what) { // case CMD_TETHER_STATE_CHANGE: TetherStateChange stateChange = (TetherStateChange) message.obj; /*开启tethering*/ if (startTethering(stateChange.available)) { transitionTo(mTetheringState); } break; } }
(6)开启startTethering成功后,跳转到mTetheringState状态,执行其enter方法:
public void enter() { /*发送延时消息,超时时间5s*/ sendMessageDelayed(obtainMessage(CMD_TETHER_NOTIFICATION_TIMED_OUT, ++mTetherToken, 0), TETHER_NOTIFICATION_TIME_OUT_MSECS); }
mTetheringState状态下,收到CMD_TETHER_NOTIFICATION_TIMED_OUT超时消息,则启动tether失败,一步步切回到init状态。
switch(message.what) { case CMD_TETHER_STATE_CHANGE: TetherStateChange stateChange = (TetherStateChange) message.obj; if (isWifiTethered(stateChange.active)) { transitionTo(mTetheredState); } return HANDLED; case CMD_TETHER_NOTIFICATION_TIMED_OUT: if (message.arg1 == mTetherToken) { loge("Failed to get tether update, shutdown soft access point"); transitionTo(mSoftApStartedState); // Needs to be first thing handled sendMessageAtFrontOfQueue(CMD_STOP_AP); } break; ...... }
如果在超时消息之前收到CMD_TETHER_STATE_CHANGE消息,则跳转到 TetheredState 中:
class TetheredState extends State { @Override public boolean processMessage(Message message) { logStateAndMessage(message, getClass().getSimpleName()); switch(message.what) { case CMD_TETHER_STATE_CHANGE: TetherStateChange stateChange = (TetherStateChange) message.obj; if (!isWifiTethered(stateChange.active)) { loge("Tethering reports wifi as untethered!, shut down soft Ap");
// 开启热点 setHostApRunning(null, false); setHostApRunning(null, true); } return HANDLED; ...... } }
其中setHostApRunning方法中发送CMD_START_AP消息:
public void setHostApRunning(WifiConfiguration wifiConfig, boolean enable) { if (enable) { sendMessage(CMD_START_AP, wifiConfig); } else { sendMessage(CMD_STOP_AP); } }
上面发送的CMD_START_AP消息会传到DefaultState中处理。
至此整个状态机的状态历经如下切换,稳定在mThertheredState:
mInitialState->mSoftApStartingState->mSoftApStartedState->mThetheringState->mThertheredState
若在mThertheredState状态下关闭AP,则按照如下流程切换:
mThertheredState->mUntetheringState->mSoftApStartedState->mInitialState
这个流程中用到了deferMessage来实现相同消息的反复发送。