一、WifiStateMachine类分析
frameworks/base/wifi/java/android/net/wifi/WifiStateMachine.java
public class WifiStateMachine extends StateMachine {
public WifiStateMachine(Context context, String wlanInterface) {
//添加状态到状态机
addState(mDefaultState);
addState(mInitialState, mDefaultState);
//设置初始状态
setInitialState(mInitialState);
}
public void setWifiApEnabled(WifiConfiguration wifiConfig, boolean enable) {
if (enable) {
sendMessage(obtainMessage(CMD_LOAD_DRIVER, WIFI_AP_STATE_ENABLING, 0));
sendMessage(obtainMessage(CMD_START_AP, wifiConfig));
} else {
sendMessage(CMD_STOP_AP);
sendMessage(obtainMessage(CMD_UNLOAD_DRIVER, WIFI_AP_STATE_DISABLED, 0));
}
}
}
frameworks/base/core/java/com/android/internal/util/StateMachine.java
public class StateMachine {
//设置状态机的下一个状态
protected final void transitionTo(IState destState) {
mSmHandler.transitionTo(destState);
}
//增加状态到状态队列
protected final void addState(State state, State parent) {
mSmHandler.addState(state, parent);
}
//设置初始状态
private final void setInitialState(State initialState) {
if (mDbg) Log.d(TAG, "setInitialState: initialState=" + initialState.getName());
mInitialState = initialState;
}
//获取状态机当前状态
protected final IState getCurrentState() {
return mSmHandler.getCurrentState();
}
//向状态机发送消息
public final void sendMessage(Message msg) {
// mSmHandler can be null if the state machine has quit.
if (mSmHandler == null) return;
mSmHandler.sendMessage(msg);
}
///
private static class SmHandler extends Handler {
//设置状态机的下一个状态
private final void transitionTo(IState destState) {
mDestState = (State) destState;
if (mDbg) Log.d(TAG, "transitionTo: destState=" + mDestState.getName());
}
//增加状态到状态队列
private final StateInfo addState(State state, State parent) {
if (mDbg) {
Log.d(TAG, "addStateInternal: E state=" + state.getName()
+ ",parent=" + ((parent == null) ? "" : parent.getName()));
}
StateInfo parentStateInfo = null;
if (parent != null) {
parentStateInfo = mStateInfo.get(parent);
if (parentStateInfo == null) {
parentStateInfo = addState(parent, null);
}
}
StateInfo stateInfo = mStateInfo.get(state);
if (stateInfo == null) {
stateInfo = new StateInfo();
mStateInfo.put(state, stateInfo);
}
if ((stateInfo.parentStateInfo != null) && (stateInfo.parentStateInfo != parentStateInfo)) {
throw new RuntimeException("state already added");
}
stateInfo.state = state;
stateInfo.parentStateInfo = parentStateInfo;
stateInfo.active = false;
if (mDbg) Log.d(TAG, "addStateInternal: X stateInfo: " + stateInfo);
return stateInfo;
}
//获取状态机当前状态
private final IState getCurrentState() {
return mStateStack[mStateStackTopIndex].state;
}
//状态机处理消息
@Override
public final void handleMessage(Message msg) {
if (mDbg) Log.d(TAG, "handleMessage: E msg.what=" + msg.what);
mMsg = msg;
if (mIsConstructionCompleted) {
processMsg(msg);//事件处理
}
else if (!mIsConstructionCompleted &&
(mMsg.what == SM_INIT_CMD) && (mMsg.obj == mSmHandlerObj)) {
mIsConstructionCompleted = true;
invokeEnterMethods(0);
}
else {
throw new RuntimeException("StateMachine.handleMessage: " +
"The start method not called, received msg: " + msg);
}
performTransitions();//状态机切换
if (mDbg) Log.d(TAG, "handleMessage: X");
}
//状态机处理消息
private final void processMsg(Message msg) {//事件处理
StateInfo curStateInfo = mStateStack[mStateStackTopIndex];
if (mDbg) {
Log.d(TAG, "processMsg: " + curStateInfo.state.getName());
}
if (isQuit(msg)) {
transitionTo(mQuittingState);
}
else {
//状态处理,调用下面“二”中各个状态的processMessage
//当返回值为NOT_HANDLED时继续下一个,直到返回值为HANDLED
while (!curStateInfo.state.processMessage(msg)) {
curStateInfo = curStateInfo.parentStateInfo;
if (curStateInfo == null) {
mSm.unhandledMessage(msg);
break;
}
if (mDbg) {
Log.d(TAG, "processMsg: " + curStateInfo.state.getName());
}
}
if (mSm.recordLogRec(msg)) {
if (curStateInfo != null) {
State orgState = mStateStack[mStateStackTopIndex].state;
mLogRecords.add(msg, mSm.getLogRecString(msg), curStateInfo.state,
orgState);
} else {
mLogRecords.add(msg, mSm.getLogRecString(msg), null, null);
}
}
}
}
//状态机切换
private void performTransitions() {//状态机切换
State destState = null;
while (mDestState != null) {
if (mDbg) Log.d(TAG, "handleMessage: new destination call exit");
destState = mDestState;
mDestState = null;
//将transitionTo设置的状态mDestState作为下一个状态放到mStateStack中
//把当前活动state家族放入mTempStateStack中, 并且返回顶层节点的信息
StateInfo commonStateInfo = setupTempStateStackWithStatesToEnter(destState);
//从当前活动state顶层节点一次调用exit方法,并且设置state的active标记为false;
invokeExitMethods(commonStateInfo);
//将mTempStateStack的值倒序放到mStateStack中
int stateStackEnteringIndex = moveTempStateStackToStateStack();
//依次调用活动状态的enter方法,把当前state的active置为true
invokeEnterMethods(stateStackEnteringIndex);
//刷新消息队列的排序。该方法就是将 mDeferredMessages容器中的消息按先后顺序发送出去,然后清空容器。这些消息是发送给比如wifip2pservice等其他服务的
moveDeferredMessageAtFrontOfQueue();
}
if (destState != null) {
if (destState == mQuittingState) {
mSm.onQuitting();
cleanupAfterQuitting();
}
else if (destState == mHaltingState) {
mSm.onHalting();
}
}
}
}
public static class LogRec {
}
private static class LogRecords {
}
private class StateInfo {
}
private class HaltingState extends State {
}
private class QuittingState extends State {
}
}
二、相关状态分析
WifiStateMachine下有如下状态:
DefaultState、InitialState,
DriverUnloadingState、DriverUnloadedState、DriverFailedState、DriverLoadingState、DriverLoadedState,
SupplicantStartingState、SupplicantStartedState、SupplicantStoppingState,
DriverStartingState、DriverStartedState、DriverStoppingState、DriverStoppedState,
WaitForP2pDisableState、SoftApStartingState、SoftApStartedState、SoftApStoppingState、TetheringState、TetheredState,
ScanModeState、ConnectModeState、L2ConnectedState、ObtainingIpState、VerifyingLinkState、CaptivePortalCheckState、ConnectedState、DisconnectingState、DisconnectedState、WpsRunningState。
下面就其中InitialState类继承关系分析,其他相同、不再分析。
frameworks/base/wifi/java/android/net/wifi/WifiStateMachine.java
class InitialState extends State {
public void enter() {
if (DBG) log(getName() + "\n");
EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
if (mWifiNative.isDriverLoaded()) {
transitionTo(mDriverLoadedState);
}
else {
transitionTo(mDriverUnloadedState);
}
mWifiP2pManager = (WifiP2pManager) mContext.getSystemService(Context.WIFI_P2P_SERVICE);
mWifiP2pChannel.connect(mContext, getHandler(), mWifiP2pManager.getMessenger());
try {
mNwService.disableIpv6(mInterfaceName);
} catch (RemoteException re) {
loge("Failed to disable IPv6: " + re);
} catch (IllegalStateException e) {
loge("Failed to disable IPv6: " + e);
}
}
}
frameworks/base/core/java/com/android/internal/util/State.java
public class State implements IState {
protected State() {
}
@Override
public void enter() {
}
@Override
public void exit() {
}
@Override
public boolean processMessage(Message msg) {
return false;
}
@Override
public String getName() {
String name = getClass().getName();
int lastDollar = name.lastIndexOf('$');
return name.substring(lastDollar + 1);
}
}