diff options
author | Roshan Pius <rpius@google.com> | 2019-10-07 06:14:58 -0700 |
---|---|---|
committer | Roshan Pius <rpius@google.com> | 2019-10-11 15:10:28 -0700 |
commit | 46adcb39a183597343cc1184521c0684212e6c5e (patch) | |
tree | 4fd67463d37949e3ad25bc6fa7fb1a3a4e6ecd42 /service | |
parent | 5a00530815780fd21d7b120bbd471fadf60f1117 (diff) |
WifiNetworkFactory: Use the latest cached scan results
Before starting scans for processing a network request, fetch the latest
cached scan results to speed up the matching process. The cached scan
results are filtered out to remove scan results that are older than 20
seconds.
As long as there was a previous scan in the last 20 seconds, there are 2
benefits with this change:
a) There is currently a delay of 2-3 seconds after the request
where the user sees a blank screen when platform is performing
the first scan. This can be avoided and we can present the user with
matches immediately when the request is received.
b) If the request is for a specific bssid and there is an approved match
in the cached scan results, then we can bypass the UI and trigger connection.
Also, renames "PreviouslyApproved" -> "Approved" in test name to ensure
the test names fit in one line :)
Bug: 134712530
Test: atest com.android.server.wifi
Test: Manually verified with CtsVerifier tests that the UI does not
start out with a blank page (because the matched networks are already
found by using the cached results).
Change-Id: I7a788777aabd11562077be88fcc4c9cd45e5b9ab
Merged-In: I7a788777aabd11562077be88fcc4c9cd45e5b9ab
(cherry-picked from 0ab35f26f0da8885a5d249a678187993da425447)
Diffstat (limited to 'service')
-rw-r--r-- | service/java/com/android/server/wifi/WifiNetworkFactory.java | 113 |
1 files changed, 78 insertions, 35 deletions
diff --git a/service/java/com/android/server/wifi/WifiNetworkFactory.java b/service/java/com/android/server/wifi/WifiNetworkFactory.java index 48797f773..be6ac6473 100644 --- a/service/java/com/android/server/wifi/WifiNetworkFactory.java +++ b/service/java/com/android/server/wifi/WifiNetworkFactory.java @@ -82,6 +82,8 @@ public class WifiNetworkFactory extends NetworkFactory { @VisibleForTesting private static final int SCORE_FILTER = 60; @VisibleForTesting + public static final int CACHED_SCAN_RESULTS_MAX_AGE_IN_MILLIS = 20 * 1000; // 20 seconds + @VisibleForTesting public static final int PERIODIC_SCAN_INTERVAL_MS = 10 * 1000; // 10 seconds @VisibleForTesting public static final int NETWORK_CONNECTION_TIMEOUT_MS = 30 * 1000; // 30 seconds @@ -230,37 +232,10 @@ public class WifiNetworkFactory extends NetworkFactory { if (mVerboseLoggingEnabled) { Log.v(TAG, "Received " + scanResults.length + " scan results"); } - List<ScanResult> matchedScanResults = - getNetworksMatchingActiveNetworkRequest(scanResults); - if (mActiveMatchedScanResults == null) { - // only note the first match size in metrics (chances of this changing in further - // scans is pretty low) - mWifiMetrics.incrementNetworkRequestApiMatchSizeHistogram( - matchedScanResults.size()); - } - mActiveMatchedScanResults = matchedScanResults; - - ScanResult approvedScanResult = null; - if (isActiveRequestForSingleAccessPoint()) { - approvedScanResult = - findUserApprovedAccessPointForActiveRequestFromActiveMatchedScanResults(); - } - if (approvedScanResult != null - && !mWifiConfigManager.wasEphemeralNetworkDeleted( - ScanResultUtil.createQuotedSSID(approvedScanResult.SSID))) { - Log.v(TAG, "Approved access point found in matching scan results. " - + "Triggering connect " + approvedScanResult); - handleConnectToNetworkUserSelectionInternal( - ScanResultUtil.createNetworkFromScanResult(approvedScanResult)); - mWifiMetrics.incrementNetworkRequestApiNumUserApprovalBypass(); - // TODO (b/122658039): Post notification. - } else { - if (mVerboseLoggingEnabled) { - Log.v(TAG, "No approved access points found in matching scan results. " - + "Sending match callback"); - } - sendNetworkRequestMatchCallbacksForActiveRequest(matchedScanResults); - // Didn't find an approved match, schedule the next scan. + if (!handleScanResultsAndTriggerConnectIfUserApprovedMatchFound(scanResults)) { + // Didn't find an approved match, send the matching results to UI and schedule the + // next scan. + sendNetworkRequestMatchCallbacksForActiveRequest(mActiveMatchedScanResults); scheduleNextPeriodicScan(); } } @@ -612,10 +587,19 @@ public class WifiNetworkFactory extends NetworkFactory { wns.requestorUid, wns.requestorPackageName); mWifiMetrics.incrementNetworkRequestApiNumRequest(); - // Start UI to let the user grant/disallow this request from the app. - startUi(); - // Trigger periodic scans for finding a network in the request. - startPeriodicScans(); + // Fetch the latest cached scan results to speed up network matching. + ScanResult[] cachedScanResults = getFilteredCachedScanResults(); + if (mVerboseLoggingEnabled) { + Log.v(TAG, "Using cached " + cachedScanResults.length + " scan results"); + } + if (!handleScanResultsAndTriggerConnectIfUserApprovedMatchFound(cachedScanResults)) { + // Start UI to let the user grant/disallow this request from the app. + startUi(); + // Didn't find an approved match, send the matching results to UI and trigger + // periodic scans for finding a network in the request. + sendNetworkRequestMatchCallbacksForActiveRequest(mActiveMatchedScanResults); + startPeriodicScans(); + } } } @@ -1331,6 +1315,65 @@ public class WifiNetworkFactory extends NetworkFactory { } /** + * Handle scan results + * a) Find all scan results matching the active network request. + * b) If the request is for a single bssid, check if the matching ScanResult was pre-approved + * by the user. + * c) If yes to (b), trigger a connect immediately and returns true. Else, returns false. + * + * @param scanResults Array of {@link ScanResult} to be processed. + * @return true if a pre-approved network was found for connection, false otherwise. + */ + private boolean handleScanResultsAndTriggerConnectIfUserApprovedMatchFound( + ScanResult[] scanResults) { + List<ScanResult> matchedScanResults = + getNetworksMatchingActiveNetworkRequest(scanResults); + if ((mActiveMatchedScanResults == null || mActiveMatchedScanResults.isEmpty()) + && !matchedScanResults.isEmpty()) { + // only note the first match size in metrics (chances of this changing in further + // scans is pretty low) + mWifiMetrics.incrementNetworkRequestApiMatchSizeHistogram( + matchedScanResults.size()); + } + mActiveMatchedScanResults = matchedScanResults; + + ScanResult approvedScanResult = null; + if (isActiveRequestForSingleAccessPoint()) { + approvedScanResult = + findUserApprovedAccessPointForActiveRequestFromActiveMatchedScanResults(); + } + if (approvedScanResult != null + && !mWifiConfigManager.wasEphemeralNetworkDeleted( + ScanResultUtil.createQuotedSSID(approvedScanResult.SSID))) { + Log.v(TAG, "Approved access point found in matching scan results. " + + "Triggering connect " + approvedScanResult); + handleConnectToNetworkUserSelectionInternal( + ScanResultUtil.createNetworkFromScanResult(approvedScanResult)); + mWifiMetrics.incrementNetworkRequestApiNumUserApprovalBypass(); + return true; + } + if (mVerboseLoggingEnabled) { + Log.v(TAG, "No approved access points found in matching scan results"); + } + return false; + } + + /** + * Retrieve the latest cached scan results from wifi scanner and filter out any + * {@link ScanResult} older than {@link #CACHED_SCAN_RESULTS_MAX_AGE_IN_MILLIS}. + */ + private @NonNull ScanResult[] getFilteredCachedScanResults() { + List<ScanResult> cachedScanResults = mWifiScanner.getSingleScanResults(); + if (cachedScanResults == null || cachedScanResults.isEmpty()) return new ScanResult[0]; + long currentTimeInMillis = mClock.getElapsedSinceBootMillis(); + return cachedScanResults.stream() + .filter(scanResult + -> ((currentTimeInMillis - (scanResult.timestamp / 1000)) + < CACHED_SCAN_RESULTS_MAX_AGE_IN_MILLIS)) + .toArray(ScanResult[]::new); + } + + /** * Clean up least recently used Access Points if specified app reach the limit. */ private static void cleanUpLRUAccessPoints(Set<AccessPoint> approvedAccessPoints) { |