android wifi打开进程源码解析及Wifi打开失败原因分析
在android中wifi打开的状态从DISABLED-->ENABLING-->ENABLED
1 WifiSettings.java--wifi界面wifi开关
wifi开关定义在SettingsActivity.java中,传入WifiEnabler.java,并在WifiEnabler.java中响应。
private SwitchBar mSwitchBar; public SwitchBar getSwitchBar() { return mSwitchBar; } mSwitchBar = (SwitchBar) findViewById(R.id.switch_bar);
private SwitchBar mSwitchBar; public SwitchBar getSwitchBar() { return mSwitchBar; } mSwitchBar = (SwitchBar) findViewById(R.id.switch_bar);
2 WifiEnabler.java--响应点击wifi开关
WifiEnabler.java实际处理开关wifi的消息。
@Override public void onSwitchChanged(Switch switchView, boolean isChecked) { Log.d(TAG, "mWifiManager.setWifiEnabled"); if (!mWifiManager.setWifiEnabled(isChecked)) { // Error Log.d(TAG, "set wifi enabled error"); mSwitchBar.setEnabled(true); Toast.makeText(mContext, R.string.wifi_error, Toast.LENGTH_SHORT).show(); } }3 WifiManager.java和WifiService.java
WifiEnabler.java调用WifiManager,WifiManager调用WifiService.
mService.setWifiEnabled(enabled);
public synchronized boolean setWifiEnabled(boolean enable) { Slog.d(TAG, "setWifiEnabled: " + enable + " pid=" + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()); if (DBG) { Slog.e(TAG, "Invoking mWifiStateMachine.setWifiEnabled\n"); } if (!mIsControllerStarted) { Slog.e(TAG,"WifiController is not yet started, abort setWifiEnabled"); return false; } mWifiController.sendMessage(CMD_WIFI_TOGGLED); return true; }
4 WifiController.java
WifiController.java处理开关wifi 的消息CMD_WIFI_TOGGLED,从ApStaDisabledState-->StaEnabledState-->DeviceActiveState,
class ApStaDisabledState extends State { @Override public boolean processMessage(Message msg) { switch (msg.what) { case CMD_WIFI_TOGGLED: case CMD_AIRPLANE_TOGGLED: if (mSettingsStore.isWifiToggleEnabled()) { if (doDeferEnable(msg)) { if (mHaveDeferredEnable) { // have 2 toggles now, inc serial number an ignore both mDeferredEnableSerialNumber++; } mHaveDeferredEnable = !mHaveDeferredEnable; break; } if (mDeviceIdle == false) { transitionTo(mDeviceActiveState); } else { checkLocksAndTransitionWhenDeviceIdle(); } } else if (mSettingsStore.isScanAlwaysAvailable()) { transitionTo(mStaDisabledWithScanState); } break; }
class StaEnabledState extends State { @Override public void enter() { mWifiStateMachine.setSupplicantRunning(true); } }在进入StaEnabledState时由WifiStateMachine启动supplicant,进入DeviceActiveState时启动driver。
/* Parent: StaEnabledState */ class DeviceActiveState extends State { @Override public void enter() { mWifiStateMachine.setOperationalMode(WifiStateMachine.CONNECT_MODE); mWifiStateMachine.setDriverStart(true); mWifiStateMachine.setHighPerfModeEnabled(false); } }5 WifiStateMachine.java
WIFI_STATE_ENABLED由SupplicantStartingState发出, CMD_START_SUPPLICANT-->startMonitoring-->WifiMonitor.SUP_CONNECTION_EVENT-->WifiManager.WIFI_STATE_ENABLED,到此wifi开关完全打开。
class InitialState extends State { @Override public boolean processMessage(Message message) { switch (message.what) { case CMD_START_SUPPLICANT: if (mWifiNative.loadDriver()) { mNwService.wifiFirmwareReload(mInterfaceName, "STA"); if(mWifiNative.startSupplicant(mP2pSupported)) { setWifiState(WIFI_STATE_ENABLING); mWifiMonitor.startMonitoring(); transitionTo(mSupplicantStartingState); } } break; } }
class SupplicantStartingState extends State { @Override public boolean processMessage(Message message) { switch(message.what) { case WifiMonitor.SUP_CONNECTION_EVENT: if (DBG) log("Supplicant connection established"); setWifiState(WIFI_STATE_ENABLED);transitionTo(mDriverStartedState); break; } }
6 SoftAP打开失败wifi不能打开原因分析
SoftAP打开过程:
WifiService的setWifiApEnabled-->WifiController的CDM_SET_AP-->WifiStateMachine的CMD_START_AP
class SoftApStartingState extends State { @Override public void enter() { if (message.what == CMD_START_AP) { final WifiConfiguration config = (WifiConfiguration) message.obj; if (config == null) { mWifiApConfigChannel.sendMessage(CMD_REQUEST_AP_CONFIG); } } } @Override public boolean processMessage(Message message) { switch(message.what) { case CMD_START_AP: deferMessage(message); break; case WifiStateMachine.CMD_RESPONSE_AP_CONFIG: WifiConfiguration config = (WifiConfiguration) message.obj; if (config != null) { startSoftApWithConfig(config); } break; case CMD_START_AP_FAILURE: setWifiApState(WIFI_AP_STATE_FAILED); transitionTo(mInitialState); break; } } }CMD_REQUEST_AP_CONFIG-->CMD_RESPONSE_AP_CONFIG-->startSoftApWithConfig-->CMD_START_FAILURE
由于WifiService没有收到WIFI_AP_START_FAILED,导致WifiController处于ApEnabledState,无法接收CMD_WIFI_TOGGLED消息,从而无法进入WifiStateMachie打开WIfi。