diff options
author | Roshan Pius <rpius@google.com> | 2019-09-23 07:26:29 -0700 |
---|---|---|
committer | Roshan Pius <rpius@google.com> | 2019-09-25 15:15:44 -0700 |
commit | aedd6a682f0df40dec61e76146018b2a1e6794f1 (patch) | |
tree | 6b2216c0e2c2374b6880f51bf2308e5095a4f14a /service | |
parent | 0525d17eeb8138474b50abcb2187076e83222a1a (diff) |
WifiScanningService: Support multiple scanner impls for PNO scan
Create a new helper class to track PNO scan across multiple impls:
a) Pass the PNO scan request to all of the available impls.
b) Wait till a PNO match is reported from any of of the impls.
c) Consolidate the failure from different impls and pass it to external clients.
As long as at-least 1 of the impls PNO succeeded, failures from other
impls are ignored (since there is a possibility of a PNO match).
Bug: 140111024
Test: atest com.android.server.wifi.scanner
Change-Id: Ib670c38d5e54132f58a3b41194fb8ef99ea7d0aa
Diffstat (limited to 'service')
-rw-r--r-- | service/java/com/android/server/wifi/scanner/WifiScanningServiceImpl.java | 136 |
1 files changed, 120 insertions, 16 deletions
diff --git a/service/java/com/android/server/wifi/scanner/WifiScanningServiceImpl.java b/service/java/com/android/server/wifi/scanner/WifiScanningServiceImpl.java index 715fb113c..1fdd5044c 100644 --- a/service/java/com/android/server/wifi/scanner/WifiScanningServiceImpl.java +++ b/service/java/com/android/server/wifi/scanner/WifiScanningServiceImpl.java @@ -1695,10 +1695,14 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub { private final RequestList<Pair<PnoSettings, ScanSettings>> mActivePnoScans = new RequestList<>(); + // Tracks scan requests across multiple scanner impls. + private final ScannerImplsTracker mScannerImplsTracker; WifiPnoScanStateMachine(Looper looper) { super("WifiPnoScanStateMachine", looper); + mScannerImplsTracker = new ScannerImplsTracker(); + setLogRecSize(256); setLogOnlyTransitions(false); @@ -1717,23 +1721,124 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub { transitionTo(mStartedState); } - private final class PnoEventHandler implements WifiNative.PnoEventHandler { - private final String mImplIfaceName; + /** + * Tracks a PNO scan request across all the available scanner impls. + * + * Note: If there are failures on some of the scanner impls, we ignore them since we can + * get a PNO match from the other successful impls. We don't declare total scan + * failures, unless all the scanner impls fail. + */ + private final class ScannerImplsTracker { + private final class PnoEventHandler implements WifiNative.PnoEventHandler { + private final String mImplIfaceName; - PnoEventHandler(@NonNull String implIfaceName) { - mImplIfaceName = implIfaceName; + PnoEventHandler(@NonNull String implIfaceName) { + mImplIfaceName = implIfaceName; + } + + @Override + public void onPnoNetworkFound(ScanResult[] results) { + if (DBG) localLog("onWifiPnoNetworkFound event received"); + reportPnoNetworkFoundForImpl(mImplIfaceName, results); + } + + @Override + public void onPnoScanFailed() { + if (DBG) localLog("onWifiPnoScanFailed event received"); + reportPnoScanFailedForImpl(mImplIfaceName); + } } - @Override - public void onPnoNetworkFound(ScanResult[] results) { - if (DBG) localLog("onWifiPnoNetworkFound event received"); - sendMessage(CMD_PNO_NETWORK_FOUND, 0, 0, results); + private static final int STATUS_PENDING = 0; + private static final int STATUS_FAILED = 2; + + // Tracks scan status per impl. + Map<String, Integer> mStatusPerImpl = new ArrayMap<>(); + + /** + * Triggers a new PNO with the specified settings on all the available scanner impls. + * @return true if the PNO succeeded on any of the impl, false otherwise. + */ + public boolean setHwPnoList(WifiNative.PnoSettings pnoSettings) { + mStatusPerImpl.clear(); + boolean anySuccess = false; + for (Map.Entry<String, WifiScannerImpl> entry : mScannerImpls.entrySet()) { + String ifaceName = entry.getKey(); + WifiScannerImpl impl = entry.getValue(); + boolean success = impl.setHwPnoList( + pnoSettings, new PnoEventHandler(ifaceName)); + if (!success) { + Log.e(TAG, "Failed to start pno on " + ifaceName); + continue; + } + mStatusPerImpl.put(ifaceName, STATUS_PENDING); + anySuccess = true; + } + return anySuccess; } - @Override - public void onPnoScanFailed() { - if (DBG) localLog("onWifiPnoScanFailed event received"); - sendMessage(CMD_PNO_SCAN_FAILED, 0, 0, null); + /** + * Resets any ongoing PNO on all the available scanner impls. + * @return true if the PNO stop succeeded on all of the impl, false otherwise. + */ + public boolean resetHwPnoList() { + boolean allSuccess = true; + for (String ifaceName : mStatusPerImpl.keySet()) { + WifiScannerImpl impl = mScannerImpls.get(ifaceName); + if (impl == null) continue; + boolean success = impl.resetHwPnoList(); + if (!success) { + Log.e(TAG, "Failed to stop pno on " + ifaceName); + allSuccess = false; + } + } + mStatusPerImpl.clear(); + return allSuccess; + } + + /** + * @return true if HW PNO is supported on all the available scanner impls, + * false otherwise. + */ + public boolean isHwPnoSupported(boolean isConnected) { + for (WifiScannerImpl impl : mScannerImpls.values()) { + if (!impl.isHwPnoSupported(isConnected)) { + return false; + } + } + return true; + } + + private void reportPnoNetworkFoundForImpl(@NonNull String implIfaceName, + ScanResult[] results) { + Integer status = mStatusPerImpl.get(implIfaceName); + if (status != null && status == STATUS_PENDING) { + sendMessage(CMD_PNO_NETWORK_FOUND, 0, 0, results); + } + } + + private int getConsolidatedStatus() { + boolean anyPending = mStatusPerImpl.values().stream() + .anyMatch(status -> status == STATUS_PENDING); + // at-least one impl status is still pending. + if (anyPending) { + return STATUS_PENDING; + } else { + // all failed. + return STATUS_FAILED; + } + } + + private void reportPnoScanFailedForImpl(@NonNull String implIfaceName) { + Integer currentStatus = mStatusPerImpl.get(implIfaceName); + if (currentStatus != null && currentStatus == STATUS_PENDING) { + mStatusPerImpl.put(implIfaceName, STATUS_FAILED); + } + // Now check if all the scanner impls scan status is available. + int consolidatedStatus = getConsolidatedStatus(); + if (consolidatedStatus == STATUS_FAILED) { + sendMessage(CMD_PNO_SCAN_FAILED); + } } } @@ -1802,7 +1907,7 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub { pnoParams.setDefusable(true); PnoSettings pnoSettings = pnoParams.getParcelable(WifiScanner.PNO_PARAMS_PNO_SETTINGS_KEY); - if (getAnyImpl().isHwPnoSupported(pnoSettings.isConnected)) { + if (mScannerImplsTracker.isHwPnoSupported(pnoSettings.isConnected)) { deferMessage(msg); transitionTo(mHwPnoScanState); } else { @@ -1828,7 +1933,7 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub { @Override public void exit() { // Reset PNO scan in ScannerImpl before we exit. - getAnyImpl().resetHwPnoList(); + mScannerImplsTracker.resetHwPnoList(); removeInternalClient(); } @@ -1994,8 +2099,7 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub { } WifiNative.PnoSettings nativePnoSettings = convertSettingsToPnoNative(scanSettings, pnoSettings); - if (!getAnyImpl().setHwPnoList(nativePnoSettings, - new PnoEventHandler(getAnyImpl().getIfaceName()))) { + if (!mScannerImplsTracker.setHwPnoList(nativePnoSettings)) { return false; } logScanRequest("addHwPnoScanRequest", ci, handler, null, scanSettings, pnoSettings); |