summaryrefslogtreecommitdiff
path: root/service
diff options
context:
space:
mode:
authorRoshan Pius <rpius@google.com>2016-03-02 14:20:22 -0800
committerRoshan Pius <rpius@google.com>2016-03-06 20:28:23 -0800
commit9153bd67d51b305ffdd61355e0748e3c332c2caf (patch)
tree9e8f347fab576c361dc9b5f7cd6623663e5e8aef /service
parent9bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bd (diff)
WifiScannerImpl: PNO implementation (Part 1)
1. Immplementation of the PNO interface in WifiScannerImpl for setting/resetting the PNO list. a. For supplicant based PNO, setting the pno list will also trigger the scan and we don't scan any background scans. b. For HAL based PNO, we set the pno list and then schedule a normal background scan. 2. Plumbing of the OnPnoNetworkFound callback to the client. TODO's: 1. Will need to integrate the PNO monitor notifcations in SupplicantWifiScannerImpl to raise OnPnoNetworkFound callbacks. BUG: 27167559 Change-Id: I8859a419b37b9cb125a710fb67ae1b62db7f779d TEST: Compiles & unit-test passes
Diffstat (limited to 'service')
-rw-r--r--service/java/com/android/server/wifi/HalWifiScannerImpl.java16
-rw-r--r--service/java/com/android/server/wifi/SupplicantWifiScannerImpl.java65
-rw-r--r--service/java/com/android/server/wifi/WifiNative.java25
-rw-r--r--service/java/com/android/server/wifi/WifiScannerImpl.java22
-rw-r--r--service/java/com/android/server/wifi/WifiScanningServiceImpl.java95
5 files changed, 216 insertions, 7 deletions
diff --git a/service/java/com/android/server/wifi/HalWifiScannerImpl.java b/service/java/com/android/server/wifi/HalWifiScannerImpl.java
index 90a54f09f..e08ab510f 100644
--- a/service/java/com/android/server/wifi/HalWifiScannerImpl.java
+++ b/service/java/com/android/server/wifi/HalWifiScannerImpl.java
@@ -195,6 +195,22 @@ public class HalWifiScannerImpl extends WifiScannerImpl implements Handler.Callb
}
@Override
+ public boolean setPnoList(WifiNative.PnoSettings settings,
+ WifiNative.PnoEventHandler eventHandler) {
+ return mWifiNative.setPnoList(settings, eventHandler);
+ }
+
+ @Override
+ public boolean resetPnoList(WifiNative.PnoSettings settings) {
+ return mWifiNative.resetPnoList();
+ }
+
+ @Override
+ public boolean shouldScheduleBackgroundScanForPno() {
+ return true;
+ }
+
+ @Override
public WifiScanner.ScanData[] getLatestBatchedScanResults(boolean flush) {
return mWifiNative.getScanResults(flush);
}
diff --git a/service/java/com/android/server/wifi/SupplicantWifiScannerImpl.java b/service/java/com/android/server/wifi/SupplicantWifiScannerImpl.java
index 90413ff85..f9e40186d 100644
--- a/service/java/com/android/server/wifi/SupplicantWifiScannerImpl.java
+++ b/service/java/com/android/server/wifi/SupplicantWifiScannerImpl.java
@@ -19,6 +19,7 @@ package com.android.server.wifi;
import android.app.AlarmManager;
import android.content.Context;
import android.net.wifi.ScanResult;
+import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiScanner;
import android.os.Handler;
import android.os.Looper;
@@ -85,6 +86,10 @@ public class SupplicantWifiScannerImpl extends WifiScannerImpl implements Handle
private WifiNative.HotlistEventHandler mHotlistHandler = null;
private ChangeBuffer mHotlistChangeBuffer = new ChangeBuffer();
+ // Pno related info.
+ private boolean mPnoRunning = false;
+ private WifiNative.PnoEventHandler mPnoEventHandler;
+
AlarmManager.OnAlarmListener mScanPeriodListener = new AlarmManager.OnAlarmListener() {
public void onAlarm() {
synchronized (mSettingsLock) {
@@ -248,6 +253,66 @@ public class SupplicantWifiScannerImpl extends WifiScannerImpl implements Handle
}
}
+ private boolean setNetworkPriorities(WifiNative.PnoNetwork[] networkList) {
+ if (networkList != null) {
+ if (DBG) Log.i(TAG, "Set priorities for PNO.");
+ for (WifiNative.PnoNetwork network : networkList) {
+ // What if this fails? Should we bail out?
+ boolean isSuccess = mWifiNative.setNetworkVariable(network.networkId,
+ WifiConfiguration.priorityVarName,
+ Integer.toString(network.priority));
+ if (!isSuccess) {
+ Log.e(TAG, "Update priority failed for :" + network.networkId);
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+
+ private boolean startPnoScan() {
+ if (!mWifiNative.setPnoScan(true)) {
+ mPnoRunning = true;
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ @Override
+ public boolean setPnoList(WifiNative.PnoSettings settings,
+ WifiNative.PnoEventHandler eventHandler) {
+ if (mPnoRunning) return true;
+ mPnoEventHandler = eventHandler;
+ boolean isSuccess = setNetworkPriorities(settings.networkList);
+ if (!isSuccess) return false;
+ // For supplicant based PNO, we start the scan immediately when we set pno list.
+ return startPnoScan();
+ }
+
+ private boolean stopPnoScan() {
+ if (!mWifiNative.setPnoScan(false)) {
+ mPnoRunning = false;
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ @Override
+ public boolean resetPnoList(WifiNative.PnoSettings settings) {
+ if (!mPnoRunning) return true;
+ mPnoEventHandler = null;
+ setNetworkPriorities(settings.networkList);
+ // For supplicant based PNO, we stop the scan immediately when we reset pno list.
+ return stopPnoScan();
+ }
+
+ @Override
+ public boolean shouldScheduleBackgroundScanForPno() {
+ return false;
+ }
+
private void unscheduleScansLocked() {
mAlarmManager.cancel(mScanPeriodListener);
mLastScanSettings = null; // make sure that a running scan is marked as ended
diff --git a/service/java/com/android/server/wifi/WifiNative.java b/service/java/com/android/server/wifi/WifiNative.java
index c485a84c4..9c37f5c7c 100644
--- a/service/java/com/android/server/wifi/WifiNative.java
+++ b/service/java/com/android/server/wifi/WifiNative.java
@@ -894,7 +894,16 @@ public class WifiNative {
return doBooleanCommand("DRIVER COUNTRY");
}
+ /**
+ * Start/Stop PNO scan.
+ * @param enable boolean indicating whether PNO is being enabled or disabled.
+ */
+ public boolean setPnoScan(boolean enable) {
+ String cmd = enable ? "SET pno 1" : "SET pno 0";
+ return doBooleanCommand(cmd);
+ }
+ // TODO(rpius): Move PnoMonitor to SupplicantWifiScannerImpl.
//PNO Monitor
private class PnoMonitor {
private static final int MINIMUM_PNO_GAP = 5 * 1000;
@@ -940,8 +949,8 @@ public class WifiNative {
new IntentFilter(ACTION_TOGGLE_PNO));
}
- /* Enable/Disable PNO with updated network priorities.
- *
+ /**
+ * 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.
*/
@@ -961,8 +970,7 @@ public class WifiNative {
}
}
}
- String cmd = enable ? "SET pno 1" : "SET pno 0";
- boolean ret = doBooleanCommand(cmd);
+ boolean ret = WifiNative.this.setPnoScan(enable);
mLastPnoChangeTimeStamp = System.currentTimeMillis();
if (ret) {
mCurrentPnoState = enable;
@@ -1784,8 +1792,15 @@ public class WifiNative {
public String configKey; // kept for reference
/**
+ * Default constructor needed in WifiScanningServiceImpl.
+ * TODO(rpius): Remove both the constructors.
+ */
+ PnoNetwork() {
+ }
+
+ /**
* Constructor for the PnoNetwork object used by WifiStateMachine.
- * TODO(rpius): Remove this interface when we remove the PNO usage out of StateMachine.
+ * TODO(rpius): Remove this constructor when we remove the PNO usage out of StateMachine.
* @param config Corresponding configuration for the network
* @param newPriority Priority to be set.
*/
diff --git a/service/java/com/android/server/wifi/WifiScannerImpl.java b/service/java/com/android/server/wifi/WifiScannerImpl.java
index d425f623f..41c356c29 100644
--- a/service/java/com/android/server/wifi/WifiScannerImpl.java
+++ b/service/java/com/android/server/wifi/WifiScannerImpl.java
@@ -108,6 +108,28 @@ public abstract class WifiScannerImpl {
public abstract void restartBatchedScan();
/**
+ * Set PNO list to start PNO background scan.
+ * @param settings PNO settings for this scan.
+ * @param eventHandler Event handler for notifying the scan results.
+ * @return true if success, false otherwise
+ */
+ public abstract boolean setPnoList(WifiNative.PnoSettings settings,
+ WifiNative.PnoEventHandler eventHandler);
+
+ /**
+ * Reset PNO list to terminate PNO background scan.
+ * @param settings PNO settings for this scan.
+ * @return true if success, false otherwise
+ */
+ public abstract boolean resetPnoList(WifiNative.PnoSettings settings);
+
+ /**
+ * This returns whether a background scan should be running for PNO scan or not.
+ * @return true if background scan needs to be started, false otherwise.
+ */
+ public abstract boolean shouldScheduleBackgroundScanForPno();
+
+ /**
* Get the latest cached scan results from the last scan event. This should be called
* immediately when the scan success callback is receieved.
*/
diff --git a/service/java/com/android/server/wifi/WifiScanningServiceImpl.java b/service/java/com/android/server/wifi/WifiScanningServiceImpl.java
index 75f2cc229..6b1c92633 100644
--- a/service/java/com/android/server/wifi/WifiScanningServiceImpl.java
+++ b/service/java/com/android/server/wifi/WifiScanningServiceImpl.java
@@ -30,6 +30,7 @@ import android.net.wifi.WifiManager;
import android.net.wifi.WifiScanner;
import android.net.wifi.WifiScanner.BssidInfo;
import android.net.wifi.WifiScanner.ChannelSpec;
+import android.net.wifi.WifiScanner.PnoSettings;
import android.net.wifi.WifiScanner.ScanData;
import android.net.wifi.WifiScanner.ScanSettings;
import android.os.Binder;
@@ -187,6 +188,8 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub {
switch (msg.what) {
case WifiScanner.CMD_START_BACKGROUND_SCAN:
case WifiScanner.CMD_STOP_BACKGROUND_SCAN:
+ case WifiScanner.CMD_START_PNO_SCAN:
+ case WifiScanner.CMD_STOP_PNO_SCAN:
case WifiScanner.CMD_SET_HOTLIST:
case WifiScanner.CMD_RESET_HOTLIST:
case WifiScanner.CMD_CONFIGURE_WIFI_CHANGE:
@@ -216,7 +219,8 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub {
private static final int CMD_SCAN_PAUSED = BASE + 8;
private static final int CMD_SCAN_RESTARTED = BASE + 9;
private static final int CMD_STOP_SCAN_INTERNAL = BASE + 10;
- private static final int CMD_SCAN_FAILED = BASE + 11;
+ private static final int CMD_SCAN_FAILED = BASE + 11;
+ private static final int CMD_PNO_NETWORK_FOUND = BASE + 12;
private final Context mContext;
private final Looper mLooper;
@@ -267,7 +271,8 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub {
}
class WifiScanningStateMachine extends StateMachine implements WifiNative.ScanEventHandler,
- WifiNative.HotlistEventHandler, WifiNative.SignificantWifiChangeEventHandler {
+ WifiNative.PnoEventHandler, WifiNative.HotlistEventHandler,
+ WifiNative.SignificantWifiChangeEventHandler {
private final DefaultState mDefaultState = new DefaultState();
private final StartedState mStartedState = new StartedState();
@@ -340,6 +345,12 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub {
sendMessage(CMD_WIFI_CHANGE_DETECTED, 0, 0, results);
}
+ @Override
+ public void onPnoNetworkFound(ScanResult[] results) {
+ if (DBG) localLog("onWifiPnoNetworkFound event received");
+ sendMessage(CMD_PNO_NETWORK_FOUND, 0, 0, results);
+ }
+
class DefaultState extends State {
@Override
public void enter() {
@@ -375,6 +386,8 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub {
break;
case WifiScanner.CMD_START_BACKGROUND_SCAN:
case WifiScanner.CMD_STOP_BACKGROUND_SCAN:
+ case WifiScanner.CMD_START_PNO_SCAN:
+ case WifiScanner.CMD_STOP_PNO_SCAN:
case WifiScanner.CMD_START_SINGLE_SCAN:
case WifiScanner.CMD_STOP_SINGLE_SCAN:
case WifiScanner.CMD_SET_HOTLIST:
@@ -428,6 +441,21 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub {
case WifiScanner.CMD_STOP_BACKGROUND_SCAN:
removeScanRequest(ci, msg.arg2);
break;
+ case WifiScanner.CMD_START_PNO_SCAN:
+ Bundle pnoParams = (Bundle) msg.obj;
+ PnoSettings pnoSettings =
+ pnoParams.getParcelable(WifiScanner.PNO_PARAMS_PNO_SETTINGS_KEY);
+ ScanSettings scanSettings =
+ pnoParams.getParcelable(WifiScanner.PNO_PARAMS_SCAN_SETTINGS_KEY);
+ if (addScanRequestForPno(ci, msg.arg2, scanSettings, pnoSettings)) {
+ replySucceeded(msg);
+ } else {
+ replyFailed(msg, WifiScanner.REASON_INVALID_REQUEST, "bad request");
+ }
+ break;
+ case WifiScanner.CMD_STOP_PNO_SCAN:
+ removeScanRequestForPno(ci, msg.arg2, (PnoSettings) msg.obj);
+ break;
case WifiScanner.CMD_GET_SCAN_RESULTS:
reportScanResults(mScannerImpl.getLatestBatchedScanResults(true));
replySucceeded(msg);
@@ -507,6 +535,11 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub {
// report this)
Log.e(TAG, "WifiScanner background scan gave CMD_SCAN_TERMINATED");
break;
+ case CMD_PNO_NETWORK_FOUND: {
+ ScanResult[] results = (ScanResult[]) msg.obj;
+ reportPnoNetworkFound(results);
+ }
+ break;
default:
return NOT_HANDLED;
}
@@ -796,6 +829,17 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub {
}
}
+ void reportPnoNetworkFound(ScanResult[] results) {
+ WifiScanner.ParcelableScanResults parcelableScanResults =
+ new WifiScanner.ParcelableScanResults(results);
+ Iterator<Integer> it = mSignificantWifiHandlers.iterator();
+ while (it.hasNext()) {
+ int handler = it.next();
+ mChannel.sendMessage(WifiScanner.CMD_PNO_NETWORK_FOUND, 0, handler,
+ parcelableScanResults);
+ }
+ }
+
void cleanup() {
mScanSettings.clear();
updateSchedule();
@@ -974,6 +1018,46 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub {
}
}
+ private WifiNative.PnoSettings convertPnoSettingsToNative(PnoSettings pnoSettings) {
+ WifiNative.PnoSettings nativePnoSetting = new WifiNative.PnoSettings();
+ nativePnoSetting.min5GHzRssi = pnoSettings.min5GHzRssi;
+ nativePnoSetting.min24GHzRssi = pnoSettings.min24GHzRssi;
+ nativePnoSetting.initialScoreMax = pnoSettings.initialScoreMax;
+ nativePnoSetting.currentConnectionBonus = pnoSettings.currentConnectionBonus;
+ nativePnoSetting.sameNetworkBonus = pnoSettings.sameNetworkBonus;
+ nativePnoSetting.secureBonus = pnoSettings.secureBonus;
+ nativePnoSetting.band5GHzBonus = pnoSettings.band5GHzBonus;
+ nativePnoSetting.networkList = new WifiNative.PnoNetwork[pnoSettings.networkList.length];
+ for (int i = 0; i < pnoSettings.networkList.length; i++) {
+ nativePnoSetting.networkList[i] = new WifiNative.PnoNetwork();
+ nativePnoSetting.networkList[i].ssid = pnoSettings.networkList[i].ssid;
+ nativePnoSetting.networkList[i].networkId = pnoSettings.networkList[i].networkId;
+ nativePnoSetting.networkList[i].priority = pnoSettings.networkList[i].priority;
+ nativePnoSetting.networkList[i].flags = pnoSettings.networkList[i].flags;
+ nativePnoSetting.networkList[i].auth = pnoSettings.networkList[i].authBitField;
+ }
+ return nativePnoSetting;
+ }
+
+ boolean addScanRequestForPno(ClientInfo ci, int handler, ScanSettings settings,
+ PnoSettings pnoSettings) {
+ if (!mScannerImpl.setPnoList(convertPnoSettingsToNative(pnoSettings), mStateMachine)) {
+ return false;
+ }
+ if (!mScannerImpl.shouldScheduleBackgroundScanForPno()) {
+ return true;
+ }
+ return addScanRequest(ci, handler, settings);
+ }
+
+ void removeScanRequestForPno(ClientInfo ci, int handler, PnoSettings pnoSettings) {
+ mScannerImpl.resetPnoList(convertPnoSettingsToNative(pnoSettings));
+ if (!mScannerImpl.shouldScheduleBackgroundScanForPno()) {
+ return;
+ }
+ removeScanRequest(ci, handler);
+ }
+
boolean addSingleScanRequest(ClientInfo ci, int handler, ScanSettings settings) {
if (ci == null) {
Log.d(TAG, "Failing single scan request ClientInfo not found " + handler);
@@ -1114,6 +1198,13 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub {
}
}
+ void reportPnoNetworkFound(ScanResult[] results) {
+ Collection<ClientInfo> clients = mClients.values();
+ for (ClientInfo ci : clients) {
+ ci.reportPnoNetworkFound(results);
+ }
+ }
+
class WifiChangeStateMachine extends StateMachine
implements WifiNative.SignificantWifiChangeEventHandler {