简介:当手机灭屏情况下,有保存网络时,若已连接,不扫描,否则,PNO扫描,即只扫描已保存的网络。最小间隔min=20s,最大间隔max=20s*3=60s
WifiConnectivityManager.java 灭屏时,WifiConnectivityManager中handleScreenStateChanged函数会判断是否触发PNO扫描。并且进行PNO扫描列表设置、PNO扫描间隔(20s)设置等PNO扫描的参数设置。所以先从处理屏幕状态改变开始。
public void handleScreenStateChanged(boolean screenOn) {
localLog("handleScreenStateChanged: screenOn=" + screenOn);
mScreenOn = screenOn;
mOpenNetworkNotifier.handleScreenStateChanged(screenOn);
mCarrierNetworkNotifier.handleScreenStateChanged(screenOn);
startConnectivityScan(SCAN_ON_SCHEDULE);
}
开始连接扫描。 扫描方式根据当前的屏幕状态和WiFi状态选择。这里会选择PNO扫描。
private void startConnectivityScan(boolean scanImmediately) {
localLog("startConnectivityScan: screenOn=" + mScreenOn
+ " wifiState=" + stateToString(mWifiState)
+ " scanImmediately=" + scanImmediately
+ " wifiEnabled=" + mWifiEnabled
+ " wifiConnectivityManagerEnabled="
+ mWifiConnectivityManagerEnabled);
if (!mWifiEnabled || !mWifiConnectivityManagerEnabled) {
return;
}
if (mWifiState != WIFI_STATE_CONNECTED && mWifiState != WIFI_STATE_DISCONNECTED) {
return;
}
if (mScreenOn) {
startPeriodicScan(scanImmediately);
} else {
if (mWifiState == WIFI_STATE_DISCONNECTED && !mPnoScanStarted) {
startDisconnectedPnoScan();
}
}
}
当屏幕关闭且WiFI未连接时,开启PNO扫描,初始化scan的设置。 可以看到扫描间隔为20s:scanSettings.periodInMs = DISCONNECTED_PNO_SCAN_INTERVAL_MS
private static final int DISCONNECTED_PNO_SCAN_INTERVAL_MS = 20 * 1000; // 20 seconds
private void startDisconnectedPnoScan() {
// Initialize PNO settings
PnoSettings pnoSettings = new PnoSettings();
List<PnoSettings.PnoNetwork> pnoNetworkList = mConfigManager.retrievePnoNetworkList();
int listSize = pnoNetworkList.size();
pnoSettings.networkList = new PnoSettings.PnoNetwork[listSize];
pnoSettings.networkList = pnoNetworkList.toArray(pnoSettings.networkList);
pnoSettings.min5GHzRssi = mMin5GHzRssi;
pnoSettings.min24GHzRssi = mMin24GHzRssi;
pnoSettings.initialScoreMax = mInitialScoreMax;
pnoSettings.currentConnectionBonus = mCurrentConnectionBonus;
pnoSettings.sameNetworkBonus = mSameNetworkBonus;
pnoSettings.secureBonus = mSecureBonus;
pnoSettings.band5GHzBonus = mBand5GHzBonus;
// Initialize scan settings
ScanSettings scanSettings = new ScanSettings();
scanSettings.band = getScanBand();
scanSettings.reportEvents = WifiScanner.REPORT_EVENT_NO_BATCH;
scanSettings.numBssidsPerScan = 0;
scanSettings.periodInMs = DISCONNECTED_PNO_SCAN_INTERVAL_MS;
mPnoScanListener.clearScanDetails();
mScanner.startDisconnectedPnoScan(scanSettings, pnoSettings, mPnoScanListener);
mPnoScanStarted = true;
}
WifiScanner.java startDisconnectedPnoScan --> startPnoScan 开启PNO扫描
public void startDisconnectedPnoScan(ScanSettings scanSettings, PnoSettings pnoSettings,
PnoScanListener listener) {
Preconditions.checkNotNull(listener, "listener cannot be null");
Preconditions.checkNotNull(pnoSettings, "pnoSettings cannot be null");
int key = addListener(listener);
if (key == INVALID_KEY) return;
validateChannel();
pnoSettings.isConnected = false;
startPnoScan(scanSettings, pnoSettings, key);
}
startPnoScan发送PNO扫描(CMD_START_PNO_SCAN)的消息,由WifiScanningServiceImpl处理。
private void startPnoScan(ScanSettings scanSettings, PnoSettings pnoSettings, int key) {
// Bundle up both the settings and send it across.
Bundle pnoParams = new Bundle();
// Set the PNO scan flag.
scanSettings.isPnoScan = true;
pnoParams.putParcelable(PNO_PARAMS_SCAN_SETTINGS_KEY, scanSettings);
pnoParams.putParcelable(PNO_PARAMS_PNO_SETTINGS_KEY, pnoSettings);
mAsyncChannel.sendMessage(CMD_START_PNO_SCAN, 0, key, pnoParams);
}
WifiScanningServiceImpl.java 从StartedState状态开始,获取到PNO扫描的设置以后,进入HwPnoScanState状态。
class StartedState extends State {
.......
@Override
public boolean processMessage(Message msg) {
ClientInfo ci = mClients.get(msg.replyTo);
switch (msg.what) {
case WifiScanner.CMD_START_PNO_SCAN:
........
pnoParams.setDefusable(true);
PnoSettings pnoSettings =
pnoParams.getParcelable(WifiScanner.PNO_PARAMS_PNO_SETTINGS_KEY);
if (mScannerImpl.isHwPnoSupported(pnoSettings.isConnected)) {
deferMessage(msg);
transitionTo(mHwPnoScanState);
} else {
replyFailed(msg, WifiScanner.REASON_INVALID_REQUEST, "not supported");
}
.................
}
return HANDLED;
}
}
如果已经有PNO扫描,则进入StartedState。如果没有,则addHwPnoScanRequest。 注意:这里的StartedState是WifiBackgroundScanStateMachine中的StartedState。
class HwPnoScanState extends State {
@Override
public boolean processMessage(Message msg) {
ClientInfo ci = mClients.get(msg.replyTo);
switch (msg.what) {
case WifiScanner.CMD_START_PNO_SCAN:
Bundle pnoParams = (Bundle) msg.obj;
if (pnoParams == null) {
replyFailed(msg, WifiScanner.REASON_INVALID_REQUEST, "params null");
return HANDLED;
}
pnoParams.setDefusable(true);
PnoSettings pnoSettings =
pnoParams.getParcelable(WifiScanner.PNO_PARAMS_PNO_SETTINGS_KEY);
ScanSettings scanSettings =
pnoParams.getParcelable(WifiScanner.PNO_PARAMS_SCAN_SETTINGS_KEY);
if (addHwPnoScanRequest(ci, msg.arg2, scanSettings, pnoSettings)) {
replySucceeded(msg);
} else {
replyFailed(msg, WifiScanner.REASON_INVALID_REQUEST, "bad request");
transitionTo(mStartedState);
}
break;
...........
return HANDLED;
}
}
addHwPnoScanRequest --> addPnoScanRequest
private boolean addHwPnoScanRequest(ClientInfo ci, int handler, ScanSettings scanSettings,
PnoSettings pnoSettings) {
if (ci == null) {
Log.d(TAG, "Failing scan request ClientInfo not found " + handler);
return false;
}
if (!mActivePnoScans.isEmpty()) {
loge("Failing scan request because there is already an active scan");
return false;
}
WifiNative.PnoSettings nativePnoSettings =
convertSettingsToPnoNative(scanSettings, pnoSettings);
if (!mScannerImpl.setHwPnoList(nativePnoSettings, mPnoScanStateMachine)) {
return false;
}
logScanRequest("addHwPnoScanRequest", ci, handler, null, scanSettings, pnoSettings);
addPnoScanRequest(ci, handler, scanSettings, pnoSettings);
return true;
}
private void addPnoScanRequest(ClientInfo ci, int handler, ScanSettings scanSettings,
PnoSettings pnoSettings) {
mActivePnoScans.addRequest(ci, handler, WifiStateMachine.WIFI_WORK_SOURCE,
Pair.create(pnoSettings, scanSettings));
addInternalClient(ci);
}
WifiBackgroundScanStateMachine --> StartedState
未完待续。。。。