一、状态图:

  

二、代码分析: \frameworks\opt\net\wifi\service\java\com\android\server\wifi\WifiStateMachine.java

  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来实现相同消息的反复发送。

最新文章

  1. C++之路进阶codevs1242(布局)
  2. Mongodb Manual阅读笔记:CH2 Mongodb CRUD 操作
  3. SQL探险
  4. Windows下安装node
  5. Java反射与动态代理
  6. android学习笔记22——Notification
  7. BASE64与单向加密算法MD5&SHA&MAC
  8. 英特尔Intel
  9. Android 给listview设置分割线与边界的距离
  10. iOS: performSelectorOnMainThread(译)
  11. 『重构--改善既有代码的设计』读书笔记----Introduce Foreign Method
  12. Spring(一)简述(转载)
  13. ASP.NET基础之HttpHandler学习
  14. winform控件跨线程委托
  15. Delphi json解析相关
  16. 关于 JavaScript 的 null 和 undefined,判断 null 的真实类型
  17. Workerman创建聊天室实例
  18. webpack优化记录
  19. js的各种正则表达式
  20. 20165310 Java实验五《网络编程与安全》

热门文章

  1. JavaScript函数封装调用
  2. rabbitMq实现延时队列
  3. Find The Multiple (DFS递归)
  4. 【数组模拟-小顶堆的插入构造/遍历】PAT-L2-012.-关于堆的判断--数组模拟
  5. webpack 配置react脚手架(四):路由配置
  6. 【noi2019集训题1】 脑部进食 期望dp+高斯消元
  7. 51nod 1488 帕斯卡小三角 斜率优化
  8. MongoDB 分片管理(四)数据均衡
  9. learning scala How To Create Variable Argument Function - varargs :_ *
  10. 从ServerSwitch到SONiC Chassis:数据中心交换机技术的十年探索历程