diff options
4 files changed, 255 insertions, 134 deletions
diff --git a/service/java/com/android/server/wifi/WifiConfigStore.java b/service/java/com/android/server/wifi/WifiConfigStore.java index 834de6fd7..2a0a14a25 100644 --- a/service/java/com/android/server/wifi/WifiConfigStore.java +++ b/service/java/com/android/server/wifi/WifiConfigStore.java @@ -511,12 +511,6 @@ public class WifiConfigStore extends IpConfigStore { private long mLastSelectedTimeStamp = WifiConfiguration.NetworkSelectionStatus.INVALID_NETWORK_SELECTION_DISABLE_TIMESTAMP; - /** - * Cached PNO list, it is updated when WifiConfiguration changes due to user input. - */ - ArrayList<WifiNative.WifiPnoNetwork> mCachedPnoList - = new ArrayList<WifiNative.WifiPnoNetwork>(); - /* * BSSID blacklist, i.e. list of BSSID we want to avoid */ @@ -1043,7 +1037,6 @@ public class WifiConfigStore extends IpConfigStore { if (updatePriorities) { config.priority = ++mLastPriority; setNetworkPriorityNative(config.networkId, config.priority); - buildPnoList(); } if (config.isPasspoint()) { @@ -1382,78 +1375,85 @@ public class WifiConfigStore extends IpConfigStore { } /** - * Get the Wifi PNO list - * - * @return list of WifiNative.WifiPnoNetwork + * General PnoNetwork list sorting algorithm: + * 1, Place the fully enabled networks first. Among the fully enabled networks, + * sort them in the oder determined by the return of |compareConfigurations| method + * implementation. + * 2. Next place all the temporarily disabled networks. Among the temporarily disabled + * networks, sort them in the order determined by the return of |compareConfigurations| method + * implementation. + * 3. Place the permanently disabled networks last. The order among permanently disabled + * networks doesn't matter. */ - private void buildPnoList() { - mCachedPnoList = new ArrayList<WifiNative.WifiPnoNetwork>(); - - ArrayList<WifiConfiguration> sortedWifiConfigurations - = new ArrayList<WifiConfiguration>(getConfiguredNetworks()); - Log.e(TAG, "buildPnoList sortedWifiConfigurations size " + sortedWifiConfigurations.size()); - if (sortedWifiConfigurations.size() != 0) { - // Sort by descending priority - Collections.sort(sortedWifiConfigurations, new Comparator<WifiConfiguration>() { - public int compare(WifiConfiguration a, WifiConfiguration b) { - return a.priority - b.priority; - } - }); + private static class PnoListComparator implements Comparator<WifiConfiguration> { + + public final int ENABLED_NETWORK_SCORE = 3; + public final int TEMPORARY_DISABLED_NETWORK_SCORE = 2; + public final int PERMANENTLY_DISABLED_NETWORK_SCORE = 1; + + @Override + public int compare(WifiConfiguration a, WifiConfiguration b) { + int configAScore = getPnoNetworkSortScore(a); + int configBScore = getPnoNetworkSortScore(b); + if (configAScore == configBScore) { + return compareConfigurations(a, b); + } else { + return Integer.compare(configBScore, configAScore); + } } - for (WifiConfiguration config : sortedWifiConfigurations) { - // Initialize the RSSI threshold with sane value: - // Use the 2.4GHz threshold since most WifiConfigurations are dual bands - // There is very little penalty with triggering too soon, i.e. if PNO finds a network - // that has an RSSI too low for us to attempt joining it. - int threshold = thresholdMinimumRssi24.get(); - Log.e(TAG, "found sortedWifiConfigurations : " + config.configKey()); - WifiNative.WifiPnoNetwork network = new WifiNative.WifiPnoNetwork(config, threshold); - mCachedPnoList.add(network); + // This needs to be implemented by the connected/disconnected PNO list comparator. + public int compareConfigurations(WifiConfiguration a, WifiConfiguration b) { + return 0; } - } + /** + * Returns an integer representing a score for each configuration. The scores are assigned + * based on the status of the configuration. The scores are assigned according to the order: + * Fully enabled network > Temporarily disabled network > Permanently disabled network. + */ + private int getPnoNetworkSortScore(WifiConfiguration config) { + if (config.getNetworkSelectionStatus().isNetworkEnabled()) { + return ENABLED_NETWORK_SCORE; + } else if (config.getNetworkSelectionStatus().isNetworkTemporaryDisabled()) { + return TEMPORARY_DISABLED_NETWORK_SCORE; + } else { + return PERMANENTLY_DISABLED_NETWORK_SCORE; + } + } + } /** - * PnoNetwork list sorting algorithm: - * 1, Place the fully enabled networks first. Among the fully enabled networks, - * sort them in descending order of their |numAssociation| values. If networks have - * the same |numAssociation|, then sort them in descending order of their |priority| + * Disconnected PnoNetwork list sorting algorithm: + * Place the configurations in descending order of their |numAssociation| values. If networks + * have the same |numAssociation|, then sort them in descending order of their |priority| * values. - * 2. Next place all the temporarily disabled networks. Among the temporarily disabled - * networks, sort them in the same order as the fully enabled networks. - * 3. Place the permanently disabled networks last. The order among permanently disabled - * networks doesn't matter. */ - private static final Comparator<WifiConfiguration> sPnoListSortComparator = - new Comparator<WifiConfiguration>() { - public int compare(WifiConfiguration a, WifiConfiguration b) { - boolean isConfigAEnabled = a.getNetworkSelectionStatus().isNetworkEnabled(); - boolean isConfigBEnabled = b.getNetworkSelectionStatus().isNetworkEnabled(); - boolean isConfigATempDisabled = - a.getNetworkSelectionStatus().isNetworkTemporaryDisabled(); - boolean isConfigBTempDisabled = - b.getNetworkSelectionStatus().isNetworkTemporaryDisabled(); - if ((isConfigAEnabled && isConfigBEnabled) - || (isConfigATempDisabled && isConfigBTempDisabled)) { - // If 2 networks have the same saved |numAssociation| value, sort them - // according to their priority. - if (a.numAssociation != b.numAssociation) { - return Long.compare(b.numAssociation, a.numAssociation); - } else { - return Integer.compare(b.priority, a.priority); - } - } else if (isConfigAEnabled != isConfigBEnabled) { - return Boolean.compare(isConfigBEnabled, isConfigAEnabled); + private static final PnoListComparator sDisconnectedPnoListComparator = + new PnoListComparator() { + @Override + public int compareConfigurations(WifiConfiguration a, WifiConfiguration b) { + if (a.numAssociation != b.numAssociation) { + return Long.compare(b.numAssociation, a.numAssociation); } else { - return Boolean.compare(isConfigBTempDisabled, isConfigATempDisabled); + return Integer.compare(b.priority, a.priority); } } }; /** * Retrieves an updated list of priorities for all the saved networks before - * enabling/disabling PNO. + * enabling disconnected PNO (wpa_supplicant based PNO). + * + * @return list of networks with updated priorities. + */ + public ArrayList<WifiNative.WifiPnoNetwork> retrieveDisconnectedWifiPnoNetworkList() { + return retrieveWifiPnoNetworkList(true, sDisconnectedPnoListComparator); + } + + /** + * Retrieves an updated list of priorities for all the saved networks before + * enabling/disabling disconnected PNO (wpa_supplicant based PNO). * * wpa_supplicant uses the priority of networks to build the list of SSID's to monitor * during PNO. If there are a lot of saved networks, this list will be truncated and we @@ -1463,34 +1463,83 @@ public class WifiConfigStore extends IpConfigStore { * @param enablePno boolean indicating whether PNO is being enabled or disabled. * @return list of networks with updated priorities. */ - ArrayList<WifiNative.PnoNetworkPriority> retrievePnoNetworkPriorityList(boolean enablePno) { - ArrayList<WifiNative.PnoNetworkPriority> pnoList = - new ArrayList<WifiNative.PnoNetworkPriority>(); + public ArrayList<WifiNative.WifiPnoNetwork> retrieveDisconnectedWifiPnoNetworkList( + boolean enablePno) { + return retrieveWifiPnoNetworkList(enablePno, sDisconnectedPnoListComparator); + } + + /** + * Connected PnoNetwork list sorting algorithm: + * Place the configurations with |lastSeenInQualifiedNetworkSelection| set first. If networks + * have the same value, then sort them in descending order of their |numAssociation| + * values. + */ + private static final PnoListComparator sConnectedPnoListComparator = + new PnoListComparator() { + @Override + public int compareConfigurations(WifiConfiguration a, WifiConfiguration b) { + boolean isConfigALastSeen = + a.getNetworkSelectionStatus().getSeenInLastQualifiedNetworkSelection(); + boolean isConfigBLastSeen = + b.getNetworkSelectionStatus().getSeenInLastQualifiedNetworkSelection(); + if (isConfigALastSeen != isConfigBLastSeen) { + return Boolean.compare(isConfigBLastSeen, isConfigALastSeen); + } else { + return Long.compare(b.numAssociation, a.numAssociation); + } + } + }; + + /** + * Retrieves an updated list of priorities for all the saved networks before + * enabling connected PNO (HAL based ePno). + * + * @return list of networks with updated priorities. + */ + public ArrayList<WifiNative.WifiPnoNetwork> retrieveConnectedWifiPnoNetworkList() { + return retrieveWifiPnoNetworkList(true, sConnectedPnoListComparator); + } + + /** + * Retrieves an updated list of priorities for all the saved networks before + * enabling/disabling PNO. + * + * @param enablePno boolean indicating whether PNO is being enabled or disabled. + * @return list of networks with updated priorities. + */ + private ArrayList<WifiNative.WifiPnoNetwork> retrieveWifiPnoNetworkList( + boolean enablePno, PnoListComparator pnoListComparator) { + ArrayList<WifiNative.WifiPnoNetwork> pnoList = + new ArrayList<WifiNative.WifiPnoNetwork>(); ArrayList<WifiConfiguration> wifiConfigurations = new ArrayList<WifiConfiguration>(mConfiguredNetworks.valuesForCurrentUser()); if (enablePno) { - Collections.sort(wifiConfigurations, sPnoListSortComparator); + Collections.sort(wifiConfigurations, pnoListComparator); // Let's use the network list size as the highest priority and then go down from there. // So, the most frequently connected network has the highest priority now. int priority = wifiConfigurations.size(); if (DBG) { Log.d(TAG, "Retrieve network priorities before PNO. Max priority: " + priority); } + // Initialize the RSSI threshold with sane value: + // Use the 2.4GHz threshold since most WifiConfigurations are dual bands + // There is very little penalty with triggering too soon, i.e. if PNO finds a network + // that has an RSSI too low for us to attempt joining it. + int threshold = thresholdMinimumRssi24.get(); for (WifiConfiguration config : wifiConfigurations) { - pnoList.add(new WifiNative.PnoNetworkPriority(config.networkId, priority)); + pnoList.add(new WifiNative.WifiPnoNetwork(config, threshold, priority)); priority--; } } else { // Revert the priorities back to the saved config values after PNO. if (DBG) Log.d(TAG, "Retrieve network priorities after PNO."); for (WifiConfiguration config : wifiConfigurations) { - pnoList.add(new WifiNative.PnoNetworkPriority(config.networkId, config.priority)); + pnoList.add(new WifiNative.WifiPnoNetwork(config, 0, config.priority)); } } return pnoList; } - String[] getWhiteListedSsids(WifiConfiguration config) { int num_ssids = 0; String nonQuoteSSID; @@ -2272,8 +2321,6 @@ public class WifiConfigStore extends IpConfigStore { readIpAndProxyConfigurations(); readAutoJoinConfig(); - buildPnoList(); - sendConfiguredNetworksChangedBroadcast(); if (showNetworks) { diff --git a/service/java/com/android/server/wifi/WifiNative.java b/service/java/com/android/server/wifi/WifiNative.java index 1b9cbed1c..bd7b6faf0 100644 --- a/service/java/com/android/server/wifi/WifiNative.java +++ b/service/java/com/android/server/wifi/WifiNative.java @@ -884,28 +884,6 @@ public class WifiNative { } - /** - * Object holding the network ID and the corresponding priority to be set before enabling/ - * disabling PNO. - */ - public static class PnoNetworkPriority { - public int networkId; - public int priority; - - PnoNetworkPriority(int networkId, int priority) { - this.networkId = networkId; - this.priority = priority; - } - - @Override - public String toString() { - StringBuilder sbuf = new StringBuilder(); - sbuf.append(" Network ID=").append(this.networkId); - sbuf.append(" Priority=").append(this.priority); - return sbuf.toString(); - } - } - //PNO Monitor private class PnoMonitor { private static final int MINIMUM_PNO_GAP = 5 * 1000; @@ -913,7 +891,7 @@ public class WifiNative { "com.android.server.Wifi.action.TOGGLE_PNO"; long mLastPnoChangeTimeStamp = -1L; boolean mExpectedPnoState = false; - List<PnoNetworkPriority> mExpectedPnoNetworkPriorityList = null; + List<WifiPnoNetwork> mExpectedWifiPnoNetworkList = null; boolean mCurrentPnoState = false;; boolean mWaitForTimer = false; final Object mPnoLock = new Object(); @@ -937,7 +915,7 @@ public class WifiNative { if (DBG) Log.d(mTAG, "change PNO from " + mCurrentPnoState + " to " + mExpectedPnoState); boolean ret = setPno( - mExpectedPnoState, mExpectedPnoNetworkPriorityList); + mExpectedPnoState, mExpectedWifiPnoNetworkList); if (!ret) { Log.e(mTAG, "set PNO failure"); } @@ -956,18 +934,18 @@ public class WifiNative { * @param enable boolean indicating whether PNO is being enabled or disabled. * @param pnoNetworkList list of networks with priorities to be set before PNO setting. */ - private boolean setPno(boolean enable, List<PnoNetworkPriority> pnoNetworkList) { + private boolean setPno(boolean enable, List<WifiPnoNetwork> pnoNetworkList) { // TODO: Couple of cases yet to be handled: // 1. What if the network priority update fails, should we bail out of PNO setting? // 2. If PNO setting fails below, should we go back and revert this priority change? if (pnoNetworkList != null) { if (DBG) Log.i(mTAG, "Update priorities for PNO. Enable: " + enable); - for (PnoNetworkPriority pnoNetwork : pnoNetworkList) { + for (WifiPnoNetwork pnoNetwork : pnoNetworkList) { // What if this fails? Should we bail out? boolean isSuccess = setNetworkVariable(pnoNetwork.networkId, WifiConfiguration.priorityVarName, Integer.toString(pnoNetwork.priority)); - if (DBG && !isSuccess) { + if (!isSuccess) { Log.e(mTAG, "Update priority failed for :" + pnoNetwork.networkId); } } @@ -983,12 +961,12 @@ public class WifiNative { public boolean enableBackgroundScan( boolean enable, - List<PnoNetworkPriority> pnoNetworkList) { + List<WifiPnoNetwork> pnoNetworkList) { synchronized(mPnoLock) { if (mWaitForTimer) { //already has a timer mExpectedPnoState = enable; - mExpectedPnoNetworkPriorityList = pnoNetworkList; + mExpectedWifiPnoNetworkList = pnoNetworkList; if (DBG) Log.d(mTAG, "update expected PNO to " + mExpectedPnoState); } else { if (mCurrentPnoState == enable) { @@ -999,7 +977,7 @@ public class WifiNative { return setPno(enable, pnoNetworkList); } else { mExpectedPnoState = enable; - mExpectedPnoNetworkPriorityList = pnoNetworkList; + mExpectedWifiPnoNetworkList = pnoNetworkList; mWaitForTimer = true; if (DBG) Log.d(mTAG, "start PNO timer with delay:" + timeDifference); mAlarmManager.set(AlarmManager.RTC_WAKEUP, @@ -1013,7 +991,7 @@ public class WifiNative { public boolean enableBackgroundScan( boolean enable, - List<PnoNetworkPriority> pnoNetworkList) { + List<WifiPnoNetwork> pnoNetworkList) { if (mPnoMonitor != null) { return mPnoMonitor.enableBackgroundScan(enable, pnoNetworkList); } else { @@ -2634,7 +2612,7 @@ public class WifiNative { } //--------------------------------------------------------------------------------- - /* Configure ePNO */ + /* Configure ePNO/PNO */ /* pno flags, keep these values in sync with gscan.h */ private static int WIFI_PNO_AUTH_CODE_OPEN = 1; // open @@ -2650,34 +2628,39 @@ public class WifiNative { // Whether strict matching is required (i.e. firmware shall not match on the entire SSID) private static int WIFI_PNO_FLAG_STRICT_MATCH = 8; + /** + * Object holding the network ID and the corresponding priority to be set before enabling/ + * disabling PNO. + */ public static class WifiPnoNetwork { - String SSID; - int rssi_threshold; // TODO remove - int flags; - int auth; - String configKey; // kept for reference + public String SSID; + public int rssi_threshold; // TODO remove + public int flags; + public int auth; + public String configKey; // kept for reference + public int networkId; + public int priority; - WifiPnoNetwork(WifiConfiguration config, int threshold) { + WifiPnoNetwork(WifiConfiguration config, int threshold, int newPriority) { if (config.SSID == null) { - this.SSID = ""; - this.flags = WIFI_PNO_FLAG_DIRECTED_SCAN; + SSID = ""; + flags = WIFI_PNO_FLAG_DIRECTED_SCAN; } else { - this.SSID = config.SSID; + SSID = config.SSID; } - this.rssi_threshold = threshold; + rssi_threshold = threshold; if (config.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.WPA_PSK)) { auth |= WIFI_PNO_AUTH_CODE_PSK; } else if (config.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.WPA_EAP) || config.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.IEEE8021X)) { auth |= WIFI_PNO_AUTH_CODE_EAPOL; - } else if (config.wepKeys[0] != null) { - auth |= WIFI_PNO_AUTH_CODE_OPEN; } else { auth |= WIFI_PNO_AUTH_CODE_OPEN; } - flags |= WIFI_PNO_FLAG_A_BAND | WIFI_PNO_FLAG_G_BAND; configKey = config.configKey(); + networkId = config.networkId; + priority = newPriority; } @Override @@ -2687,6 +2670,8 @@ public class WifiNative { sbuf.append(" flags=").append(this.flags); sbuf.append(" rssi=").append(this.rssi_threshold); sbuf.append(" auth=").append(this.auth); + sbuf.append(" Network ID=").append(this.networkId); + sbuf.append(" Priority=").append(this.priority); return sbuf.toString(); } } diff --git a/service/java/com/android/server/wifi/WifiStateMachine.java b/service/java/com/android/server/wifi/WifiStateMachine.java index c731fe0df..0cae467e1 100644 --- a/service/java/com/android/server/wifi/WifiStateMachine.java +++ b/service/java/com/android/server/wifi/WifiStateMachine.java @@ -2517,8 +2517,8 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiPno if (enable) { mWifiConfigStore.enableAllNetworks(); } - List<WifiNative.PnoNetworkPriority> pnoList = - mWifiConfigStore.retrievePnoNetworkPriorityList(enable); + List<WifiNative.WifiPnoNetwork> pnoList = + mWifiConfigStore.retrieveDisconnectedWifiPnoNetworkList(enable); boolean ret = mWifiNative.enableBackgroundScan(enable, pnoList); if (ret) { mLegacyPnoEnabled = enable; @@ -6616,6 +6616,7 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiPno //records how long this network is connected in future config.lastConnected = System.currentTimeMillis(); config.getNetworkSelectionStatus().clearDisableReasonCounter(); + config.numAssociation++; } mBadLinkspeedcount = 0; } diff --git a/tests/wifitests/src/com/android/server/wifi/WifiConfigStoreTest.java b/tests/wifitests/src/com/android/server/wifi/WifiConfigStoreTest.java index ddc4894fe..67370de65 100644 --- a/tests/wifitests/src/com/android/server/wifi/WifiConfigStoreTest.java +++ b/tests/wifitests/src/com/android/server/wifi/WifiConfigStoreTest.java @@ -967,21 +967,22 @@ public class WifiConfigStoreTest { * network in expectedNetworkIDOrder list. */ private static void verifyPnoNetworkListOrder( - ArrayList<WifiNative.PnoNetworkPriority> pnoNetworkList, + ArrayList<WifiNative.WifiPnoNetwork> pnoNetworkList, ArrayList<Integer> expectedNetworkIdOrder) throws Exception { int i = 0; - for (WifiNative.PnoNetworkPriority pnoNetwork : pnoNetworkList) { + for (WifiNative.WifiPnoNetwork pnoNetwork : pnoNetworkList) { Log.i(TAG, "PNO Network List Index: " + i + ", networkID: " + pnoNetwork.networkId); - assertTrue(pnoNetwork.networkId == expectedNetworkIdOrder.get(i++)); + assertEquals("Expected network ID: " + pnoNetwork.networkId, + pnoNetwork.networkId, expectedNetworkIdOrder.get(i++).intValue()); } } /** - * Verifies the retrievePnoNetworkPriorityList API. The test verifies that the list returned - * from the API is sorted as expected. + * Verifies the retrieveDisconnectedWifiPnoNetworkList API. The test verifies that the list + * returned from the API is sorted as expected. */ @Test - public void testPnoNetworkPriorityListCreation() throws Exception { + public void testDisconnectedWifiPnoNetworkListCreation() throws Exception { addNetworks(); Random rand = new Random(WifiTestUtil.getTestMethod().hashCode()); @@ -999,15 +1000,14 @@ public class WifiConfigStoreTest { for (WifiConfiguration config : mConfiguredNetworks.valuesForCurrentUser()) { config.numAssociation = numAssociationValues.pop(); config.priority = rand.nextInt(10000); - config.status = WifiConfiguration.Status.ENABLED; config.getNetworkSelectionStatus().setNetworkSelectionStatus( WifiConfiguration.NetworkSelectionStatus.NETWORK_SELECTION_ENABLED); numAssociationToNetworkIdMap.put(config.numAssociation, config.networkId); Log.i(TAG, "networkID: " + config.networkId + ", numAssociation: " + config.numAssociation); } - ArrayList<WifiNative.PnoNetworkPriority> pnoNetworkList = - mConfigStore.retrievePnoNetworkPriorityList(true); + ArrayList<WifiNative.WifiPnoNetwork> pnoNetworkList = + mConfigStore.retrieveDisconnectedWifiPnoNetworkList(); verifyPnoNetworkListOrder(pnoNetworkList, new ArrayList(numAssociationToNetworkIdMap.values())); } @@ -1024,14 +1024,13 @@ public class WifiConfigStoreTest { for (WifiConfiguration config : mConfiguredNetworks.valuesForCurrentUser()) { config.numAssociation = 0; config.priority = priorityValues.pop(); - config.status = WifiConfiguration.Status.ENABLED; config.getNetworkSelectionStatus().setNetworkSelectionStatus( WifiConfiguration.NetworkSelectionStatus.NETWORK_SELECTION_ENABLED); priorityToNetworkIdMap.put(config.priority, config.networkId); Log.i(TAG, "networkID: " + config.networkId + ", priority: " + config.priority); } - ArrayList<WifiNative.PnoNetworkPriority> pnoNetworkList = - mConfigStore.retrievePnoNetworkPriorityList(true); + ArrayList<WifiNative.WifiPnoNetwork> pnoNetworkList = + mConfigStore.retrieveDisconnectedWifiPnoNetworkList(); verifyPnoNetworkListOrder(pnoNetworkList, new ArrayList(priorityToNetworkIdMap.values())); } @@ -1049,7 +1048,6 @@ public class WifiConfigStoreTest { for (WifiConfiguration config : mConfiguredNetworks.valuesForCurrentUser()) { config.numAssociation = rand.nextInt(10000); config.priority = rand.nextInt(10000); - config.status = WifiConfiguration.Status.ENABLED; config.getNetworkSelectionStatus().setNetworkSelectionStatus( networkSelectionStatusValues.pop()); networkSelectionStatusToNetworkIdMap.put( @@ -1058,8 +1056,98 @@ public class WifiConfigStoreTest { Log.i(TAG, "networkID: " + config.networkId + ", NetworkSelectionStatus: " + config.getNetworkSelectionStatus().getNetworkSelectionStatus()); } - ArrayList<WifiNative.PnoNetworkPriority> pnoNetworkList = - mConfigStore.retrievePnoNetworkPriorityList(true); + ArrayList<WifiNative.WifiPnoNetwork> pnoNetworkList = + mConfigStore.retrieveDisconnectedWifiPnoNetworkList(); + verifyPnoNetworkListOrder(pnoNetworkList, + new ArrayList(networkSelectionStatusToNetworkIdMap.values())); + } + } + + /** + * Verifies the retrieveConnectedWifiPnoNetworkList API. The test verifies that the list + * returned from the API is sorted as expected. + */ + @Test + public void testConnectedWifiPnoNetworkListCreation() throws Exception { + addNetworks(); + + Random rand = new Random(WifiTestUtil.getTestMethod().hashCode()); + + // First assign |lastSeen| values and verify that the list is sorted + // in descending order of |lastSeen| values. Keep NetworkSelectionStatus + // values constant. + for (int userId : USER_IDS) { + switchUser(userId); + TreeMap<Boolean, Integer> lastSeenToNetworkIdMap = + new TreeMap<>(Collections.reverseOrder()); + ArrayDeque<Integer> lastSeenValues = getUniqueRandomNumberValues(1, 2, 2); + if (mConfiguredNetworks.valuesForCurrentUser().size() > 2) continue; + for (WifiConfiguration config : mConfiguredNetworks.valuesForCurrentUser()) { + config.numAssociation = rand.nextInt(10000); + config.priority = rand.nextInt(10000); + config.getNetworkSelectionStatus().setNetworkSelectionStatus( + WifiConfiguration.NetworkSelectionStatus.NETWORK_SELECTION_ENABLED); + boolean lastSeenValue = (lastSeenValues.pop() == 1); + config.getNetworkSelectionStatus().setSeenInLastQualifiedNetworkSelection( + lastSeenValue); + lastSeenToNetworkIdMap.put(lastSeenValue, config.networkId); + Log.i(TAG, "networkID: " + config.networkId + ", lastSeen: " + lastSeenValue); + } + ArrayList<WifiNative.WifiPnoNetwork> pnoNetworkList = + mConfigStore.retrieveConnectedWifiPnoNetworkList(); + verifyPnoNetworkListOrder(pnoNetworkList, + new ArrayList(lastSeenToNetworkIdMap.values())); + } + + // Assign random |numAssociation| values and verify that the list is sorted + // in descending order of |numAssociation| values. Keep NetworkSelectionStatus/lastSeen + // values constant. + for (int userId : USER_IDS) { + switchUser(userId); + TreeMap<Integer, Integer> numAssociationToNetworkIdMap = + new TreeMap<>(Collections.reverseOrder()); + ArrayDeque<Integer> numAssociationValues = + getUniqueRandomNumberValues( + 1, 10000, mConfiguredNetworks.valuesForCurrentUser().size()); + for (WifiConfiguration config : mConfiguredNetworks.valuesForCurrentUser()) { + config.numAssociation = numAssociationValues.pop(); + config.priority = rand.nextInt(10000); + config.getNetworkSelectionStatus().setNetworkSelectionStatus( + WifiConfiguration.NetworkSelectionStatus.NETWORK_SELECTION_ENABLED); + config.getNetworkSelectionStatus().setSeenInLastQualifiedNetworkSelection(true); + numAssociationToNetworkIdMap.put(config.numAssociation, config.networkId); + Log.i(TAG, "networkID: " + config.networkId + ", numAssociation: " + + config.numAssociation); + } + ArrayList<WifiNative.WifiPnoNetwork> pnoNetworkList = + mConfigStore.retrieveConnectedWifiPnoNetworkList(); + verifyPnoNetworkListOrder(pnoNetworkList, + new ArrayList(numAssociationToNetworkIdMap.values())); + } + + // Now assign random |NetworkSelectionStatus| values and verify that the list is sorted in + // ascending order of |NetworkSelectionStatus| values. + for (int userId : USER_IDS) { + switchUser(userId); + TreeMap<Integer, Integer> networkSelectionStatusToNetworkIdMap = new TreeMap<>(); + ArrayDeque<Integer> networkSelectionStatusValues = + getUniqueRandomNumberValues( + 3, + WifiConfiguration.NetworkSelectionStatus.NETWORK_SELECTION_STATUS_MAX, + mConfiguredNetworks.valuesForCurrentUser().size()); + for (WifiConfiguration config : mConfiguredNetworks.valuesForCurrentUser()) { + config.numAssociation = rand.nextInt(10000); + config.priority = rand.nextInt(10000); + config.getNetworkSelectionStatus().setNetworkSelectionStatus( + networkSelectionStatusValues.pop()); + networkSelectionStatusToNetworkIdMap.put( + config.getNetworkSelectionStatus().getNetworkSelectionStatus(), + config.networkId); + Log.i(TAG, "networkID: " + config.networkId + ", NetworkSelectionStatus: " + + config.getNetworkSelectionStatus().getNetworkSelectionStatus()); + } + ArrayList<WifiNative.WifiPnoNetwork> pnoNetworkList = + mConfigStore.retrieveConnectedWifiPnoNetworkList(); verifyPnoNetworkListOrder(pnoNetworkList, new ArrayList(networkSelectionStatusToNetworkIdMap.values())); } |