总体流程
- 老套路基本不变: WifiSettings 通过 WifiManager 下cmd 给 WifiService
- WifiService 收到cmd后,先完成一部分列行检查(如UID的权限、是否airPlayMode等等),之后将cmd下发给到WifiController
- WifiController 收到cmd 之后,在内部状态机轮询一圈(就是将cmd送给对应的状态机进行处理,处理完后,送往下一个状态机进行加工),俨然很标准化的流水线工序,完成后再送到WifiStateMachinePrime处理
- WifiStateMachinePrime 是P 版本新增的Prime状态机,分担了原来WifiStateMachine工作,同样按照标准化流水线工序加工,完成后送到WifiNative,
- WifiNative是包工头,负责将活儿下发到工人(wpa_supplicant)身上,工人没完成一件任务,上报分销商(wifiMonitor),各大分销商又将结果按照约定的渠道上报包工头(wifiNative)、总经销商(wifiService、wifiScanningService)等等,完成此项工作的闭环。
代码流程
1. WifiEnabler --> WifiManager
- 老规矩: WifiSettings --> WifiEnabler 调用wifiManager 来disable Wifi
packages/apps/Settings/src/com/android/settings/wifi/WifiEnabler.java
public boolean onSwitchToggled(boolean isChecked) {
..
mWifiManager.setWifiEnabled(isChecked);
}
2. WifiManager–> WifiService --> WifiServiceImpl
- setWifiEnabled 函数里 前面有一大堆列行检查
- 最后是关键,发送CMD_WIFI_TOGGLED
frameworks/opt/net/wifi/service/java/com/android/server/wifi/WifiServiceImpl.java
public synchronized boolean setWifiEnabled(String packageName, boolean enable){
....
mWifiController.sendMessage(CMD_WIFI_TOGGLED);
}
3. WifiServiceImpl --> WifiController
- 流水线上的标准加工: StaEnabledState --> StaDisabledState
- 转入到wifiStateMachinePrime 处理wifi disable 事项
frameworks/opt/net/wifi/service/java/com/android/server/wifi/WifiController.java
class StaEnabledState extends State {
switch (msg.what) {
case CMD_WIFI_TOGGLED:
if (! mSettingsStore.isWifiToggleEnabled()) {
if (checkScanOnlyModeAvailable()) {
transitionTo(mStaDisabledWithScanState);
} else {
transitionTo(mStaDisabledState); // 转入StaDisableState 处理 wifi disable 事项
}
}
class StaDisabledState extends State {
public void enter() {
mWifiStateMachinePrime.disableWifi(); // 转入wifiStateMachinePrime 处理wifi disable
// Supplicant can't restart right away, so note the time we switched off
mDisabledTimestamp = SystemClock.elapsedRealtime();
mDeferredEnableSerialNumber++;
mHaveDeferredEnable = false;
mWifiStateMachine.clearANQPCache();
}
}
4. WifiStateMachinePrime --> WifiScaningServiceImpl
- WifiStateMachinePrime 发送CMD_DISABLE_WIFI给到内部状态机处理
- WifiDisabledState 接领任务,先广播停掉Scan(WifiManager.EXTRA_SCAN_AVALIABLE),然后 clearScanResults
frameworks/opt/net/wifi/service/java/com/android/server/wifi/WifiStateMachinePrime.java
public void disableWifi() {
changeMode(ModeStateMachine.CMD_DISABLE_WIFI);
}
class WifiDisabledState extends ModeActiveState {
public void enter() {
mDefaultModeManager.sendScanAvailableBroadcast(mContext, false);
mScanRequestProxy.enableScanningForHiddenNetworks(false);
mScanRequestProxy.clearScanResults();
}
}
5. WifiScaningServiceImpl 善后
- 接收到wifi disable 需求后,立即开始清掉ScanResults
frameworks/opt/net/wifi/service/java/com/android/server/wifi/scanner/WifiScanningServiceImpl.java{
public void onReceive(Context context, Intent intent){
else if (state == WifiManager.WIFI_STATE_DISABLED) {
mBackgroundScanStateMachine.sendMessage(CMD_DRIVER_UNLOADED);
mSingleScanStateMachine.sendMessage(CMD_DRIVER_UNLOADED);
mPnoScanStateMachine.sendMessage(CMD_DRIVER_UNLOADED);
}
}
class DefaultState extends State {
public void enter() {
mActiveScans.clear();
mPendingScans.clear();}
}