summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRoshan Pius <rpius@google.com>2016-01-27 17:36:42 -0800
committerThe Android Automerger <android-build@google.com>2016-02-24 13:21:18 -0800
commit7a0e978a5ba16f237c7ef8aac9cb6154d2d183bd (patch)
treef70eceabead4b76c790bd4798cc1bb6e3b284f2b
parent76eb4f1ad5a51038c2d18fb9eb13d0e0ab6dfc60 (diff)
downloadframeworks_opt_net_wifi-7a0e978a5ba16f237c7ef8aac9cb6154d2d183bd.tar.gz
frameworks_opt_net_wifi-7a0e978a5ba16f237c7ef8aac9cb6154d2d183bd.tar.bz2
frameworks_opt_net_wifi-7a0e978a5ba16f237c7ef8aac9cb6154d2d183bd.zip
DO NOT MERGE Update network priorities before PNO is triggered
The max SSID watch list size for PNO supported by wlan drivers is fixed to a certain size. wpa_supplicant sorts this SSID watch list based on the priorities assigned to those networks. This may result in us losing some frequently used networks from the PNO list because they have lower priorities. This is a side effect of how we assign priorities to network configuration as they're added. So before we trigger PNO, re-sort the network list based on the 'numAssociation' value and assign them relative priorities. This will make sure that the PNO SSID watch list contains all the frequent SSID's to which we were connected to. PS: This change has a side-effect of ignoring the configured priorities during PNO. BUG: 26763375 Change-Id: I2c82254b2cb83aef0dd4da9e7d9b2eb5b376bead Cherry-picked from: https://partner-android-review.googlesource.com/#/c/529355
-rw-r--r--service/java/com/android/server/wifi/WifiConfigStore.java103
-rw-r--r--service/java/com/android/server/wifi/WifiNative.java41
-rw-r--r--service/java/com/android/server/wifi/WifiStateMachine.java4
3 files changed, 146 insertions, 2 deletions
diff --git a/service/java/com/android/server/wifi/WifiConfigStore.java b/service/java/com/android/server/wifi/WifiConfigStore.java
index d40b875..d6e41a1 100644
--- a/service/java/com/android/server/wifi/WifiConfigStore.java
+++ b/service/java/com/android/server/wifi/WifiConfigStore.java
@@ -1330,6 +1330,109 @@ public class WifiConfigStore extends IpConfigStore {
}
}
+ /**
+ * Returns whether the provided network config is enabled for autojoin or not.
+ */
+ private static boolean isNetworkEnabled(WifiConfiguration config) {
+ return (config.status == Status.ENABLED && !config.ephemeral
+ && (config.autoJoinStatus == WifiConfiguration.AUTO_JOIN_ENABLED));
+ }
+
+ /**
+ * Returns whether the provided network config is only temporarily disabled for autojoin or not.
+ */
+ private static boolean isNetworkTempDisabled(WifiConfiguration config) {
+ return (config.status == Status.ENABLED && !config.ephemeral
+ && ((config.autoJoinStatus <= WifiConfiguration.AUTO_JOIN_DISABLED_ON_AUTH_FAILURE)
+ && (config.autoJoinStatus > WifiConfiguration.AUTO_JOIN_ENABLED)));
+ }
+
+ /**
+ * 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 this order:
+ * Fully enabled network > Temporarily disabled network > Permanently disabled network.
+ */
+ private static int getPnoNetworkSortScore(WifiConfiguration config) {
+ // Do we need static constants for these scores? We're not using them anywhere else though.
+ if (isNetworkEnabled(config)) {
+ return 3;
+ } else if (isNetworkTempDisabled(config)) {
+ return 2;
+ } else {
+ return 1;
+ }
+ }
+
+ /**
+ * 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|
+ * 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) {
+ int configAScore = getPnoNetworkSortScore(a);
+ int configBScore = getPnoNetworkSortScore(b);
+ if (configAScore == configBScore) {
+ // 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 {
+ return Integer.compare(configBScore, configAScore);
+ }
+ }
+ };
+
+ /**
+ * Retrieves an updated list of priorities for all the saved networks before
+ * enabling/disabling 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
+ * might end up not connecting to the networks we use most frequently. So, We want the networks
+ * to be re-sorted based on the relative |numAssociation| values.
+ *
+ * @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>();
+ ArrayList<WifiConfiguration> wifiConfigurations =
+ new ArrayList<WifiConfiguration>(mConfiguredNetworks.values());
+ if (enablePno) {
+ Collections.sort(wifiConfigurations, sPnoListSortComparator);
+ // 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);
+ }
+ for (WifiConfiguration config : wifiConfigurations) {
+ pnoList.add(new WifiNative.PnoNetworkPriority(config.networkId, 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));
+ }
+ }
+ return pnoList;
+ }
+
+
String[] getWhiteListedSsids(WifiConfiguration config) {
int num_ssids = 0;
String nonQuoteSSID;
diff --git a/service/java/com/android/server/wifi/WifiNative.java b/service/java/com/android/server/wifi/WifiNative.java
index 2e25bae..620f8b5 100644
--- a/service/java/com/android/server/wifi/WifiNative.java
+++ b/service/java/com/android/server/wifi/WifiNative.java
@@ -656,8 +656,47 @@ public class WifiNative {
return doBooleanCommand("DRIVER COUNTRY");
}
- public boolean enableBackgroundScan(boolean enable) {
+ /**
+ * 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();
+ }
+ }
+
+ public boolean enableBackgroundScan(
+ boolean enable,
+ List<PnoNetworkPriority> pnoNetworkList) {
boolean ret;
+ // 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) {
+ // What if this fails? Should we bail out?
+ boolean isSuccess = setNetworkVariable(pnoNetwork.networkId,
+ WifiConfiguration.priorityVarName,
+ Integer.toString(pnoNetwork.priority));
+ if (!isSuccess) {
+ Log.e(mTAG, "Update priority failed for :" + pnoNetwork.networkId);
+ }
+ }
+ }
if (enable) {
ret = doBooleanCommand("SET pno 1");
} else {
diff --git a/service/java/com/android/server/wifi/WifiStateMachine.java b/service/java/com/android/server/wifi/WifiStateMachine.java
index 706c08b..4e40f73 100644
--- a/service/java/com/android/server/wifi/WifiStateMachine.java
+++ b/service/java/com/android/server/wifi/WifiStateMachine.java
@@ -2357,7 +2357,9 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiPno
if (enable) {
mWifiConfigStore.enableAllNetworks();
}
- boolean ret = mWifiNative.enableBackgroundScan(enable);
+ List<WifiNative.PnoNetworkPriority> pnoList =
+ mWifiConfigStore.retrievePnoNetworkPriorityList(enable);
+ boolean ret = mWifiNative.enableBackgroundScan(enable, pnoList);
if (ret) {
mLegacyPnoEnabled = enable;
} else {