最近在处理一些wifi问题,所以梳理wifi的启动流程有助于快速定位wifi问题的根源。此篇是根据Android 10的源码来分析的,Android 11及以上略微有点不同,但大差不差。
wifi打开方式有两种,一是从Settings里面打开,二是从通知栏的快捷方式快速开启,两者的入口分别位于
- packages\apps\Settings\src\com\android\settings\wifi\WifiEnabler.java
@Override
public boolean onSwitchToggled(boolean isChecked) {
//Do nothing if called as a result of a state machine event
if (mStateMachineEvent) {
return true;
}
// Show toast message if Wi-Fi is not allowed in airplane mode
if (isChecked && !WirelessUtils.isRadioAllowed(mContext, Settings.Global.RADIO_WIFI)) {
Toast.makeText(mContext, R.string.wifi_in_airplane_mode, Toast.LENGTH_SHORT).show();
// Reset switch to off. No infinite check/listener loop.
mSwitchWidget.setChecked(false);
return false;
}
if (isChecked) {
mMetricsFeatureProvider.action(mContext, SettingsEnums.ACTION_WIFI_ON);
} else {
// Log if user was connected at the time of switching off.
mMetricsFeatureProvider.action(mContext, SettingsEnums.ACTION_WIFI_OFF,
mConnected.get());
}
//通过WifiManager.setWifiEnabled()开启/关闭wifi
if (!mWifiManager.setWifiEnabled(isChecked)) {
// Error
mSwitchWidget.setEnabled(true);
Toast.makeText(mContext, R.string.wifi_error, Toast.LENGTH_SHORT).show();
}
return true;
}
- frameworks\base\packages\SystemUI\src\com\android\systemui\qs\tiles\WifiTile.java
@Override
protected void handleClick() {
// Secondary clicks are header clicks, just toggle.
mState.copyTo(mStateBeforeClick);
boolean wifiEnabled = mState.value;
// Immediately enter transient state when turning on wifi.
refreshState(wifiEnabled ? null : ARG_SHOW_TRANSIENT_ENABLING);
//通过NetworkController.setWifiEnabled()开启wifi
mController.setWifiEnabled(!wifiEnabled);
mExpectDisabled = wifiEnabled;
if (mExpectDisabled) {
mHandler.postDelayed(() -> {
if (mExpectDisabled) {
mExpectDisabled = false;
refreshState();
}
}, QSIconViewImpl.QS_ANIM_LENGTH);
}
}
NetworkController是一个接口,其实现类为NetworkControllerImpl,查看该类setWifiEnabled()的实现方式
@Override
public void setWifiEnabled(final boolean enabled) {
new AsyncTask<Void, Void, Void>() {
@Override
protected Void doInBackground(Void... args) {
//最终也是通过WifiManager.setWifiEnabled()控制wifi的开启
mWifiManager.setWifiEnabled(enabled);
return null;
}
}.execute();
}
查看WifiManager.setWifiEnabled()的代码
@Deprecated
public boolean setWifiEnabled(boolean enabled) {
try {
return mService.setWifiEnabled(mContext.getOpPackageName(), enabled);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
这里的mService是WifiServiceImpl的代理对象IWifiManager,通过aidl方式调用了WifiServiceImpl的setWifiEnabled()方法,而WifiServiceImpl在WifiService启动时被创建,WifiService是一个SystemService,在系统启动的时候被启动
public final class WifiService extends SystemService {
private static final String TAG = "WifiService";
final WifiServiceImpl mImpl;
public WifiService(Context context) {
super(context);
//创建WifiServiceImpl对象,wifi相关的处理都有此对象来完成
mImpl = new WifiServiceImpl(context, new WifiInjector(context), new WifiAsyncChannel(TAG));
}
@Override
public void onStart() {
Log.i(TAG, "Registering " + Context.WIFI_SERVICE);
publishBinderService(Context.WIFI_SERVICE, mImpl);
}
@Override
public void onBootPhase(int phase) {
if (phase == SystemService.PHASE_SYSTEM_SERVICES_READY) {
mImpl.checkAndStartWifi();
} else if (phase == SystemService.PHASE_BOOT_COMPLETED) {
mImpl.handleBootCompleted();
}
}
@Override
public void onSwitchUser(int userId) {
mImpl.handleUserSwitch(userId);
}
@Override
public void onUnlockUser(int userId) {
mImpl.handleUserUnlock(userId);
}
@Override
public void onStopUser(int userId) {
mImpl.handleUserStop(userId);
}
}
关于Android系统启动流程,后续会单独用一篇文章去分析,这里只需要知道WifiServiceImpl是什么时候被创建的,查看WifiServiceImpl.setWifiEnabled()
@Override
public synchronized boolean setWifiEnabled(String packageName, boolean enable) {
return setWifiEnabled2(packageName, STA_PRIMARY, enable);
}
@Override
public synchronized boolean setWifiEnabled2(String packageName, int staId, boolean enable) {
if (enforceChangePermission(packageName) != MODE_ALLOWED) {
return false;
}
boolean isPrivileged = isPrivileged(Binder.getCallingPid(), Binder.getCallingUid());
if (!isPrivileged && !isDeviceOrProfileOwner(Binder.getCallingUid())
&& !mWifiPermissionsUtil.isTargetSdkLessThan(packageName, Build.VERSION_CODES.Q,
Binder.getCallingUid())
&& !isSystem(packageName, Binder.getCallingUid())) {
mLog.info("setWifiEnabled not allowed for uid=%")
.c(Binder.getCallingUid()).flush();
return false;
}
// If Airplane mode is enabled, only privileged apps are allowed to toggle Wifi
if (mSettingsStore.isAirplaneModeOn() && !isPrivileged) {
mLog.err("setWifiEnabled in Airplane mode: only Settings can toggle wifi").flush();
return false;
}
// If SoftAp is enabled, only privileged apps are allowed to toggle wifi
boolean apEnabled = mWifiApState == WifiManager.WIFI_AP_STATE_ENABLED;
if (apEnabled && !isPrivileged) {
mLog.err("setWifiEnabled SoftAp enabled: only Settings can toggle wifi").flush();
return false;
}
// If we're in crypt debounce, ignore any wifi state change APIs.
if (mFrameworkFacade.inStorageManagerCryptKeeperBounce()) {
return false;
}
mLog.info("setWifiEnabled package=% uid=% enable=%").c(packageName)
.c(Binder.getCallingUid()).c(enable).flush();
long ident = Binder.clearCallingIdentity();
try {
if (staId == STA_PRIMARY && !mSettingsStore.handleWifiToggled(enable)) {
// Nothing to do if wifi cannot be toggled
return true;
}
} finally {
Binder.restoreCallingIdentity(ident);
}
if (!mIsControllerStarted) {
Slog.e(TAG,"WifiController is not yet started, abort setWifiEnabled");
return false;
}
mWifiMetrics.incrementNumWifiToggles(isPrivileged, enable);
if (staId == STA_PRIMARY) {
//这里通过Handler发送了一个消息,通知系统wifi状态发生了改变
mWifiController.sendMessage(CMD_WIFI_TOGGLED);
} else if ((getNumConcurrentStaSupported() > 1)
&& (getWifiEnabledState() == WifiManager.WIFI_STATE_ENABLED)
&& staId > STA_PRIMARY) {
mWifiController.sendMessage(CMD_ADD_WIFI_SET, staId, enable ? 1 : 0);
} else {
Slog.e(TAG,"setWifiEnabled not allowed for id:"+staId);
return false;
}
return true;
}
mWififContoller中定义了一个SmHandler,通过SmHandler发送了一个wifi状态改变的消息,然后在其handleMessage()方法中处理消息
@Override
public final void handleMessage(Message msg) {
if (!mHasQuit) {
if (mSm != null && msg.what != SM_INIT_CMD && msg.what != SM_QUIT_CMD) {
mSm.onPreHandleMessage(msg);
}
if (mDbg) mSm.log("handleMessage: E msg.what=" + msg.what);
/** Save the current message */
mMsg = msg;
/** State that processed the message */
State msgProcessedState = null;
if (mIsConstructionCompleted || (mMsg.what == SM_QUIT_CMD)) {
/** Normal path */
//执行processMsg方法处理消息
msgProcessedState = processMsg(msg);
} else if (!mIsConstructionCompleted && (mMsg.what == SM_INIT_CMD)
&& (mMsg.obj == mSmHandlerObj)) {
/** Initial one time path. */
mIsConstructionCompleted = true;
invokeEnterMethods(0);
} else {
throw new RuntimeException("StateMachine.handleMessage: "
+ "The start method not called, received msg: " + msg);
}
//执行transitions方法,该方法是为了执行下一状态的enter()方法
performTransitions(msgProcessedState, msg);
// We need to check if mSm == null here as we could be quitting.
if (mDbg && mSm != null) mSm.log("handleMessage: X");
if (mSm != null && msg.what != SM_INIT_CMD && msg.what != SM_QUIT_CMD) {
mSm.onPostHandleMessage(msg);
}
}
}
private final State processMsg(Message msg) {
//获取当前状态机
StateInfo curStateInfo = mStateStack[mStateStackTopIndex];
if (mDbg) {
mSm.log("processMsg: " + curStateInfo.state.getName());
}
if (isQuit(msg)) {
transitionTo(mQuittingState);
} else {
//执行状态机的processMessage()方法
while (!curStateInfo.state.processMessage(msg)) {
/**
* Not processed
*/
curStateInfo = curStateInfo.parentStateInfo;
if (curStateInfo == null) {
/**
* No parents left so it's not handled
*/
mSm.unhandledMessage(msg);
break;
}
if (mDbg) {
mSm.log("processMsg: " + curStateInfo.state.getName());
}
}
}
return (curStateInfo != null) ? curStateInfo.state : null;
}
首先获取当前wifi状态,wifi状态是通过StateMachine状态机来管理的,状态机划分如下
- ModeStateMachine:非客户端模式下的状态机
- StaDisabledState:wifi不可用状态
- StaEnabledState:wifi可用状态
- …
- ClientModeStateMachine:客户端模式下的状态机
- WifiDisabledState:wifi不可用状态
- ClientModeActiveState:wifi激活状态
- IdleState:空闲状态
- StartedState:已启动状态
- ScanOnlyModeActiveState:扫描状态
获取到State之后执行对应的processMessage()方法,这里研究开启流程,默认从ModeStateMachine到ClientModeStateMachine的顺序执行,所以先执行的是StaDisabledState的processMessage()方法
@Override
public boolean processMessage(Message msg) {
switch (msg.what) {
case CMD_WIFI_TOGGLED:
if (mSettingsStore.isWifiToggleEnabled()) {
if (doDeferEnable(msg)) {
if (mHaveDeferredEnable) {
// have 2 toggles now, inc serial number and ignore both
mDeferredEnableSerialNumber++;
}
mHaveDeferredEnable = !mHaveDeferredEnable;
break;
}
//将状态切换到StaEnabledState,执行该状态的enter()方法
transitionTo(mStaEnabledState);
} else if (checkScanOnlyModeAvailable()) {
// only go to scan mode if we aren't in airplane mode
if (mSettingsStore.isAirplaneModeOn()) {
transitionTo(mStaDisabledWithScanState);
}
}
break;
case CMD_SCAN_ALWAYS_MODE_CHANGED:
if (checkScanOnlyModeAvailable()) {
transitionTo(mStaDisabledWithScanState);
break;
}
break;
case CMD_SET_AP:
if (msg.arg1 == 1) {
// remember that we were disabled, but pass the command up to start softap
mSettingsStore.setWifiSavedState(WifiSettingsStore.WIFI_DISABLED);
}
return NOT_HANDLED;
case CMD_DEFERRED_TOGGLE:
if (msg.arg1 != mDeferredEnableSerialNumber) {
log("DEFERRED_TOGGLE ignored due to serial mismatch");
break;
}
log("DEFERRED_TOGGLE handled");
sendMessage((Message)(msg.obj));
break;
case CMD_DEFERRED_RECOVERY_RESTART_WIFI:
// wait mRecoveryDelayMillis for letting driver clean reset.
sendMessageDelayed(CMD_RECOVERY_RESTART_WIFI_CONTINUE, mRecoveryDelayMillis);
break;
case CMD_RECOVERY_RESTART_WIFI_CONTINUE:
if (mSettingsStore.isWifiToggleEnabled()) {
// wifi is currently disabled but the toggle is on, must have had an
// interface down before the recovery triggered
transitionTo(mStaEnabledState);
break;
} else if (checkScanOnlyModeAvailable()) {
transitionTo(mStaDisabledWithScanState);
break;
}
break;
default:
return NOT_HANDLED;
}
return HANDLED;
}
StaDisabledState在处理CMD_WIFI_TOGGLED消息时,直接通过transitionTo()将状态切换至StaEnabledState,在SmHandler的handleMessage()中,执行完msgProcessedState = processMsg(msg)后会执行performTransitions(msgProcessedState, msg),此方法里面执行了invokeEnterMethods(stateStackEnteringIndex),该方法就是调用State的enter()方法,也就是说状态切换后会立即执行当前状态的enter()方法,查看StaEnabledState的enter()方法
@Override
public void enter() {
log("StaEnabledState.enter()");
mActiveModeWarden.enterClientMode();
}
执行了ActiveModeWarden.enterClientMode(),进入客户端模式,查看该方法
public void enterClientMode() {
changeMode(ModeStateMachine.CMD_START_CLIENT_MODE);
}
private void changeMode(int newMode) {
mModeStateMachine.sendMessage(newMode);
}
这里通过mModeStateMachine里面的SmHandler对象发送了CMD_START_CLIENT_MODE消息,对应的由客户端模式下的WifiDisabledState来处理此消息,因为ModeStateMachine创建时设置WifiDisabledState为初始化的状态,如下:
ModeStateMachine() {
super(TAG, mLooper);
addState(mClientModeActiveState);
addState(mScanOnlyModeActiveState);
addState(mWifiDisabledState);
Log.d(TAG, "Starting Wifi in WifiDisabledState");
//设置WifiDisabledState为初始化状态
setInitialState(mWifiDisabledState);
start();
}
查看WifiDisabledState,注意WifiDisabledState是ModeStateMachine的内部类,而ModeStateMachine又是ActiveModeWarden的内部类
class WifiDisabledState extends ModeActiveState {
@Override
public void enter() {
Log.d(TAG, "Entering WifiDisabledState");
}
@Override
public boolean processMessage(Message message) {
Log.d(TAG, "received a message in WifiDisabledState: " + message);
//处理CMD_START_CLIENT_MODE消息
if (checkForAndHandleModeChange(message)) {
return HANDLED;
}
return NOT_HANDLED;
}
@Override
public void exit() {
// do not have an active mode manager... nothing to clean up
}
}
又执行checkForAndHandleModeChange()处理消息
private boolean checkForAndHandleModeChange(Message message) {
switch(message.what) {
case ModeStateMachine.CMD_START_CLIENT_MODE:
Log.d(TAG, "Switching from " + getCurrentMode() + " to ClientMode");
if (getCurrentMode().equals(mClientModeActiveState.getName()))
return NOT_HANDLED;
//将状态切换至ClientModeActiveState
mModeStateMachine.transitionTo(mClientModeActiveState);
break;
case ModeStateMachine.CMD_START_SCAN_ONLY_MODE:
Log.d(TAG, "Switching from " + getCurrentMode() + " to ScanOnlyMode");
if (getCurrentMode().equals(mScanOnlyModeActiveState.getName()))
return NOT_HANDLED;
mModeStateMachine.transitionTo(mScanOnlyModeActiveState);
break;
case ModeStateMachine.CMD_DISABLE_WIFI:
Log.d(TAG, "Switching from " + getCurrentMode() + " to WifiDisabled");
if (getCurrentMode().equals(mWifiDisabledState.getName()))
return NOT_HANDLED;
mModeStateMachine.transitionTo(mWifiDisabledState);
break;
default:
return NOT_HANDLED;
}
return HANDLED;
}
这里状态机直接将状态切换至ClientModeActiveState,此时会执行ClientModeActiveState的enter()方法
@Override
public void enter() {
Log.d(TAG, "Entering ClientModeActiveState");
mListener = new ClientListener();
//创建wifi客户端管理者ClientModeManager
mManager = mWifiInjector.makeClientModeManager(mListener);
//启动客户端模式
mManager.start();
mActiveModeManagers.add(mManager);
updateBatteryStatsWifiState(true);
}
查看start()
/**
* Start client mode.
*/
public void start() {
mStateMachine.sendMessage(ClientModeStateMachine.CMD_START);
}
这里又通过ClientModeStateMachine发送了一个CMD_START消息,使状态机由激活状态下的空闲状态变为已开启状态,而ClientModeStateMachine初始化时也是设置的IdleState为默认状态
ClientModeStateMachine(Looper looper) {
super(TAG, looper);
addState(mIdleState);
addState(mStartedState);
//设置IdleState为默认状态
setInitialState(mIdleState);
start();
}
所以这里先由IdleState处理此消息
private class IdleState extends State {
@Override
public void enter() {
Log.d(TAG, "entering IdleState");
mClientInterfaceName = null;
mIfaceIsUp = false;
}
@Override
public boolean processMessage(Message message) {
switch (message.what) {
case CMD_START:
//将wifi状态由不可用变为连接中状态
updateWifiState(WifiManager.WIFI_STATE_ENABLING,
WifiManager.WIFI_STATE_DISABLED);
//为连接状态下的客户端设置一个接口,此接口用于上层客户端与hal层通信
mClientInterfaceName =
mWifiNative.setupInterfaceForClientInConnectivityMode(
mWifiNativeInterfaceCallback);
if (TextUtils.isEmpty(mClientInterfaceName)) {
Log.e(TAG, "Failed to create ClientInterface. Sit in Idle");
updateWifiState(WifiManager.WIFI_STATE_UNKNOWN,
WifiManager.WIFI_STATE_ENABLING);
updateWifiState(WifiManager.WIFI_STATE_DISABLED,
WifiManager.WIFI_STATE_UNKNOWN);
break;
}
//将状态切换至已启动状态
transitionTo(mStartedState);
break;
default:
Log.d(TAG, "received an invalid message: " + message);
return NOT_HANDLED;
}
return HANDLED;
}
}
updateWifiState()方法会更新wifi的状态,此更新会发送一个全局的粘性广播,随后通过mWifiNative.setupInterfaceForClientInConnectivityMode(mWifiNativeInterfaceCallback)为连接状态下的客户端设置一个接口,此接口用于上层客户端与hal层通信,看一下该方法的实现
/**
* Setup an interface for client mode (for connectivity) operations.
*
* This method configures an interface in STA mode in all the native daemons
* (wificond, wpa_supplicant & vendor HAL).
*
* @param interfaceCallback Associated callback for notifying status changes for the iface.
* @return Returns the name of the allocated interface, will be null on failure.
*/
public String setupInterfaceForClientInConnectivityMode(
@NonNull InterfaceCallback interfaceCallback) {
return setupInterfaceForClientInConnectivityMode(interfaceCallback, false);
}
/**
* Setup an interface for client mode (for connectivity) operations.
*
* This method configures an interface in STA mode in all the native daemons
* (wificond, wpa_supplicant & vendor HAL).
*
* @param interfaceCallback Associated callback for notifying status changes for the iface.
* @param lowPriority the iface is of low priority.
* @return Returns the name of the allocated interface, will be null on failure.
*/
public String setupInterfaceForClientInConnectivityMode(
@NonNull InterfaceCallback interfaceCallback, boolean lowPriority) {
synchronized (mLock) {
//加载wifi驱动
if (!startHal()) {
Log.e(TAG, "Failed to start Hal");
mWifiMetrics.incrementNumSetupClientInterfaceFailureDueToHal();
return null;
}
//启动FST管理器,并开启与FST组的通信
boolean res = startFst();
if (!res)
return null;
//建立与spplicant的连接
if (!startSupplicant()) {
Log.e(TAG, "Failed to start supplicant");
mWifiMetrics.incrementNumSetupClientInterfaceFailureDueToSupplicant();
return null;
}
//分配Iface,全名Internet Interface,就是我们说的网卡
Iface iface = mIfaceMgr.allocateIface(Iface.IFACE_TYPE_STA_FOR_CONNECTIVITY);
if (iface == null) {
Log.e(TAG, "Failed to allocate new STA iface");
return null;
}
//绑定Iface的回调对象
iface.externalListener = interfaceCallback;
//设置Iface的名称
iface.name = createStaIface(iface, lowPriority);
if (TextUtils.isEmpty(iface.name)) {
Log.e(TAG, "Failed to create STA iface in vendor HAL");
mIfaceMgr.removeIface(iface.id);
mWifiMetrics.incrementNumSetupClientInterfaceFailureDueToHal();
return null;
}
//为mWificondControl绑定Iface
if (mWificondControl.setupInterfaceForClientMode(iface.name) == null) {
Log.e(TAG, "Failed to setup iface in wificond on " + iface);
teardownInterface(iface.name);
mWifiMetrics.incrementNumSetupClientInterfaceFailureDueToWificond();
return null;
}
//为mSupplicantStaIfaceHal绑定Iface
if (!mSupplicantStaIfaceHal.setupIface(iface.name)) {
Log.e(TAG, "Failed to setup iface in supplicant on " + iface);
teardownInterface(iface.name);
mWifiMetrics.incrementNumSetupClientInterfaceFailureDueToSupplicant();
return null;
}
if (mIsFstAvailable) {
if (!mSupplicantStaIfaceHal.setupIface(getFstSlaveIface())) {
Log.e(TAG, "Failed to setup iface " + getFstSlaveIface() + " in supplicant on");
teardownInterface(iface.name);
return null;
}
}
//创建网络观察者
iface.networkObserver = new NetworkObserverInternal(iface.id);
if (!registerNetworkObserver(iface.networkObserver)) {
Log.e(TAG, "Failed to register network observer on " + iface);
teardownInterface(iface.name);
return null;
}
//启动wifi监视器
mWifiMonitor.startMonitoring(iface.name);
// Just to avoid any race conditions with interface state change callbacks,
// update the interface state before we exit.
//激活Iface,up-激活,down-禁用
onInterfaceStateChanged(iface, isInterfaceUp(iface.name));
//初始化Iface信息
initializeNwParamsForClientInterface(iface.name);
Log.i(TAG, "Successfully setup " + iface);
iface.featureSet = getSupportedFeatureSetInternal(iface.name);
return iface.name;
}
}
此方法基本上涵盖了wifi开启的全过程,从加载驱动,建立通信到分配网卡,基本都是在hal层完成的,上层设置好回调接口后直接执行结果回调即可。关于hal层的启动流程后续会再梳理。
hal层启动之后再通过transitionTo(mStartedState)将状态切换至StartedState,此时执行StartedState的enter()方法
private class StartedState extends State {
private void onUpChanged(boolean isUp) {
if (isUp == mIfaceIsUp) {
return; // no change
}
mIfaceIsUp = isUp;
if (isUp) {
Log.d(TAG, "Wifi is ready to use for client mode");
//将wifi状态由连接中更改为已连接
mClientModeImpl.setOperationalMode(ClientModeImpl.CONNECT_MODE,
mClientInterfaceName);
updateWifiState(WifiManager.WIFI_STATE_ENABLED,
WifiManager.WIFI_STATE_ENABLING);
} else {
if (mClientModeImpl.isConnectedMacRandomizationEnabled()) {
// Handle the error case where our underlying interface went down if we
// do not have mac randomization enabled (b/72459123).
return;
}
// if the interface goes down we should exit and go back to idle state.
Log.d(TAG, "interface down!");
updateWifiState(WifiManager.WIFI_STATE_UNKNOWN,
WifiManager.WIFI_STATE_ENABLED);
mStateMachine.sendMessage(CMD_INTERFACE_DOWN);
}
}
@Override
public void enter() {
Log.d(TAG, "entering StartedState");
mIfaceIsUp = false;
//执行状态更改逻辑
onUpChanged(mWifiNative.isInterfaceUp(mClientInterfaceName));
}
@Override
public boolean processMessage(Message message) {
switch(message.what) {
case CMD_START:
// Already started, ignore this command.
break;
case CMD_INTERFACE_DOWN:
Log.e(TAG, "Detected an interface down, reporting failure to SelfRecovery");
mClientModeImpl.failureDetected(SelfRecovery.REASON_STA_IFACE_DOWN);
updateWifiState(WifiManager.WIFI_STATE_DISABLING,
WifiManager.WIFI_STATE_UNKNOWN);
transitionTo(mIdleState);
break;
case CMD_INTERFACE_STATUS_CHANGED:
boolean isUp = message.arg1 == 1;
onUpChanged(isUp);
break;
case CMD_INTERFACE_DESTROYED:
Log.d(TAG, "interface destroyed - client mode stopping");
updateWifiState(WifiManager.WIFI_STATE_DISABLING,
WifiManager.WIFI_STATE_ENABLED);
mClientInterfaceName = null;
transitionTo(mIdleState);
break;
default:
return NOT_HANDLED;
}
return HANDLED;
}
/**
* Clean up state, unregister listeners and update wifi state.
*/
@Override
public void exit() {
mClientModeImpl.setOperationalMode(ClientModeImpl.DISABLED_MODE, null);
if (mClientInterfaceName != null) {
mWifiNative.teardownInterface(mClientInterfaceName);
mClientInterfaceName = null;
mIfaceIsUp = false;
}
updateWifiState(WifiManager.WIFI_STATE_DISABLED,
WifiManager.WIFI_STATE_DISABLING);
// once we leave started, nothing else to do... stop the state machine
mStateMachine.quitNow();
}
}
enter()方法中执行了onUpChanged(mWifiNative.isInterfaceUp(mClientInterfaceName)),此方法中通过updateWifiState()更新wifi状态,将连接中更改为已连接,至此,wifi才得以真正的启动。同时在updateWifiState()中,会触发ClientModeManager.Listener的回调
/**
* Update Wifi state and send the broadcast.
* @param newState new Wifi state
* @param currentState current wifi state
*/
private void updateWifiState(int newState, int currentState) {
if (!mExpectedStop) {
//触发回调
mListener.onStateChanged(newState);
} else {
Log.d(TAG, "expected stop, not triggering callbacks: newState = " + newState);
}
// Once we report the mode has stopped/failed any other stop signals are redundant
// note: this can happen in failure modes where we get multiple callbacks as underlying
// components/interface stops or the underlying interface is destroyed in cleanup
if (newState == WifiManager.WIFI_STATE_UNKNOWN
|| newState == WifiManager.WIFI_STATE_DISABLED) {
mExpectedStop = true;
}
if (newState == WifiManager.WIFI_STATE_UNKNOWN) {
// do not need to broadcast failure to system
return;
}
mClientModeImpl.setWifiStateForApiCalls(newState);
//发送粘性广播
final Intent intent = new Intent(WifiManager.WIFI_STATE_CHANGED_ACTION);
intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
intent.putExtra(WifiManager.EXTRA_WIFI_STATE, newState);
intent.putExtra(WifiManager.EXTRA_PREVIOUS_WIFI_STATE, currentState);
mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
}
mListener是在ClientModeActiveState里面被实现了
class ClientModeActiveState extends ModeActiveState {
ClientListener mListener;
//此处实现了ClientModeManager.Listener回调
private class ClientListener implements ClientModeManager.Listener {
@Override
public void onStateChanged(int state) {
// make sure this listener is still active
if (this != mListener) {
Log.d(TAG, "Client mode state change from previous manager");
return;
}
Log.d(TAG, "State changed from client mode. state = " + state);
if (state == WifiManager.WIFI_STATE_UNKNOWN) {
// error while setting up client mode or an unexpected failure.
mModeStateMachine.sendMessage(CMD_CLIENT_MODE_FAILED, this);
} else if (state == WifiManager.WIFI_STATE_DISABLED) {
// client mode stopped
mModeStateMachine.sendMessage(CMD_CLIENT_MODE_STOPPED, this);
} else if (state == WifiManager.WIFI_STATE_ENABLED) {
// client mode is ready to go
Log.d(TAG, "client mode active");
//wifi开启后执行此方法
onModeActivationComplete();
} else {
// only care if client mode stopped or started, dropping
}
}
}
@Override
public void enter() {
Log.d(TAG, "Entering ClientModeActiveState");
mListener = new ClientListener();
mManager = mWifiInjector.makeClientModeManager(mListener);
mManager.start();
mActiveModeManagers.add(mManager);
updateBatteryStatsWifiState(true);
}
@Override
public void exit() {
super.exit();
mListener = null;
}
@Override
public boolean processMessage(Message message) {
if (checkForAndHandleModeChange(message)) {
return HANDLED;
}
switch(message.what) {
case CMD_START_CLIENT_MODE:
Log.d(TAG, "Received CMD_START_CLIENT_MODE when active - drop");
break;
case CMD_CLIENT_MODE_FAILED:
if (mListener != message.obj) {
Log.d(TAG, "Client mode state change from previous manager");
return HANDLED;
}
Log.d(TAG, "ClientMode failed, return to WifiDisabledState.");
// notify WifiController that ClientMode failed
mClientModeCallback.onStateChanged(WifiManager.WIFI_STATE_UNKNOWN);
mModeStateMachine.transitionTo(mWifiDisabledState);
break;
case CMD_CLIENT_MODE_STOPPED:
if (mListener != message.obj) {
Log.d(TAG, "Client mode state change from previous manager");
return HANDLED;
}
Log.d(TAG, "ClientMode stopped, return to WifiDisabledState.");
// notify WifiController that ClientMode stopped
mClientModeCallback.onStateChanged(WifiManager.WIFI_STATE_DISABLED);
mModeStateMachine.transitionTo(mWifiDisabledState);
break;
default:
return NOT_HANDLED;
}
return NOT_HANDLED;
}
}
wifi开启之后会执行ClientListener的onStateChange()方法,此时状态机的状态为WIFI_STATE_ENABLED,所以会执行onModeActivationComplete()
// Hook to be used by sub-classes of ModeActiveState to indicate the completion of
// bringup of the corresponding mode.
public void onModeActivationComplete() {
updateScanMode();
}
// Update the scan state based on all active mode managers.
// Note: This is an overkill currently because there is only 1 of scan-only or client
// mode present today.
private void updateScanMode() {
boolean scanEnabled = false;
boolean scanningForHiddenNetworksEnabled = false;
for (ActiveModeManager modeManager : mActiveModeManagers) {
@ActiveModeManager.ScanMode int scanState = modeManager.getScanMode();
switch (scanState) {
case ActiveModeManager.SCAN_NONE:
break;
case ActiveModeManager.SCAN_WITHOUT_HIDDEN_NETWORKS:
scanEnabled = true;
break;
case ActiveModeManager.SCAN_WITH_HIDDEN_NETWORKS:
scanEnabled = true;
scanningForHiddenNetworksEnabled = true;
break;
}
}
mScanRequestProxy.enableScanning(scanEnabled, scanningForHiddenNetworksEnabled);
}
此时状态机切换到ScanOnlyModeActiveState,开始扫描周围wifi,至此,wifi启动流程分析完毕。