summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorandroid-build-team Robot <android-build-team-robot@google.com>2020-09-09 23:05:41 +0000
committerandroid-build-team Robot <android-build-team-robot@google.com>2020-09-09 23:05:41 +0000
commitc006242c5f4156f479f395339012586d46288775 (patch)
tree642792a27a4a5bcb5cea48fafef86e52a064a2b0
parent94f943259578467bc1143e515f9ec190da714cca (diff)
parent3f749b85c6608dc23b9bfc4a6b8a0392587df7bc (diff)
Snap for 6823548 from 3f749b85c6608dc23b9bfc4a6b8a0392587df7bc to rvc-qpr1-release
Change-Id: I426cb5ac9d00e994b1a2475e30e62c2b7dd18748
-rw-r--r--service/java/com/android/server/wifi/ClientModeImpl.java3
-rw-r--r--service/java/com/android/server/wifi/WifiNetworkFactory.java59
-rw-r--r--service/java/com/android/server/wifi/WifiScoreReport.java78
-rw-r--r--tests/wifitests/src/com/android/server/wifi/WifiNetworkFactoryTest.java182
-rw-r--r--tests/wifitests/src/com/android/server/wifi/WifiScoreReportTest.java74
5 files changed, 364 insertions, 32 deletions
diff --git a/service/java/com/android/server/wifi/ClientModeImpl.java b/service/java/com/android/server/wifi/ClientModeImpl.java
index 9f4c41f83..e7371a9f1 100644
--- a/service/java/com/android/server/wifi/ClientModeImpl.java
+++ b/service/java/com/android/server/wifi/ClientModeImpl.java
@@ -812,7 +812,7 @@ public class ClientModeImpl extends StateMachine {
mWifiScoreReport = new WifiScoreReport(mWifiInjector.getScoringParams(), mClock,
mWifiMetrics, mWifiInfo, mWifiNative, mBssidBlocklistMonitor,
mWifiInjector.getWifiThreadRunner(), mWifiInjector.getDeviceConfigFacade(),
- mContext);
+ mContext, looper, mFacade);
mNetworkCapabilitiesFilter = new NetworkCapabilities.Builder()
.addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
@@ -3441,6 +3441,7 @@ public class ClientModeImpl extends StateMachine {
break;
case CMD_INITIALIZE:
mWifiNative.initialize();
+ mWifiScoreReport.initialize();
break;
case CMD_BOOT_COMPLETED:
// get other services that we need to manage
diff --git a/service/java/com/android/server/wifi/WifiNetworkFactory.java b/service/java/com/android/server/wifi/WifiNetworkFactory.java
index 9dc89addc..d1f9fbb1f 100644
--- a/service/java/com/android/server/wifi/WifiNetworkFactory.java
+++ b/service/java/com/android/server/wifi/WifiNetworkFactory.java
@@ -65,6 +65,7 @@ import com.android.server.wifi.util.WifiPermissionsUtil;
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
@@ -74,6 +75,7 @@ import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
+import java.util.stream.Collectors;
/**
* Network factory to handle trusted wifi network requests.
@@ -128,20 +130,23 @@ public class WifiNetworkFactory extends NetworkFactory {
private WifiScanner mWifiScanner;
private CompanionDeviceManager mCompanionDeviceManager;
// Temporary approval set by shell commands.
- private String mApprovedApp = null;
+ @Nullable private String mApprovedApp = null;
private int mGenericConnectionReqCount = 0;
// Request that is being actively processed. All new requests start out as an "active" request
// because we're processing it & handling all the user interactions associated with it. Once we
// successfully connect to the network, we transition that request to "connected".
- private NetworkRequest mActiveSpecificNetworkRequest;
- private WifiNetworkSpecifier mActiveSpecificNetworkRequestSpecifier;
+ @Nullable private NetworkRequest mActiveSpecificNetworkRequest;
+ @Nullable private WifiNetworkSpecifier mActiveSpecificNetworkRequestSpecifier;
// Request corresponding to the the network that the device is currently connected to.
- private NetworkRequest mConnectedSpecificNetworkRequest;
- private WifiNetworkSpecifier mConnectedSpecificNetworkRequestSpecifier;
- private WifiConfiguration mUserSelectedNetwork;
+ @Nullable private NetworkRequest mConnectedSpecificNetworkRequest;
+ @Nullable private WifiNetworkSpecifier mConnectedSpecificNetworkRequestSpecifier;
+ @Nullable private WifiConfiguration mUserSelectedNetwork;
private int mUserSelectedNetworkConnectRetryCount;
- private List<ScanResult> mActiveMatchedScanResults;
+ // Map of bssid to latest scan results for all scan results matching a request. Will be
+ // - null, if there are no active requests.
+ // - empty, if there are no matching scan results received for the active request.
+ @Nullable private Map<String, ScanResult> mActiveMatchedScanResults;
// Verbose logging flag.
private boolean mVerboseLoggingEnabled = false;
private boolean mPeriodicScanTimerSet = false;
@@ -237,7 +242,10 @@ public class WifiNetworkFactory extends NetworkFactory {
Log.v(TAG, "Received " + scanResults.length + " scan results");
}
handleScanResults(scanResults);
- sendNetworkRequestMatchCallbacksForActiveRequest(mActiveMatchedScanResults);
+ if (mActiveMatchedScanResults != null) {
+ sendNetworkRequestMatchCallbacksForActiveRequest(
+ mActiveMatchedScanResults.values());
+ }
scheduleNextPeriodicScan();
}
@@ -432,7 +440,10 @@ public class WifiNetworkFactory extends NetworkFactory {
// If we are already in the midst of processing a request, send matching callbacks
// immediately on registering the callback.
- sendNetworkRequestMatchCallbacksForActiveRequest(mActiveMatchedScanResults);
+ if (mActiveMatchedScanResults != null) {
+ sendNetworkRequestMatchCallbacksForActiveRequest(
+ mActiveMatchedScanResults.values());
+ }
}
/**
@@ -610,8 +621,11 @@ public class WifiNetworkFactory extends NetworkFactory {
if (mVerboseLoggingEnabled) {
Log.v(TAG, "Using cached " + cachedScanResults.length + " scan results");
}
- handleScanResults(cachedScanResults);
- sendNetworkRequestMatchCallbacksForActiveRequest(mActiveMatchedScanResults);
+ handleScanResults(cachedScanResults);
+ if (mActiveMatchedScanResults != null) {
+ sendNetworkRequestMatchCallbacksForActiveRequest(
+ mActiveMatchedScanResults.values());
+ }
startPeriodicScans();
}
}
@@ -1163,8 +1177,8 @@ public class WifiNetworkFactory extends NetworkFactory {
}
private void sendNetworkRequestMatchCallbacksForActiveRequest(
- @Nullable List<ScanResult> matchedScanResults) {
- if (matchedScanResults == null || matchedScanResults.isEmpty()) return;
+ @NonNull Collection<ScanResult> matchedScanResults) {
+ if (matchedScanResults.isEmpty()) return;
if (mRegisteredCallbacks.getNumCallbacks() == 0) {
Log.e(TAG, "No callback registered for sending network request matches. "
+ "Ignoring...");
@@ -1172,7 +1186,7 @@ public class WifiNetworkFactory extends NetworkFactory {
}
for (INetworkRequestMatchCallback callback : mRegisteredCallbacks.getCallbacks()) {
try {
- callback.onMatch(matchedScanResults);
+ callback.onMatch(new ArrayList<>(matchedScanResults));
} catch (RemoteException e) {
Log.e(TAG, "Unable to invoke network request match callback " + callback, e);
}
@@ -1265,6 +1279,7 @@ public class WifiNetworkFactory extends NetworkFactory {
if (mActiveSpecificNetworkRequestSpecifier == null
|| mActiveMatchedScanResults == null) return null;
ScanResult selectedScanResult = mActiveMatchedScanResults
+ .values()
.stream()
.filter(scanResult -> Objects.equals(
ScanResultMatchInfo.fromScanResult(scanResult),
@@ -1354,7 +1369,7 @@ public class WifiNetworkFactory extends NetworkFactory {
ScanResultMatchInfo fromWifiConfiguration =
ScanResultMatchInfo.fromWifiConfiguration(network);
- for (ScanResult scanResult : mActiveMatchedScanResults) {
+ for (ScanResult scanResult : mActiveMatchedScanResults.values()) {
ScanResultMatchInfo fromScanResult = ScanResultMatchInfo.fromScanResult(scanResult);
if (fromScanResult.equals(fromWifiConfiguration)) {
AccessPoint approvedAccessPoint =
@@ -1433,7 +1448,19 @@ public class WifiNetworkFactory extends NetworkFactory {
mWifiMetrics.incrementNetworkRequestApiMatchSizeHistogram(
matchedScanResults.size());
}
- mActiveMatchedScanResults = matchedScanResults;
+ // First set of scan results for this request.
+ if (mActiveMatchedScanResults == null) mActiveMatchedScanResults = new HashMap<>();
+ // Coalesce the new set of scan results with previous scan results received for request.
+ mActiveMatchedScanResults.putAll(matchedScanResults
+ .stream()
+ .collect(Collectors.toMap(
+ scanResult -> scanResult.BSSID, scanResult -> scanResult)));
+ // Weed out any stale cached scan results.
+ long currentTimeInMillis = mClock.getElapsedSinceBootMillis();
+ mActiveMatchedScanResults.entrySet().removeIf(
+ e -> ((currentTimeInMillis - (e.getValue().timestamp / 1000))
+ >= CACHED_SCAN_RESULTS_MAX_AGE_IN_MILLIS));
+
}
/**
diff --git a/service/java/com/android/server/wifi/WifiScoreReport.java b/service/java/com/android/server/wifi/WifiScoreReport.java
index 89f0445cb..381be7f2b 100644
--- a/service/java/com/android/server/wifi/WifiScoreReport.java
+++ b/service/java/com/android/server/wifi/WifiScoreReport.java
@@ -17,16 +17,22 @@
package com.android.server.wifi;
import android.content.Context;
+import android.database.ContentObserver;
import android.net.Network;
import android.net.NetworkAgent;
+import android.net.Uri;
import android.net.wifi.IScoreUpdateObserver;
import android.net.wifi.IWifiConnectedNetworkScorer;
import android.net.wifi.WifiInfo;
import android.net.wifi.nl80211.WifiNl80211Manager;
+import android.os.Handler;
import android.os.IBinder;
+import android.os.Looper;
import android.os.RemoteException;
+import android.provider.Settings;
import android.util.Log;
+import com.android.internal.annotations.VisibleForTesting;
import com.android.wifi.resources.R;
import java.io.FileDescriptor;
@@ -57,6 +63,15 @@ public class WifiScoreReport {
private static final long DURATION_TO_BLOCKLIST_BSSID_AFTER_FIRST_EXITING_MILLIS = 30000;
private static final long INVALID_WALL_CLOCK_MILLIS = -1;
+ /**
+ * Copy of the settings string. Can't directly use the constant because it is @hide.
+ * See {@link android.provider.Settings.Secure.ADAPTIVE_CONNECTIVITY_ENABLED}.
+ * TODO(b/167709538) remove this hardcoded string and create new API in Wifi mainline.
+ */
+ @VisibleForTesting
+ public static final String SETTINGS_SECURE_ADAPTIVE_CONNECTIVITY_ENABLED =
+ "adaptive_connectivity_enabled";
+
// Cache of the last score
private int mScore = ConnectedScore.WIFI_MAX_SCORE;
@@ -78,6 +93,8 @@ public class WifiScoreReport {
WifiNative mWifiNative;
WifiThreadRunner mWifiThreadRunner;
DeviceConfigFacade mDeviceConfigFacade;
+ Handler mHandler;
+ FrameworkFacade mFrameworkFacade;
/**
* Callback proxy. See {@link android.net.wifi.WifiManager.ScoreUpdateObserver}.
@@ -200,6 +217,10 @@ public class WifiScoreReport {
return;
}
}
+ // Stay a notch above the transition score if adaptive connectivity is disabled.
+ if (!mAdaptiveConnectivityEnabled) {
+ score = ConnectedScore.WIFI_TRANSITION_SCORE + 1;
+ }
mNetworkAgent.sendNetworkScore(score);
}
@@ -286,10 +307,50 @@ public class WifiScoreReport {
private WifiConnectedNetworkScorerHolder mWifiConnectedNetworkScorerHolder;
+ /**
+ * Observer for adaptive connectivity enable settings changes.
+ * This is enabled by default. Will be toggled off via adb command or a settings
+ * toggle by the user to disable adaptive connectivity.
+ */
+ private class AdaptiveConnectivityEnabledSettingObserver extends ContentObserver {
+ AdaptiveConnectivityEnabledSettingObserver(Handler handler) {
+ super(handler);
+ }
+
+ @Override
+ public void onChange(boolean selfChange) {
+ super.onChange(selfChange);
+ mAdaptiveConnectivityEnabled = getValue();
+ Log.d(TAG, "Adaptive connectivity status changed: " + mAdaptiveConnectivityEnabled);
+ }
+
+ /**
+ * Register settings change observer.
+ */
+ public void initialize() {
+ Uri uri = Settings.Secure.getUriFor(SETTINGS_SECURE_ADAPTIVE_CONNECTIVITY_ENABLED);
+ if (uri == null) {
+ Log.e(TAG, "Adaptive connectivity user toggle does not exist in Settings");
+ return;
+ }
+ mFrameworkFacade.registerContentObserver(mContext, uri, true, this);
+ mAdaptiveConnectivityEnabled = mAdaptiveConnectivityEnabledSettingObserver.getValue();
+ }
+
+ public boolean getValue() {
+ return mFrameworkFacade.getIntegerSetting(
+ mContext, SETTINGS_SECURE_ADAPTIVE_CONNECTIVITY_ENABLED, 1) == 1;
+ }
+ }
+
+ private final AdaptiveConnectivityEnabledSettingObserver
+ mAdaptiveConnectivityEnabledSettingObserver;
+ private boolean mAdaptiveConnectivityEnabled = true;
+
WifiScoreReport(ScoringParams scoringParams, Clock clock, WifiMetrics wifiMetrics,
WifiInfo wifiInfo, WifiNative wifiNative, BssidBlocklistMonitor bssidBlocklistMonitor,
WifiThreadRunner wifiThreadRunner, DeviceConfigFacade deviceConfigFacade,
- Context context) {
+ Context context, Looper looper, FrameworkFacade frameworkFacade) {
mScoringParams = scoringParams;
mClock = clock;
mAggressiveConnectedScore = new AggressiveConnectedScore(scoringParams, clock);
@@ -301,6 +362,10 @@ public class WifiScoreReport {
mWifiThreadRunner = wifiThreadRunner;
mDeviceConfigFacade = deviceConfigFacade;
mContext = context;
+ mFrameworkFacade = frameworkFacade;
+ mHandler = new Handler(looper);
+ mAdaptiveConnectivityEnabledSettingObserver =
+ new AdaptiveConnectivityEnabledSettingObserver(mHandler);
}
/**
@@ -463,6 +528,10 @@ public class WifiScoreReport {
* @return true to indicate that an IP reachability check is recommended
*/
public boolean shouldCheckIpLayer() {
+ // Don't recommend if adaptive connectivity is disabled.
+ if (!mAdaptiveConnectivityEnabled) {
+ return false;
+ }
int nud = mScoringParams.getNudKnob();
if (nud == 0) {
return false;
@@ -703,4 +772,11 @@ public class WifiScoreReport {
mWifiConnectedNetworkScorerHolder = null;
mWifiMetrics.setIsExternalWifiScorerOn(false);
}
+
+ /**
+ * Initialize WifiScoreReport
+ */
+ public void initialize() {
+ mAdaptiveConnectivityEnabledSettingObserver.initialize();
+ }
}
diff --git a/tests/wifitests/src/com/android/server/wifi/WifiNetworkFactoryTest.java b/tests/wifitests/src/com/android/server/wifi/WifiNetworkFactoryTest.java
index 5f9e0333e..f6621a698 100644
--- a/tests/wifitests/src/com/android/server/wifi/WifiNetworkFactoryTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/WifiNetworkFactoryTest.java
@@ -52,6 +52,7 @@ import android.net.wifi.WifiNetworkSpecifier;
import android.net.wifi.WifiScanner;
import android.net.wifi.WifiScanner.ScanListener;
import android.net.wifi.WifiScanner.ScanSettings;
+import android.net.wifi.WifiSsid;
import android.os.Binder;
import android.os.IBinder;
import android.os.Message;
@@ -1122,9 +1123,7 @@ public class WifiNetworkFactoryTest extends WifiBaseTest {
verify(mWifiMetrics).setNominatorForNetwork(anyInt(),
eq(WifiMetricsProto.ConnectionEvent.NOMINATOR_SPECIFIER));
- verify(mClientModeImpl).disconnectCommand();
- verify(mClientModeImpl).connect(eq(null), eq(TEST_NETWORK_ID_1), any(Binder.class),
- mConnectListenerArgumentCaptor.capture(), anyInt(), anyInt());
+
}
/**
@@ -1333,6 +1332,134 @@ public class WifiNetworkFactoryTest extends WifiBaseTest {
}
/**
+ * Verify handling of user selection to trigger connection to a network when the selected bssid
+ * is no longer seen in scan results within the cache expiry duration. Ensure we fill up the
+ * BSSID field.
+ */
+ @Test
+ public void
+ testNetworkSpecifierHandleUserSelectionConnectToNetworkMissingBssidInLatest()
+ throws Exception {
+ WifiScanner.ScanData[] scanDatas1 =
+ ScanTestUtil.createScanDatas(new int[][]{ { 2417, 2427, 5180, 5170 }});
+ setupScanData(scanDatas1, SCAN_RESULT_TYPE_WPA_PSK,
+ TEST_SSID_1, TEST_SSID_2, TEST_SSID_3, TEST_SSID_4);
+ // Modify the next set of scan results to simulate missing |TEST_SSID_1| ScanResult.
+ WifiScanner.ScanData[] scanDatas2 =
+ ScanTestUtil.createScanDatas(new int[][]{ { 2417, 2427, 5180, 5170 }});
+ setupScanData(scanDatas2, SCAN_RESULT_TYPE_WPA_PSK,
+ TEST_SSID_2, TEST_SSID_2, TEST_SSID_3, TEST_SSID_4);
+
+ // Make a specific AP request.
+ ScanResult matchingScanResult = scanDatas1[0].getResults()[0];
+ PatternMatcher ssidPatternMatch =
+ new PatternMatcher(TEST_SSID_1, PatternMatcher.PATTERN_LITERAL);
+ Pair<MacAddress, MacAddress> bssidPatternMatch =
+ Pair.create(MacAddress.fromString(matchingScanResult.BSSID),
+ MacAddress.BROADCAST_ADDRESS);
+ WifiConfiguration wifiConfiguration = new WifiConfiguration();
+ wifiConfiguration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
+ wifiConfiguration.preSharedKey = TEST_WPA_PRESHARED_KEY;
+ attachWifiNetworkSpecifierAndAppInfo(
+ ssidPatternMatch, bssidPatternMatch, wifiConfiguration, TEST_UID_1,
+ TEST_PACKAGE_NAME_1);
+ mWifiNetworkFactory.needNetworkFor(mNetworkRequest, 0);
+ mWifiNetworkFactory.addCallback(mAppBinder, mNetworkRequestMatchCallback,
+ TEST_CALLBACK_IDENTIFIER);
+ verify(mNetworkRequestMatchCallback).onUserSelectionCallbackRegistration(
+ mNetworkRequestUserSelectionCallback.capture());
+ verifyPeriodicScans(
+ 0L,
+ new PeriodicScanParams(0, scanDatas1),
+ new PeriodicScanParams(PERIODIC_SCAN_INTERVAL_MS, scanDatas2));
+
+ // Now trigger user selection to the network.
+ mSelectedNetwork = ScanResultUtil.createNetworkFromScanResult(matchingScanResult);
+ mSelectedNetwork.SSID = "\"" + matchingScanResult.SSID + "\"";
+ INetworkRequestUserSelectionCallback networkRequestUserSelectionCallback =
+ mNetworkRequestUserSelectionCallback.getValue();
+ assertNotNull(networkRequestUserSelectionCallback);
+ sendUserSelectionSelect(networkRequestUserSelectionCallback, mSelectedNetwork);
+ mLooper.dispatchAll();
+
+ // Verify WifiConfiguration params.
+ validateConnectParams(mSelectedNetwork.SSID, matchingScanResult.BSSID);
+ verify(mWifiMetrics).setNominatorForNetwork(anyInt(),
+ eq(WifiMetricsProto.ConnectionEvent.NOMINATOR_SPECIFIER));
+
+ verify(mClientModeImpl).disconnectCommand();
+ verify(mClientModeImpl).connect(eq(null), eq(TEST_NETWORK_ID_1), any(Binder.class),
+ mConnectListenerArgumentCaptor.capture(), anyInt(), anyInt());
+ }
+
+ /**
+ * Verify handling of user selection to trigger connection to a network when the selected bssid
+ * is no longer seen in scan results beyond the cache expiry duration. Ensure we don't fill up
+ * the BSSID field.
+ */
+ @Test
+ public void
+ testNetworkSpecifierHandleUserSelectionConnectToNetworkStaleMissingBssidInLatest()
+ throws Exception {
+ WifiScanner.ScanData[] scanDatas1 =
+ ScanTestUtil.createScanDatas(new int[][]{ { 2417, 2427, 5180, 5170 }});
+ setupScanData(scanDatas1, SCAN_RESULT_TYPE_WPA_PSK,
+ TEST_SSID_1, TEST_SSID_2, TEST_SSID_3, TEST_SSID_4);
+ // Modify the next set of scan results to simulate missing |TEST_SSID_1| ScanResult.
+ WifiScanner.ScanData[] scanDatas2 =
+ ScanTestUtil.createScanDatas(new int[][]{ { 2417, 2427, 5180, 5170 }});
+ setupScanData(scanDatas2, SCAN_RESULT_TYPE_WPA_PSK,
+ TEST_SSID_2, TEST_SSID_2, TEST_SSID_3, TEST_SSID_4);
+
+ // Make a specific AP request.
+ ScanResult matchingScanResult = scanDatas1[0].getResults()[0];
+ PatternMatcher ssidPatternMatch =
+ new PatternMatcher(TEST_SSID_1, PatternMatcher.PATTERN_LITERAL);
+ Pair<MacAddress, MacAddress> bssidPatternMatch =
+ Pair.create(MacAddress.fromString(matchingScanResult.BSSID),
+ MacAddress.BROADCAST_ADDRESS);
+ WifiConfiguration wifiConfiguration = new WifiConfiguration();
+ wifiConfiguration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
+ wifiConfiguration.preSharedKey = TEST_WPA_PRESHARED_KEY;
+ attachWifiNetworkSpecifierAndAppInfo(
+ ssidPatternMatch, bssidPatternMatch, wifiConfiguration, TEST_UID_1,
+ TEST_PACKAGE_NAME_1);
+ mWifiNetworkFactory.needNetworkFor(mNetworkRequest, 0);
+ mWifiNetworkFactory.addCallback(mAppBinder, mNetworkRequestMatchCallback,
+ TEST_CALLBACK_IDENTIFIER);
+ verify(mNetworkRequestMatchCallback).onUserSelectionCallbackRegistration(
+ mNetworkRequestUserSelectionCallback.capture());
+
+ long nowMs = WifiNetworkFactory.CACHED_SCAN_RESULTS_MAX_AGE_IN_MILLIS + 1;
+ scanDatas2[0].getResults()[0].timestamp = nowMs;
+ scanDatas2[0].getResults()[1].timestamp = nowMs;
+ scanDatas2[0].getResults()[2].timestamp = nowMs;
+ scanDatas2[0].getResults()[3].timestamp = nowMs;
+ verifyPeriodicScans(
+ nowMs,
+ new PeriodicScanParams(0, scanDatas1),
+ new PeriodicScanParams(PERIODIC_SCAN_INTERVAL_MS, scanDatas2));
+
+ // Now trigger user selection to the network.
+ mSelectedNetwork = ScanResultUtil.createNetworkFromScanResult(matchingScanResult);
+ mSelectedNetwork.SSID = "\"" + matchingScanResult.SSID + "\"";
+ INetworkRequestUserSelectionCallback networkRequestUserSelectionCallback =
+ mNetworkRequestUserSelectionCallback.getValue();
+ assertNotNull(networkRequestUserSelectionCallback);
+ sendUserSelectionSelect(networkRequestUserSelectionCallback, mSelectedNetwork);
+ mLooper.dispatchAll();
+
+ // Verify WifiConfiguration params.
+ validateConnectParams(mSelectedNetwork.SSID, null);
+ verify(mWifiMetrics).setNominatorForNetwork(anyInt(),
+ eq(WifiMetricsProto.ConnectionEvent.NOMINATOR_SPECIFIER));
+
+ verify(mClientModeImpl).disconnectCommand();
+ verify(mClientModeImpl).connect(eq(null), eq(TEST_NETWORK_ID_1), any(Binder.class),
+ mConnectListenerArgumentCaptor.capture(), anyInt(), anyInt());
+ }
+
+ /**
* Verify handling of user selection to reject the request.
*/
@Test
@@ -2669,13 +2796,33 @@ public class WifiNetworkFactoryTest extends WifiBaseTest {
verify(mNetworkRequestMatchCallback, atLeastOnce()).onMatch(anyList());
}
+ private void verifyPeriodicScans(long...expectedIntervalsInSeconds) {
+ PeriodicScanParams[] periodicScanParams =
+ new PeriodicScanParams[expectedIntervalsInSeconds.length];
+ for (int i = 0; i < expectedIntervalsInSeconds.length; i++) {
+ periodicScanParams[i] =
+ new PeriodicScanParams(expectedIntervalsInSeconds[i], mTestScanDatas);
+ }
+ verifyPeriodicScans(0L, periodicScanParams);
+ }
+
+ private static class PeriodicScanParams {
+ public final long expectedIntervalInSeconds;
+ public final WifiScanner.ScanData[] scanDatas;
+
+ PeriodicScanParams(long expectedIntervalInSeconds, WifiScanner.ScanData[] scanDatas) {
+ this.expectedIntervalInSeconds = expectedIntervalInSeconds;
+ this.scanDatas = scanDatas;
+ }
+ }
+
// Simulates the periodic scans performed to find a matching network.
// a) Start scan
// b) Scan results received.
// c) Set alarm for next scan at the expected interval.
// d) Alarm fires, go to step a) again and repeat.
- private void verifyPeriodicScans(long...expectedIntervalsInSeconds) {
- when(mClock.getElapsedSinceBootMillis()).thenReturn(0L);
+ private void verifyPeriodicScans(long nowMs, PeriodicScanParams... scanParams) {
+ when(mClock.getElapsedSinceBootMillis()).thenReturn(nowMs);
OnAlarmListener alarmListener = null;
ScanListener scanListener = null;
@@ -2685,9 +2832,9 @@ public class WifiNetworkFactoryTest extends WifiBaseTest {
// Before we start scans, ensure that we look at the latest cached scan results.
mInOrder.verify(mWifiScanner).getSingleScanResults();
- for (int i = 0; i < expectedIntervalsInSeconds.length - 1; i++) {
- long expectedCurrentIntervalInMs = expectedIntervalsInSeconds[i];
- long expectedNextIntervalInMs = expectedIntervalsInSeconds[i + 1];
+ for (int i = 0; i < scanParams.length - 1; i++) {
+ long expectedCurrentIntervalInMs = scanParams[i].expectedIntervalInSeconds;
+ long expectedNextIntervalInMs = scanParams[i + 1].expectedIntervalInSeconds;
// First scan is immediately fired, so need for the alarm to fire.
if (expectedCurrentIntervalInMs != 0) {
@@ -2700,10 +2847,10 @@ public class WifiNetworkFactoryTest extends WifiBaseTest {
assertNotNull(scanListener);
// Now trigger the scan results callback and verify the alarm set for the next scan.
- scanListener.onResults(mTestScanDatas);
+ scanListener.onResults(scanParams[i].scanDatas);
mInOrder.verify(mAlarmManager).set(eq(AlarmManager.ELAPSED_REALTIME_WAKEUP),
- eq(expectedNextIntervalInMs), any(),
+ eq(expectedNextIntervalInMs + nowMs), any(),
mPeriodicScanListenerArgumentCaptor.capture(), any());
alarmListener = mPeriodicScanListenerArgumentCaptor.getValue();
assertNotNull(alarmListener);
@@ -2770,30 +2917,39 @@ public class WifiNetworkFactoryTest extends WifiBaseTest {
return "";
}
- // Helper method to setup the scan data for verifying the matching algo.
private void setupScanData(int scanResultType, String ssid1, String ssid2, String ssid3,
String ssid4) {
+ setupScanData(mTestScanDatas, scanResultType, ssid1, ssid2, ssid3, ssid4);
+ }
+
+ // Helper method to setup the scan data for verifying the matching algo.
+ private void setupScanData(WifiScanner.ScanData[] testScanDatas, int scanResultType,
+ String ssid1, String ssid2, String ssid3, String ssid4) {
// 4 scan results,
- assertEquals(1, mTestScanDatas.length);
- ScanResult[] scanResults = mTestScanDatas[0].getResults();
+ assertEquals(1, testScanDatas.length);
+ ScanResult[] scanResults = testScanDatas[0].getResults();
assertEquals(4, scanResults.length);
String caps = getScanResultCapsForType(scanResultType);
// Scan results have increasing RSSI.
scanResults[0].SSID = ssid1;
+ scanResults[0].wifiSsid = WifiSsid.createFromAsciiEncoded(ssid1);
scanResults[0].BSSID = TEST_BSSID_1;
scanResults[0].capabilities = caps;
scanResults[0].level = -45;
scanResults[1].SSID = ssid2;
+ scanResults[1].wifiSsid = WifiSsid.createFromAsciiEncoded(ssid2);
scanResults[1].BSSID = TEST_BSSID_2;
scanResults[1].capabilities = caps;
scanResults[1].level = -35;
scanResults[2].SSID = ssid3;
+ scanResults[2].wifiSsid = WifiSsid.createFromAsciiEncoded(ssid3);
scanResults[2].BSSID = TEST_BSSID_3;
scanResults[2].capabilities = caps;
scanResults[2].level = -25;
scanResults[3].SSID = ssid4;
+ scanResults[3].wifiSsid = WifiSsid.createFromAsciiEncoded(ssid4);
scanResults[3].BSSID = TEST_BSSID_4;
scanResults[3].capabilities = caps;
scanResults[3].level = -15;
diff --git a/tests/wifitests/src/com/android/server/wifi/WifiScoreReportTest.java b/tests/wifitests/src/com/android/server/wifi/WifiScoreReportTest.java
index 82dbbe941..cf83fbee3 100644
--- a/tests/wifitests/src/com/android/server/wifi/WifiScoreReportTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/WifiScoreReportTest.java
@@ -22,6 +22,7 @@ import static org.junit.Assert.assertTrue;
import static org.mockito.AdditionalAnswers.answerVoid;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.anyInt;
import static org.mockito.Mockito.anyLong;
@@ -38,6 +39,7 @@ import static org.mockito.Mockito.when;
import android.content.Context;
import android.content.res.Resources;
+import android.database.ContentObserver;
import android.net.ConnectivityManager;
import android.net.LinkProperties;
import android.net.Network;
@@ -50,6 +52,7 @@ import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiInfo;
import android.os.Handler;
import android.os.IBinder;
+import android.os.Looper;
import android.os.RemoteException;
import android.os.test.TestLooper;
@@ -60,6 +63,7 @@ import com.android.wifi.resources.R;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
+import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
@@ -102,6 +106,8 @@ public class WifiScoreReportTest extends WifiBaseTest {
@Mock BssidBlocklistMonitor mBssidBlocklistMonitor;
@Mock Network mNetwork;
@Mock DeviceConfigFacade mDeviceConfigFacade;
+ @Mock Looper mWifiLooper;
+ @Mock FrameworkFacade mFrameworkFacade;
private TestLooper mLooper;
public class WifiConnectedNetworkScorerImpl extends IWifiConnectedNetworkScorer.Stub {
@@ -200,10 +206,14 @@ public class WifiScoreReportTest extends WifiBaseTest {
mClock = new FakeClock();
mScoringParams = new ScoringParams();
mWifiThreadRunner = new WifiThreadRunner(new Handler(mLooper.getLooper()));
+ when(mFrameworkFacade.getIntegerSetting(any(Context.class),
+ eq(WifiScoreReport.SETTINGS_SECURE_ADAPTIVE_CONNECTIVITY_ENABLED), eq(1)))
+ .thenReturn(1);
mWifiScoreReport = new WifiScoreReport(mScoringParams, mClock, mWifiMetrics, mWifiInfo,
mWifiNative, mBssidBlocklistMonitor, mWifiThreadRunner,
- mDeviceConfigFacade, mContext);
+ mDeviceConfigFacade, mContext, mWifiLooper, mFrameworkFacade);
mWifiScoreReport.setNetworkAgent(mNetworkAgent);
+ mWifiScoreReport.initialize();
when(mDeviceConfigFacade.getMinConfirmationDurationSendLowScoreMs()).thenReturn(
DeviceConfigFacade.DEFAULT_MIN_CONFIRMATION_DURATION_SEND_LOW_SCORE_MS);
when(mDeviceConfigFacade.getMinConfirmationDurationSendHighScoreMs()).thenReturn(
@@ -999,4 +1009,66 @@ public class WifiScoreReportTest extends WifiBaseTest {
mLooper.dispatchAll();
verify(mNetworkAgent).sendNetworkScore(53);
}
+
+ /**
+ * Verify NUD check is not recommended and the score of 51 is sent to connectivity service
+ * when adaptive connectivity is disabled for AOSP scorer.
+ */
+ @Test
+ public void verifyNudCheckAndScoreIfToggleOffForAospScorer() throws Exception {
+ mWifiInfo.setFrequency(5220);
+ mWifiInfo.setRssi(-85);
+ ArgumentCaptor<ContentObserver> observer = ArgumentCaptor.forClass(ContentObserver.class);
+ verify(mFrameworkFacade).registerContentObserver(
+ any(), any(), eq(true), observer.capture());
+ when(mFrameworkFacade.getIntegerSetting(any(Context.class),
+ eq(WifiScoreReport.SETTINGS_SECURE_ADAPTIVE_CONNECTIVITY_ENABLED), eq(1)))
+ .thenReturn(0);
+ observer.getValue().onChange(true);
+ mWifiScoreReport.calculateAndReportScore();
+ assertFalse(mWifiScoreReport.shouldCheckIpLayer());
+ verify(mNetworkAgent).sendNetworkScore(51);
+ }
+
+ /**
+ * Verify NUD check is not recommended and the score of 51 is sent to connectivity service
+ * when adaptive connectivity is disabled for external Wi-Fi scorer.
+ */
+ @Test
+ public void verifyNudCheckAndScoreIfToggleOffForExternalScorer() throws Exception {
+ WifiConnectedNetworkScorerImpl scorerImpl = new WifiConnectedNetworkScorerImpl();
+ // Register Client for verification.
+ mWifiScoreReport.setWifiConnectedNetworkScorer(mAppBinder, scorerImpl);
+ when(mNetwork.getNetId()).thenReturn(TEST_NETWORK_ID);
+ mWifiScoreReport.startConnectedNetworkScorer(TEST_NETWORK_ID);
+ mClock.mStepMillis = 0;
+ when(mContext.getResources().getBoolean(
+ R.bool.config_wifiMinConfirmationDurationSendNetworkScoreEnabled)).thenReturn(true);
+ when(mDeviceConfigFacade.getMinConfirmationDurationSendHighScoreMs()).thenReturn(4000);
+
+ ArgumentCaptor<ContentObserver> observer = ArgumentCaptor.forClass(ContentObserver.class);
+ verify(mFrameworkFacade).registerContentObserver(
+ any(), any(), eq(true), observer.capture());
+ when(mFrameworkFacade.getIntegerSetting(any(Context.class),
+ eq(WifiScoreReport.SETTINGS_SECURE_ADAPTIVE_CONNECTIVITY_ENABLED), eq(1)))
+ .thenReturn(0);
+ observer.getValue().onChange(true);
+
+ mClock.mWallClockMillis = 10;
+ scorerImpl.mScoreUpdateObserver.notifyScoreUpdate(scorerImpl.mSessionId, 49);
+ mLooper.dispatchAll();
+ verify(mNetworkAgent, never()).sendNetworkScore(anyInt());
+ assertFalse(mWifiScoreReport.shouldCheckIpLayer());
+
+ mClock.mWallClockMillis = 10
+ + mDeviceConfigFacade.DEFAULT_MIN_CONFIRMATION_DURATION_SEND_LOW_SCORE_MS - 1;
+ scorerImpl.mScoreUpdateObserver.notifyScoreUpdate(scorerImpl.mSessionId, 48);
+ mLooper.dispatchAll();
+ verify(mNetworkAgent, never()).sendNetworkScore(anyInt());
+ mClock.mWallClockMillis = 10
+ + mDeviceConfigFacade.DEFAULT_MIN_CONFIRMATION_DURATION_SEND_LOW_SCORE_MS;
+ scorerImpl.mScoreUpdateObserver.notifyScoreUpdate(scorerImpl.mSessionId, 47);
+ mLooper.dispatchAll();
+ verify(mNetworkAgent).sendNetworkScore(51);
+ }
}