summaryrefslogtreecommitdiff
path: root/service
diff options
context:
space:
mode:
authorRoshan Pius <rpius@google.com>2016-02-11 06:48:44 +0000
committerAndroid Partner Code Review <android-gerrit-partner@google.com>2016-02-11 06:48:45 +0000
commitbfcea7de75875c900de19a8504416492ed96ae21 (patch)
treef79a09f583a46b153f90fe3f8a993aadcd92b844 /service
parentd150184a5b28f862b39ad383ab87ee0ac4ca6be8 (diff)
parentac9ad3283508db15b65b1cbb89b841278973276b (diff)
Merge "Update network priorities before PNO is triggered" into mm-wireless-dev
Diffstat (limited to 'service')
-rw-r--r--service/java/com/android/server/wifi/WifiConfigStore.java78
-rw-r--r--service/java/com/android/server/wifi/WifiNative.java63
-rw-r--r--service/java/com/android/server/wifi/WifiStateMachine.java4
3 files changed, 138 insertions, 7 deletions
diff --git a/service/java/com/android/server/wifi/WifiConfigStore.java b/service/java/com/android/server/wifi/WifiConfigStore.java
index 77757a8b3..cc9e5068f 100644
--- a/service/java/com/android/server/wifi/WifiConfigStore.java
+++ b/service/java/com/android/server/wifi/WifiConfigStore.java
@@ -1363,6 +1363,84 @@ public class WifiConfigStore extends IpConfigStore {
}
}
+
+ /**
+ * 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) {
+ 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);
+ } else {
+ return Boolean.compare(isConfigBTempDisabled, isConfigATempDisabled);
+ }
+ }
+ };
+
+ /**
+ * 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.valuesForCurrentUser());
+ 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 20f5ab3c7..9246c2ea9 100644
--- a/service/java/com/android/server/wifi/WifiNative.java
+++ b/service/java/com/android/server/wifi/WifiNative.java
@@ -880,6 +880,29 @@ public class WifiNative {
return doBooleanCommand("DRIVER COUNTRY");
}
+
+ /**
+ * 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;
@@ -887,6 +910,7 @@ public class WifiNative {
"com.android.server.Wifi.action.TOGGLE_PNO";
long mLastPnoChangeTimeStamp = -1L;
boolean mExpectedPnoState = false;
+ List<PnoNetworkPriority> mExpectedPnoNetworkPriorityList = null;
boolean mCurrentPnoState = false;;
boolean mWaitForTimer = false;
final Object mPnoLock = new Object();
@@ -909,7 +933,8 @@ public class WifiNative {
if (mCurrentPnoState != mExpectedPnoState) {
if (DBG) Log.d(mTAG, "change PNO from " + mCurrentPnoState + " to "
+ mExpectedPnoState);
- boolean ret = setPno(mExpectedPnoState);
+ boolean ret = setPno(
+ mExpectedPnoState, mExpectedPnoNetworkPriorityList);
if (!ret) {
Log.e(mTAG, "set PNO failure");
}
@@ -923,7 +948,27 @@ public class WifiNative {
new IntentFilter(ACTION_TOGGLE_PNO));
}
- private boolean setPno(boolean enable) {
+ /* Enable/Disable PNO with updated network priorities.
+ *
+ * @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) {
+ // 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 (DBG && !isSuccess) {
+ Log.e(mTAG, "Update priority failed for :" + pnoNetwork.networkId);
+ }
+ }
+ }
String cmd = enable ? "SET pno 1" : "SET pno 0";
boolean ret = doBooleanCommand(cmd);
mLastPnoChangeTimeStamp = System.currentTimeMillis();
@@ -933,11 +978,14 @@ public class WifiNative {
return ret;
}
- public boolean enableBackgroundScan(boolean enable) {
+ public boolean enableBackgroundScan(
+ boolean enable,
+ List<PnoNetworkPriority> pnoNetworkList) {
synchronized(mPnoLock) {
if (mWaitForTimer) {
//already has a timer
mExpectedPnoState = enable;
+ mExpectedPnoNetworkPriorityList = pnoNetworkList;
if (DBG) Log.d(mTAG, "update expected PNO to " + mExpectedPnoState);
} else {
if (mCurrentPnoState == enable) {
@@ -945,9 +993,10 @@ public class WifiNative {
}
long timeDifference = System.currentTimeMillis() - mLastPnoChangeTimeStamp;
if (timeDifference >= MINIMUM_PNO_GAP) {
- return setPno(enable);
+ return setPno(enable, pnoNetworkList);
} else {
mExpectedPnoState = enable;
+ mExpectedPnoNetworkPriorityList = pnoNetworkList;
mWaitForTimer = true;
if (DBG) Log.d(mTAG, "start PNO timer with delay:" + timeDifference);
mAlarmManager.set(AlarmManager.RTC_WAKEUP,
@@ -959,9 +1008,11 @@ public class WifiNative {
}
}
- public boolean enableBackgroundScan(boolean enable) {
+ public boolean enableBackgroundScan(
+ boolean enable,
+ List<PnoNetworkPriority> pnoNetworkList) {
if (mPnoMonitor != null) {
- return mPnoMonitor.enableBackgroundScan(enable);
+ return mPnoMonitor.enableBackgroundScan(enable, pnoNetworkList);
} else {
return false;
}
diff --git a/service/java/com/android/server/wifi/WifiStateMachine.java b/service/java/com/android/server/wifi/WifiStateMachine.java
index 8aaa163bd..1bf89a683 100644
--- a/service/java/com/android/server/wifi/WifiStateMachine.java
+++ b/service/java/com/android/server/wifi/WifiStateMachine.java
@@ -2507,7 +2507,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 {