From 319e63384280654615e7e7d6fcc961b7fcd135e0 Mon Sep 17 00:00:00 2001 From: Nate Jiang Date: Tue, 6 Aug 2019 17:15:27 -0700 Subject: [NetworkSuggestion] add hidden network from network suggestion Add hidden network from network suggestion to the scan list, make it can be auto connected and appear in the scan result. Bug: 138975620 Test: atest android.net.wifi Test: atest com.android.server.wifi Test: acts WifiNetworkSuggestionTest Merged-In: Ib053b7b33ed01e7da2cff888b0f720f9d6cdb528 Change-Id: Ib4bc9c51ee6e28471aee34fb7737f3659152c7d3 --- .../com/android/server/wifi/ScanRequestProxy.java | 9 +++-- .../com/android/server/wifi/WifiConfigManager.java | 17 +++------- .../server/wifi/WifiConnectivityManager.java | 9 +++-- .../server/wifi/WifiNetworkSuggestionsManager.java | 28 ++++++++++++++++ .../android/server/wifi/ScanRequestProxyTest.java | 38 +++++++++++++++------ .../server/wifi/WifiConnectivityManagerTest.java | 5 +++ .../wifi/WifiNetworkSuggestionsManagerTest.java | 39 ++++++++++++++++++++++ 7 files changed, 117 insertions(+), 28 deletions(-) diff --git a/service/java/com/android/server/wifi/ScanRequestProxy.java b/service/java/com/android/server/wifi/ScanRequestProxy.java index efbb7b649..a4678440b 100644 --- a/service/java/com/android/server/wifi/ScanRequestProxy.java +++ b/service/java/com/android/server/wifi/ScanRequestProxy.java @@ -484,11 +484,14 @@ public class ScanRequestProxy { settings.reportEvents = WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN | WifiScanner.REPORT_EVENT_FULL_SCAN_RESULT; if (mScanningForHiddenNetworksEnabled) { - // retrieve the list of hidden network SSIDs to scan for, if enabled. + // retrieve the list of hidden network SSIDs from saved network to scan for, if enabled. List hiddenNetworkList = - mWifiConfigManager.retrieveHiddenNetworkList(); + new ArrayList<>(mWifiConfigManager.retrieveHiddenNetworkList()); + // retrieve the list of hidden network SSIDs from Network suggestion to scan for. + hiddenNetworkList.addAll( + mWifiInjector.getWifiNetworkSuggestionsManager().retrieveHiddenNetworkList()); settings.hiddenNetworks = hiddenNetworkList.toArray( - new WifiScanner.ScanSettings.HiddenNetwork[hiddenNetworkList.size()]); + new WifiScanner.ScanSettings.HiddenNetwork[0]); } mWifiScanner.startScan(settings, new ScanRequestProxyScanListener(), workSource); return true; diff --git a/service/java/com/android/server/wifi/WifiConfigManager.java b/service/java/com/android/server/wifi/WifiConfigManager.java index bda1eb7d2..aa59f251b 100644 --- a/service/java/com/android/server/wifi/WifiConfigManager.java +++ b/service/java/com/android/server/wifi/WifiConfigManager.java @@ -2685,7 +2685,7 @@ public class WifiConfigManager { } /** - * Retrieves a list of all the saved hidden networks for scans. + * Retrieves a list of all the saved hidden networks for scans * * Hidden network list sent to the firmware has limited size. If there are a lot of saved * networks, this list will be truncated and we might end up not sending the networks @@ -2698,19 +2698,12 @@ public class WifiConfigManager { public List retrieveHiddenNetworkList() { List hiddenList = new ArrayList<>(); List networks = new ArrayList<>(getInternalConfiguredNetworks()); - // Remove any permanently disabled networks or non hidden networks. - Iterator iter = networks.iterator(); - while (iter.hasNext()) { - WifiConfiguration config = iter.next(); - if (!config.hiddenSSID) { - iter.remove(); - } - } - Collections.sort(networks, sScanListComparator); + // Remove any non hidden networks. + networks.removeIf(config -> !config.hiddenSSID); + networks.sort(sScanListComparator); // The most frequently connected network has the highest priority now. for (WifiConfiguration config : networks) { - hiddenList.add( - new WifiScanner.ScanSettings.HiddenNetwork(config.SSID)); + hiddenList.add(new WifiScanner.ScanSettings.HiddenNetwork(config.SSID)); } return hiddenList; } diff --git a/service/java/com/android/server/wifi/WifiConnectivityManager.java b/service/java/com/android/server/wifi/WifiConnectivityManager.java index 7411422e0..2e4b5c891 100644 --- a/service/java/com/android/server/wifi/WifiConnectivityManager.java +++ b/service/java/com/android/server/wifi/WifiConnectivityManager.java @@ -916,11 +916,14 @@ public class WifiConnectivityManager { settings.reportEvents = WifiScanner.REPORT_EVENT_FULL_SCAN_RESULT | WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN; settings.numBssidsPerScan = 0; - + // retrieve the list of hidden network SSIDs from saved network to scan for List hiddenNetworkList = - mConfigManager.retrieveHiddenNetworkList(); + new ArrayList<>(mConfigManager.retrieveHiddenNetworkList()); + // retrieve the list of hidden network SSIDs from Network suggestion to scan for + hiddenNetworkList.addAll( + mWifiInjector.getWifiNetworkSuggestionsManager().retrieveHiddenNetworkList()); settings.hiddenNetworks = - hiddenNetworkList.toArray(new ScanSettings.HiddenNetwork[hiddenNetworkList.size()]); + hiddenNetworkList.toArray(new ScanSettings.HiddenNetwork[0]); SingleScanListener singleScanListener = new SingleScanListener(isFullBandScan); diff --git a/service/java/com/android/server/wifi/WifiNetworkSuggestionsManager.java b/service/java/com/android/server/wifi/WifiNetworkSuggestionsManager.java index 5ed0b7bdc..c30d78a08 100644 --- a/service/java/com/android/server/wifi/WifiNetworkSuggestionsManager.java +++ b/service/java/com/android/server/wifi/WifiNetworkSuggestionsManager.java @@ -37,6 +37,7 @@ import android.net.wifi.ScanResult; import android.net.wifi.WifiConfiguration; import android.net.wifi.WifiManager; import android.net.wifi.WifiNetworkSuggestion; +import android.net.wifi.WifiScanner; import android.os.Handler; import android.os.UserHandle; import android.text.TextUtils; @@ -51,6 +52,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.Collections; import java.util.HashMap; @@ -90,6 +92,10 @@ public class WifiNetworkSuggestionsManager { @VisibleForTesting public static final String EXTRA_UID = "com.android.server.wifi.extra.NetworkSuggestion.UID"; + /** + * Limit number of hidden networks attach to scan + */ + private static final int NUMBER_OF_HIDDEN_NETWORK_FOR_ONE_SCAN = 100; private final Context mContext; private final Resources mResources; @@ -921,6 +927,28 @@ public class WifiNetworkSuggestionsManager { return approvedExtNetworkSuggestions; } + /** + * Get hidden network from active network suggestions. + * Todo(): Now limit by a fixed number, maybe we can try rotation? + * @return set of WifiConfigurations + */ + public List retrieveHiddenNetworkList() { + List hiddenNetworks = new ArrayList<>(); + for (PerAppInfo appInfo : mActiveNetworkSuggestionsPerApp.values()) { + if (!appInfo.hasUserApproved) continue; + for (ExtendedWifiNetworkSuggestion ewns : appInfo.extNetworkSuggestions) { + if (!ewns.wns.wifiConfiguration.hiddenSSID) continue; + hiddenNetworks.add( + new WifiScanner.ScanSettings.HiddenNetwork( + ewns.wns.wifiConfiguration.SSID)); + if (hiddenNetworks.size() >= NUMBER_OF_HIDDEN_NETWORK_FOR_ONE_SCAN) { + return hiddenNetworks; + } + } + } + return hiddenNetworks; + } + /** * Helper method to send the post connection broadcast to specified package. */ diff --git a/tests/wifitests/src/com/android/server/wifi/ScanRequestProxyTest.java b/tests/wifitests/src/com/android/server/wifi/ScanRequestProxyTest.java index 985789858..38e2eaf86 100644 --- a/tests/wifitests/src/com/android/server/wifi/ScanRequestProxyTest.java +++ b/tests/wifitests/src/com/android/server/wifi/ScanRequestProxyTest.java @@ -66,6 +66,11 @@ public class ScanRequestProxyTest { add(new WifiScanner.ScanSettings.HiddenNetwork("test_ssid_2")); }}; + private static final List TEST_HIDDEN_NETWORKS_LIST_NS = + new ArrayList() {{ + add(new WifiScanner.ScanSettings.HiddenNetwork("test_ssid_3")); + add(new WifiScanner.ScanSettings.HiddenNetwork("test_ssid_4")); + }}; @Mock private Context mContext; @Mock private AppOpsManager mAppOps; @@ -77,6 +82,8 @@ public class ScanRequestProxyTest { @Mock private WifiMetrics mWifiMetrics; @Mock private Clock mClock; @Mock private FrameworkFacade mFrameworkFacade; + @Mock private WifiNetworkSuggestionsManager mWifiNetworkSuggestionsManager; + private ArgumentCaptor mWorkSourceArgumentCaptor = ArgumentCaptor.forClass(WorkSource.class); private ArgumentCaptor mScanSettingsArgumentCaptor = @@ -98,7 +105,11 @@ public class ScanRequestProxyTest { MockitoAnnotations.initMocks(this); when(mWifiInjector.getWifiScanner()).thenReturn(mWifiScanner); + when(mWifiInjector.getWifiNetworkSuggestionsManager()) + .thenReturn(mWifiNetworkSuggestionsManager); when(mWifiConfigManager.retrieveHiddenNetworkList()).thenReturn(TEST_HIDDEN_NETWORKS_LIST); + when(mWifiNetworkSuggestionsManager.retrieveHiddenNetworkList()) + .thenReturn(TEST_HIDDEN_NETWORKS_LIST_NS); doNothing().when(mWifiScanner).registerScanListener( mGlobalScanListenerArgumentCaptor.capture()); doNothing().when(mWifiScanner).startScan( @@ -106,7 +117,8 @@ public class ScanRequestProxyTest { mScanRequestListenerArgumentCaptor.capture(), mWorkSourceArgumentCaptor.capture()); - mInOrder = inOrder(mWifiScanner, mWifiConfigManager, mContext); + mInOrder = inOrder(mWifiScanner, mWifiConfigManager, + mContext, mWifiNetworkSuggestionsManager); mTestScanDatas1 = ScanTestUtil.createScanDatas(new int[][]{{ 2417, 2427, 5180, 5170 }}, new int[]{0}, @@ -205,8 +217,8 @@ public class ScanRequestProxyTest { mInOrder.verify(mWifiScanner).registerScanListener(any()); mInOrder.verify(mWifiScanner).startScan(any(), any(), any()); - assertTrue(mWorkSourceArgumentCaptor.getValue().equals( - new WorkSource(TEST_UID, TEST_PACKAGE_NAME_1))); + assertEquals(mWorkSourceArgumentCaptor.getValue(), + new WorkSource(TEST_UID, TEST_PACKAGE_NAME_1)); validateScanSettings(mScanSettingsArgumentCaptor.getValue(), false, true); } @@ -222,10 +234,11 @@ public class ScanRequestProxyTest { assertTrue(mScanRequestProxy.startScan(TEST_UID, TEST_PACKAGE_NAME_1)); mInOrder.verify(mWifiConfigManager, never()).retrieveHiddenNetworkList(); + mInOrder.verify(mWifiNetworkSuggestionsManager, never()).retrieveHiddenNetworkList(); mInOrder.verify(mWifiScanner).startScan(any(), any(), any()); - assertTrue(mWorkSourceArgumentCaptor.getValue().equals( - new WorkSource(TEST_UID, TEST_PACKAGE_NAME_1))); + assertEquals(mWorkSourceArgumentCaptor.getValue(), + new WorkSource(TEST_UID, TEST_PACKAGE_NAME_1)); validateScanSettings(mScanSettingsArgumentCaptor.getValue(), false); verify(mWifiMetrics).incrementExternalAppOneshotScanRequestsCount(); @@ -242,11 +255,13 @@ public class ScanRequestProxyTest { validateScanAvailableBroadcastSent(true); assertTrue(mScanRequestProxy.startScan(TEST_UID, TEST_PACKAGE_NAME_1)); + mInOrder.verify(mWifiConfigManager).retrieveHiddenNetworkList(); + mInOrder.verify(mWifiNetworkSuggestionsManager).retrieveHiddenNetworkList(); mInOrder.verify(mWifiScanner).startScan(any(), any(), any()); - assertTrue(mWorkSourceArgumentCaptor.getValue().equals( - new WorkSource(TEST_UID, TEST_PACKAGE_NAME_1))); + assertEquals(mWorkSourceArgumentCaptor.getValue(), + new WorkSource(TEST_UID, TEST_PACKAGE_NAME_1)); validateScanSettings(mScanSettingsArgumentCaptor.getValue(), true); verify(mWifiMetrics).incrementExternalAppOneshotScanRequestsCount(); @@ -860,12 +875,15 @@ public class ScanRequestProxyTest { } assertEquals(WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN | WifiScanner.REPORT_EVENT_FULL_SCAN_RESULT, scanSettings.reportEvents); + List hiddenNetworkList = + new ArrayList<>(); + hiddenNetworkList.addAll(TEST_HIDDEN_NETWORKS_LIST); + hiddenNetworkList.addAll(TEST_HIDDEN_NETWORKS_LIST_NS); if (expectHiddenNetworks) { assertNotNull(scanSettings.hiddenNetworks); - assertEquals(TEST_HIDDEN_NETWORKS_LIST.size(), scanSettings.hiddenNetworks.length); + assertEquals(hiddenNetworkList.size(), scanSettings.hiddenNetworks.length); for (int i = 0; i < scanSettings.hiddenNetworks.length; i++) { - validateHiddenNetworkInList(scanSettings.hiddenNetworks[i], - TEST_HIDDEN_NETWORKS_LIST); + validateHiddenNetworkInList(scanSettings.hiddenNetworks[i], hiddenNetworkList); } } else { assertNull(scanSettings.hiddenNetworks); diff --git a/tests/wifitests/src/com/android/server/wifi/WifiConnectivityManagerTest.java b/tests/wifitests/src/com/android/server/wifi/WifiConnectivityManagerTest.java index 7f6c1bcaf..c1686b48d 100644 --- a/tests/wifitests/src/com/android/server/wifi/WifiConnectivityManagerTest.java +++ b/tests/wifitests/src/com/android/server/wifi/WifiConnectivityManagerTest.java @@ -96,6 +96,10 @@ public class WifiConnectivityManagerTest { mWifiConnectivityHelper = mockWifiConnectivityHelper(); mWifiNS = mockWifiNetworkSelector(); when(mWifiInjector.getWifiScanner()).thenReturn(mWifiScanner); + when(mWifiInjector.getWifiNetworkSuggestionsManager()) + .thenReturn(mWifiNetworkSuggestionsManager); + when(mWifiNetworkSuggestionsManager.retrieveHiddenNetworkList()) + .thenReturn(new ArrayList<>()); mWifiConnectivityManager = createConnectivityManager(); verify(mWifiConfigManager).setOnSavedNetworkUpdateListener(anyObject()); mWifiConnectivityManager.setTrustedConnectionAllowed(true); @@ -140,6 +144,7 @@ public class WifiConnectivityManagerTest { @Mock private CarrierNetworkConfig mCarrierNetworkConfig; @Mock private WifiMetrics mWifiMetrics; @Mock private WifiNetworkScoreCache mScoreCache; + @Mock private WifiNetworkSuggestionsManager mWifiNetworkSuggestionsManager; @Captor ArgumentCaptor mCandidateScanResultCaptor; @Captor ArgumentCaptor> mBssidBlacklistCaptor; @Captor ArgumentCaptor> mSsidWhitelistCaptor; diff --git a/tests/wifitests/src/com/android/server/wifi/WifiNetworkSuggestionsManagerTest.java b/tests/wifitests/src/com/android/server/wifi/WifiNetworkSuggestionsManagerTest.java index 97a183370..d0d792541 100644 --- a/tests/wifitests/src/com/android/server/wifi/WifiNetworkSuggestionsManagerTest.java +++ b/tests/wifitests/src/com/android/server/wifi/WifiNetworkSuggestionsManagerTest.java @@ -48,6 +48,7 @@ import android.net.MacAddress; import android.net.wifi.WifiConfiguration; import android.net.wifi.WifiManager; import android.net.wifi.WifiNetworkSuggestion; +import android.net.wifi.WifiScanner; import android.os.Handler; import android.os.UserHandle; import android.os.test.TestLooper; @@ -2008,6 +2009,44 @@ public class WifiNetworkSuggestionsManagerTest { verifyNoMoreInteractions(mNotificationManger); } + /** + * Verify get hidden networks from All user approve network suggestions + */ + @Test + public void testGetHiddenNetworks() { + + WifiNetworkSuggestion networkSuggestion = new WifiNetworkSuggestion( + WifiConfigurationTestUtil.createOpenNetwork(), true, false, TEST_UID_1, + TEST_PACKAGE_1); + WifiNetworkSuggestion hiddenNetworkSuggestion1 = new WifiNetworkSuggestion( + WifiConfigurationTestUtil.createPskHiddenNetwork(), true, false, TEST_UID_1, + TEST_PACKAGE_1); + WifiNetworkSuggestion hiddenNetworkSuggestion2 = new WifiNetworkSuggestion( + WifiConfigurationTestUtil.createPskHiddenNetwork(), true, false, TEST_UID_2, + TEST_PACKAGE_2); + List networkSuggestionList1 = + new ArrayList() {{ + add(networkSuggestion); + add(hiddenNetworkSuggestion1); + }}; + List networkSuggestionList2 = + new ArrayList() {{ + add(hiddenNetworkSuggestion2); + }}; + assertEquals(WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS, + mWifiNetworkSuggestionsManager.add(networkSuggestionList1, TEST_UID_1, + TEST_PACKAGE_1)); + assertEquals(WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS, + mWifiNetworkSuggestionsManager.add(networkSuggestionList2, TEST_UID_2, + TEST_PACKAGE_2)); + mWifiNetworkSuggestionsManager.setHasUserApprovedForApp(true, TEST_PACKAGE_1); + mWifiNetworkSuggestionsManager.setHasUserApprovedForApp(false, TEST_PACKAGE_2); + List hiddenNetworks = + mWifiNetworkSuggestionsManager.retrieveHiddenNetworkList(); + assertEquals(1, hiddenNetworks.size()); + assertEquals(hiddenNetworkSuggestion1.wifiConfiguration.SSID, hiddenNetworks.get(0).ssid); + } + /** * Creates a scan detail corresponding to the provided network values. */ -- cgit v1.2.3