diff options
author | Roshan Pius <rpius@google.com> | 2016-03-02 14:20:22 -0800 |
---|---|---|
committer | Roshan Pius <rpius@google.com> | 2016-03-06 20:28:23 -0800 |
commit | 9153bd67d51b305ffdd61355e0748e3c332c2caf (patch) | |
tree | 9e8f347fab576c361dc9b5f7cd6623663e5e8aef /service | |
parent | 9bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bd (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')
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 { |