SupplicantWifiScannerImpl.java revision dcd877d6c143db557884993ea437e2a432cb0ba3
19ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills/* 29ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills * Copyright (C) 2015 The Android Open Source Project 39ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills * 49ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills * Licensed under the Apache License, Version 2.0 (the "License"); 59ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills * you may not use this file except in compliance with the License. 69ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills * You may obtain a copy of the License at 79ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills * 89ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills * http://www.apache.org/licenses/LICENSE-2.0 99ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills * 109ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills * Unless required by applicable law or agreed to in writing, software 119ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills * distributed under the License is distributed on an "AS IS" BASIS, 129ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills * See the License for the specific language governing permissions and 149ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills * limitations under the License. 159ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills */ 169ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills 179ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Willspackage com.android.server.wifi; 189ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills 199ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Willsimport android.app.AlarmManager; 209ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Willsimport android.content.Context; 219ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Willsimport android.net.wifi.ScanResult; 229153bd67d51b305ffdd61355e0748e3c332c2cafRoshan Piusimport android.net.wifi.WifiConfiguration; 239ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Willsimport android.net.wifi.WifiScanner; 249ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Willsimport android.os.Handler; 259ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Willsimport android.os.Looper; 269ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Willsimport android.os.Message; 279ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Willsimport android.os.SystemClock; 289ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Willsimport android.util.Log; 299ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills 3062bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Piusimport com.android.internal.R; 317e3e85327ca82a83de84b4750e793f2e3d1b3bfcMitchell Willsimport com.android.server.wifi.scanner.ChannelHelper; 327e3e85327ca82a83de84b4750e793f2e3d1b3bfcMitchell Willsimport com.android.server.wifi.scanner.ChannelHelper.ChannelCollection; 337e3e85327ca82a83de84b4750e793f2e3d1b3bfcMitchell Willsimport com.android.server.wifi.scanner.NoBandChannelHelper; 347e3e85327ca82a83de84b4750e793f2e3d1b3bfcMitchell Wills 359ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Willsimport java.util.ArrayDeque; 369ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Willsimport java.util.ArrayList; 379ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Willsimport java.util.Arrays; 389ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Willsimport java.util.Collections; 39d74ff28cdb01d3f711e0b0f0e99e51fdb221eaf2Roshan Piusimport java.util.HashSet; 409ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Willsimport java.util.List; 419ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Willsimport java.util.Set; 429ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills 43f2f6f79242454ff9161f5af772292fa0180436f8Mitchell Wills/** 445fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills * Implementation of the WifiScanner HAL API that uses wpa_supplicant to perform all scans 45f2f6f79242454ff9161f5af772292fa0180436f8Mitchell Wills * @see com.android.server.wifi.WifiScannerImpl for more details on each method 46f2f6f79242454ff9161f5af772292fa0180436f8Mitchell Wills */ 479ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Willspublic class SupplicantWifiScannerImpl extends WifiScannerImpl implements Handler.Callback { 489ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills private static final String TAG = "SupplicantWifiScannerImpl"; 499ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills private static final boolean DBG = false; 509ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills 519ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills private static final int SCAN_BUFFER_CAPACITY = 10; 529ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills private static final int MAX_APS_PER_SCAN = 32; 539ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills private static final int MAX_SCAN_BUCKETS = 16; 549ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills 559ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills private static final String ACTION_SCAN_PERIOD = 569ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills "com.android.server.util.SupplicantWifiScannerImpl.action.SCAN_PERIOD"; 579ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills 589ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills private final Context mContext; 599ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills private final WifiNative mWifiNative; 609ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills private final AlarmManager mAlarmManager; 619ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills private final Handler mEventHandler; 627e3e85327ca82a83de84b4750e793f2e3d1b3bfcMitchell Wills private final ChannelHelper mChannelHelper; 639ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills 649ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills private Object mSettingsLock = new Object(); 659ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills 669ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills // Next scan settings to apply when the previous scan completes 675fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills private WifiNative.ScanSettings mPendingBackgroundScanSettings = null; 685fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills private WifiNative.ScanEventHandler mPendingBackgroundScanEventHandler = null; 695fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills private WifiNative.ScanSettings mPendingSingleScanSettings = null; 705fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills private WifiNative.ScanEventHandler mPendingSingleScanEventHandler = null; 715fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills 725fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills // Active background scan settings/state 735fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills private WifiNative.ScanSettings mBackgroundScanSettings = null; 745fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills private WifiNative.ScanEventHandler mBackgroundScanEventHandler = null; 755fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills private int mNextBackgroundScanPeriod = 0; 765fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills private int mNextBackgroundScanId = 0; 775fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills private boolean mBackgroundScanPeriodPending = false; 785fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills private boolean mBackgroundScanPaused = false; 795fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills private ScanBuffer mBackgroundScanBuffer = new ScanBuffer(SCAN_BUFFER_CAPACITY); 805fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills 815fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills private WifiScanner.ScanData mLatestSingleScanResult = 825fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills new WifiScanner.ScanData(0, 0, new ScanResult[0]); 835fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills 845fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills // Settings for the currently running scan, null if no scan active 859ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills private LastScanSettings mLastScanSettings = null; 869ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills 879ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills // Active hotlist settings 889ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills private WifiNative.HotlistEventHandler mHotlistHandler = null; 899ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills private ChangeBuffer mHotlistChangeBuffer = new ChangeBuffer(); 909ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills 919153bd67d51b305ffdd61355e0748e3c332c2cafRoshan Pius // Pno related info. 92063cfc7e3eef78fcbda24a66f0c473828b39c854Roshan Pius private WifiNative.PnoSettings mPnoSettings = null; 939153bd67d51b305ffdd61355e0748e3c332c2cafRoshan Pius private WifiNative.PnoEventHandler mPnoEventHandler; 9462bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius private boolean mHwPnoRunning = false; 9562bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius private final boolean mHwPnoScanSupported; 969153bd67d51b305ffdd61355e0748e3c332c2cafRoshan Pius 9741e38d84f562e12198f7db0d45f633712cae6cbaMitchell Wills AlarmManager.OnAlarmListener mScanPeriodListener = new AlarmManager.OnAlarmListener() { 9841e38d84f562e12198f7db0d45f633712cae6cbaMitchell Wills public void onAlarm() { 9941e38d84f562e12198f7db0d45f633712cae6cbaMitchell Wills synchronized (mSettingsLock) { 10041e38d84f562e12198f7db0d45f633712cae6cbaMitchell Wills handleScanPeriod(); 10141e38d84f562e12198f7db0d45f633712cae6cbaMitchell Wills } 10241e38d84f562e12198f7db0d45f633712cae6cbaMitchell Wills } 10341e38d84f562e12198f7db0d45f633712cae6cbaMitchell Wills }; 10441e38d84f562e12198f7db0d45f633712cae6cbaMitchell Wills 1052332e9ea1b691fa0ea3a340feec159f2040aa6caRoshan Pius public SupplicantWifiScannerImpl(Context context, WifiNative wifiNative, 1062332e9ea1b691fa0ea3a340feec159f2040aa6caRoshan Pius ChannelHelper channelHelper, Looper looper) { 1079ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills mContext = context; 1089ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills mWifiNative = wifiNative; 1092332e9ea1b691fa0ea3a340feec159f2040aa6caRoshan Pius mChannelHelper = channelHelper; 1109ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills mAlarmManager = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE); 1119ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills mEventHandler = new Handler(looper, this); 1127d2d8c27647676c51208e417afbb8dd6c6784b7cMitchell Wills 11362bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius // Check if the device supports HW PNO scans. 11462bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius mHwPnoScanSupported = mContext.getResources().getBoolean( 11562bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius R.bool.config_wifi_background_scan_support); 11662bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius 1178adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills WifiMonitor.getInstance().registerHandler(mWifiNative.getInterfaceName(), 1188adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills WifiMonitor.SCAN_FAILED_EVENT, mEventHandler); 1198adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills WifiMonitor.getInstance().registerHandler(mWifiNative.getInterfaceName(), 1208adb4e72f58e3e25918f33e0b2687e6acc14c47dMitchell Wills WifiMonitor.SCAN_RESULTS_EVENT, mEventHandler); 1219ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills } 1229ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills 1232332e9ea1b691fa0ea3a340feec159f2040aa6caRoshan Pius public SupplicantWifiScannerImpl(Context context, WifiNative wifiNative, Looper looper) { 1242332e9ea1b691fa0ea3a340feec159f2040aa6caRoshan Pius // TODO figure out how to get channel information from supplicant 1252332e9ea1b691fa0ea3a340feec159f2040aa6caRoshan Pius this(context, wifiNative, new NoBandChannelHelper(), looper); 1262332e9ea1b691fa0ea3a340feec159f2040aa6caRoshan Pius } 1272332e9ea1b691fa0ea3a340feec159f2040aa6caRoshan Pius 1289ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills @Override 1291e806a7aac77f6f65ba299329e1fc452e0148b8dMitchell Wills public void cleanup() { 1301e806a7aac77f6f65ba299329e1fc452e0148b8dMitchell Wills synchronized (mSettingsLock) { 1311e806a7aac77f6f65ba299329e1fc452e0148b8dMitchell Wills mPendingSingleScanSettings = null; 1321e806a7aac77f6f65ba299329e1fc452e0148b8dMitchell Wills mPendingSingleScanEventHandler = null; 13362bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius stopHwPnoScan(); 1341e806a7aac77f6f65ba299329e1fc452e0148b8dMitchell Wills stopBatchedScan(); 1351e806a7aac77f6f65ba299329e1fc452e0148b8dMitchell Wills resetHotlist(); 1361e806a7aac77f6f65ba299329e1fc452e0148b8dMitchell Wills untrackSignificantWifiChange(); 1371e806a7aac77f6f65ba299329e1fc452e0148b8dMitchell Wills mLastScanSettings = null; // finally clear any active scan 1382332e9ea1b691fa0ea3a340feec159f2040aa6caRoshan Pius // TODO(b/27677054): Remove this once all PNO scans are started via Scanner 1392332e9ea1b691fa0ea3a340feec159f2040aa6caRoshan Pius mWifiNative.resumeBackgroundScan(); 1401e806a7aac77f6f65ba299329e1fc452e0148b8dMitchell Wills } 1411e806a7aac77f6f65ba299329e1fc452e0148b8dMitchell Wills } 1421e806a7aac77f6f65ba299329e1fc452e0148b8dMitchell Wills 1431e806a7aac77f6f65ba299329e1fc452e0148b8dMitchell Wills @Override 1449ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills public boolean getScanCapabilities(WifiNative.ScanCapabilities capabilities) { 1459ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills capabilities.max_scan_cache_size = Integer.MAX_VALUE; 1469ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills capabilities.max_scan_buckets = MAX_SCAN_BUCKETS; 1479ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills capabilities.max_ap_cache_per_scan = MAX_APS_PER_SCAN; 1489ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills capabilities.max_rssi_sample_size = 8; 1499ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills capabilities.max_scan_reporting_threshold = SCAN_BUFFER_CAPACITY; 1509ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills capabilities.max_hotlist_bssids = 0; 1519ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills capabilities.max_significant_wifi_change_aps = 0; 1527d2d8c27647676c51208e417afbb8dd6c6784b7cMitchell Wills // TODO reenable once scan results handlers are enabled again 1537d2d8c27647676c51208e417afbb8dd6c6784b7cMitchell Wills return false; 1549ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills } 1559ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills 1569ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills @Override 1577e3e85327ca82a83de84b4750e793f2e3d1b3bfcMitchell Wills public ChannelHelper getChannelHelper() { 1587e3e85327ca82a83de84b4750e793f2e3d1b3bfcMitchell Wills return mChannelHelper; 1597e3e85327ca82a83de84b4750e793f2e3d1b3bfcMitchell Wills } 1607e3e85327ca82a83de84b4750e793f2e3d1b3bfcMitchell Wills 1617e3e85327ca82a83de84b4750e793f2e3d1b3bfcMitchell Wills @Override 162f2f6f79242454ff9161f5af772292fa0180436f8Mitchell Wills public boolean startSingleScan(WifiNative.ScanSettings settings, 163f2f6f79242454ff9161f5af772292fa0180436f8Mitchell Wills WifiNative.ScanEventHandler eventHandler) { 1645fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills if (eventHandler == null || settings == null) { 1655fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills Log.w(TAG, "Invalid arguments for startSingleScan: settings=" + settings 1665fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills + ",eventHandler=" + eventHandler); 1675fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills return false; 1685fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills } 1695fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills if (mPendingSingleScanSettings != null 1705fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills || (mLastScanSettings != null && mLastScanSettings.singleScanActive)) { 1715fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills Log.w(TAG, "A single scan is already running"); 1725fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills return false; 1735fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills } 1745fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills synchronized (mSettingsLock) { 1755fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills mPendingSingleScanSettings = settings; 1765fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills mPendingSingleScanEventHandler = eventHandler; 1775fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills processPendingScans(); 1785fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills return true; 1795fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills } 180f2f6f79242454ff9161f5af772292fa0180436f8Mitchell Wills } 181f2f6f79242454ff9161f5af772292fa0180436f8Mitchell Wills 182f2f6f79242454ff9161f5af772292fa0180436f8Mitchell Wills @Override 183f2f6f79242454ff9161f5af772292fa0180436f8Mitchell Wills public WifiScanner.ScanData getLatestSingleScanResults() { 1845fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills return mLatestSingleScanResult; 185f2f6f79242454ff9161f5af772292fa0180436f8Mitchell Wills } 186f2f6f79242454ff9161f5af772292fa0180436f8Mitchell Wills 187f2f6f79242454ff9161f5af772292fa0180436f8Mitchell Wills @Override 1889ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills public boolean startBatchedScan(WifiNative.ScanSettings settings, 1899ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills WifiNative.ScanEventHandler eventHandler) { 1905fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills if (settings == null || eventHandler == null) { 1915fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills Log.w(TAG, "Invalid arguments for startBatched: settings=" + settings 1925fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills + ",eventHandler=" + eventHandler); 1939ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills return false; 1945fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills } 1959ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills 1965fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills if (settings.max_ap_per_scan < 0 || settings.max_ap_per_scan > MAX_APS_PER_SCAN) { 1979ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills return false; 1985fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills } 1995fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills if (settings.num_buckets < 0 || settings.num_buckets > MAX_SCAN_BUCKETS) { 2009ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills return false; 2015fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills } 2025fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills if (settings.report_threshold_num_scans < 0 2035fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills || settings.report_threshold_num_scans > SCAN_BUFFER_CAPACITY) { 2049ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills return false; 2055fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills } 2065fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills if (settings.report_threshold_percent < 0 || settings.report_threshold_percent > 100) { 2079ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills return false; 2085fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills } 2095fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills if (settings.base_period_ms <= 0) { 2109ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills return false; 2115fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills } 2129ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills for (int i = 0; i < settings.num_buckets; ++i) { 2139ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills WifiNative.BucketSettings bucket = settings.buckets[i]; 2145fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills if (bucket.period_ms % settings.base_period_ms != 0) { 2159ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills return false; 2165fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills } 2179ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills } 2189ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills 2195fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills synchronized (mSettingsLock) { 2209ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills stopBatchedScan(); 2215fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills Log.d(TAG, "Starting scan num_buckets=" + settings.num_buckets + ", base_period=" 2225fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills + settings.base_period_ms + " ms"); 2235fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills mPendingBackgroundScanSettings = settings; 2245fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills mPendingBackgroundScanEventHandler = eventHandler; 2259ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills handleScanPeriod(); // Try to start scan immediately 2269ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills return true; 2279ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills } 2289ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills } 2299ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills 2309ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills @Override 2319ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills public void stopBatchedScan() { 2325fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills synchronized (mSettingsLock) { 2335fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills if (DBG) Log.d(TAG, "Stopping scan"); 2345fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills mBackgroundScanSettings = null; 2355fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills mBackgroundScanEventHandler = null; 2365fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills mPendingBackgroundScanSettings = null; 2375fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills mPendingBackgroundScanEventHandler = null; 2385fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills mBackgroundScanPaused = false; 2395fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills mBackgroundScanPeriodPending = false; 2409ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills unscheduleScansLocked(); 2419ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills } 2421e806a7aac77f6f65ba299329e1fc452e0148b8dMitchell Wills processPendingScans(); 2439ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills } 2449ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills 2459ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills @Override 2469ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills public void pauseBatchedScan() { 2475fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills synchronized (mSettingsLock) { 2485fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills if (DBG) Log.d(TAG, "Pausing scan"); 2499ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills // if there isn't a pending scan then make the current scan pending 2505fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills if (mPendingBackgroundScanSettings == null) { 2515fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills mPendingBackgroundScanSettings = mBackgroundScanSettings; 2525fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills mPendingBackgroundScanEventHandler = mBackgroundScanEventHandler; 2539ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills } 2545fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills mBackgroundScanSettings = null; 2555fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills mBackgroundScanEventHandler = null; 2565fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills mBackgroundScanPeriodPending = false; 2575fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills mBackgroundScanPaused = true; 2589ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills 2599ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills unscheduleScansLocked(); 2609ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills 2619ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills WifiScanner.ScanData[] results = getLatestBatchedScanResults(/* flush = */ true); 2625fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills if (mPendingBackgroundScanEventHandler != null) { 2635fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills mPendingBackgroundScanEventHandler.onScanPaused(results); 2645fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills } 2659ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills } 2661e806a7aac77f6f65ba299329e1fc452e0148b8dMitchell Wills processPendingScans(); 2679ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills } 2689ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills 2699ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills @Override 2709ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills public void restartBatchedScan() { 2715fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills synchronized (mSettingsLock) { 2725fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills if (DBG) Log.d(TAG, "Restarting scan"); 2735fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills if (mPendingBackgroundScanEventHandler != null) { 2745fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills mPendingBackgroundScanEventHandler.onScanRestarted(); 2755fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills } 2765fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills mBackgroundScanPaused = false; 2779ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills handleScanPeriod(); 2789ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills } 2799ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills } 2809ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills 2819ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills private void unscheduleScansLocked() { 28241e38d84f562e12198f7db0d45f633712cae6cbaMitchell Wills mAlarmManager.cancel(mScanPeriodListener); 2831e806a7aac77f6f65ba299329e1fc452e0148b8dMitchell Wills if (mLastScanSettings != null) { 2841e806a7aac77f6f65ba299329e1fc452e0148b8dMitchell Wills mLastScanSettings.backgroundScanActive = false; 2851e806a7aac77f6f65ba299329e1fc452e0148b8dMitchell Wills } 2869ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills } 2879ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills 2889ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills private void handleScanPeriod() { 2895fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills synchronized (mSettingsLock) { 2905fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills mBackgroundScanPeriodPending = true; 2915fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills processPendingScans(); 2925fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills } 2935fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills } 2945fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills 2955fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills private void processPendingScans() { 2965fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills synchronized (mSettingsLock) { 29762bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius // Wait for the active scan result to come back to reschedule other scans, 29862bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius // unless if HW pno scan is running. Hw PNO scans are paused it if there 29962bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius // are other pending scans, 30062bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius if (mLastScanSettings != null && !mLastScanSettings.hwPnoScanActive) { 3019ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills return; 3029ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills } 3039ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills 3047e3e85327ca82a83de84b4750e793f2e3d1b3bfcMitchell Wills ChannelCollection allFreqs = mChannelHelper.createChannelCollection(); 305d74ff28cdb01d3f711e0b0f0e99e51fdb221eaf2Roshan Pius Set<Integer> hiddenNetworkIdSet = new HashSet<Integer>(); 30663539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills final LastScanSettings newScanSettings = 30763539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills new LastScanSettings(SystemClock.elapsedRealtime()); 3089ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills 3095fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills // Update scan settings if there is a pending scan 3105fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills if (!mBackgroundScanPaused) { 3115fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills if (mPendingBackgroundScanSettings != null) { 3125fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills mBackgroundScanSettings = mPendingBackgroundScanSettings; 3135fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills mBackgroundScanEventHandler = mPendingBackgroundScanEventHandler; 3145fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills mNextBackgroundScanPeriod = 0; 3155fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills mPendingBackgroundScanSettings = null; 3165fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills mPendingBackgroundScanEventHandler = null; 3175fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills mBackgroundScanPeriodPending = true; 3185fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills } 3195fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills if (mBackgroundScanPeriodPending) { 3205fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills if (mBackgroundScanSettings != null) { 3215fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills int reportEvents = WifiScanner.REPORT_EVENT_NO_BATCH; // default to no batch 3225fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills for (int bucket_id = 0; bucket_id < mBackgroundScanSettings.num_buckets; 3235fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills ++bucket_id) { 3245fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills WifiNative.BucketSettings bucket = 3255fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills mBackgroundScanSettings.buckets[bucket_id]; 3265fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills if (mNextBackgroundScanPeriod % (bucket.period_ms 3275fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills / mBackgroundScanSettings.base_period_ms) == 0) { 3285fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills if ((bucket.report_events 3295fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills & WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN) != 0) { 3305fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills reportEvents |= WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN; 3315fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills } 3325fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills if ((bucket.report_events 3335fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills & WifiScanner.REPORT_EVENT_FULL_SCAN_RESULT) != 0) { 3345fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills reportEvents |= WifiScanner.REPORT_EVENT_FULL_SCAN_RESULT; 3355fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills } 3365fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills // only no batch if all buckets specify it 3375fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills if ((bucket.report_events 3385fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills & WifiScanner.REPORT_EVENT_NO_BATCH) == 0) { 3395fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills reportEvents &= ~WifiScanner.REPORT_EVENT_NO_BATCH; 3405fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills } 3415fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills 3427e3e85327ca82a83de84b4750e793f2e3d1b3bfcMitchell Wills allFreqs.addChannels(bucket); 3439ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills } 3449ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills } 3457e3e85327ca82a83de84b4750e793f2e3d1b3bfcMitchell Wills if (!allFreqs.isEmpty()) { 3465fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills newScanSettings.setBackgroundScan(mNextBackgroundScanId++, 3475fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills mBackgroundScanSettings.max_ap_per_scan, reportEvents, 3485fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills mBackgroundScanSettings.report_threshold_num_scans, 3495fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills mBackgroundScanSettings.report_threshold_percent); 35062bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius // When PNO scan is enabled and HW does not support PNO scans, 35162bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius // tag SwPno as enabled for each background scan 352dcd877d6c143db557884993ea437e2a432cb0ba3Roshan Pius if (isSwPnoScanRequired()) { 35362bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius newScanSettings.setSwPnoScan(mPnoEventHandler); 35462bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius } 3559ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills } 35662bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius 357d74ff28cdb01d3f711e0b0f0e99e51fdb221eaf2Roshan Pius int[] hiddenNetworkIds = mBackgroundScanSettings.hiddenNetworkIds; 358d74ff28cdb01d3f711e0b0f0e99e51fdb221eaf2Roshan Pius if (hiddenNetworkIds != null) { 359d74ff28cdb01d3f711e0b0f0e99e51fdb221eaf2Roshan Pius for (int i = 0; i < hiddenNetworkIds.length; i++) { 360d74ff28cdb01d3f711e0b0f0e99e51fdb221eaf2Roshan Pius hiddenNetworkIdSet.add(hiddenNetworkIds[i]); 361d74ff28cdb01d3f711e0b0f0e99e51fdb221eaf2Roshan Pius } 362d74ff28cdb01d3f711e0b0f0e99e51fdb221eaf2Roshan Pius } 3639ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills } 3645fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills 3655fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills mNextBackgroundScanPeriod++; 3665fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills mBackgroundScanPeriodPending = false; 3675fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills mAlarmManager.set(AlarmManager.RTC_WAKEUP, 3685fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills System.currentTimeMillis() + mBackgroundScanSettings.base_period_ms, 3695fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills "SupplicantWifiScannerImpl Period", 3705fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills mScanPeriodListener, mEventHandler); 3719ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills } 3725fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills } 3735fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills 3745fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills if (mPendingSingleScanSettings != null) { 3755fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills boolean reportFullResults = false; 3767e3e85327ca82a83de84b4750e793f2e3d1b3bfcMitchell Wills ChannelCollection singleScanFreqs = mChannelHelper.createChannelCollection(); 3775fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills for (int i = 0; i < mPendingSingleScanSettings.num_buckets; ++i) { 3785fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills WifiNative.BucketSettings bucketSettings = 3795fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills mPendingSingleScanSettings.buckets[i]; 3805fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills if ((bucketSettings.report_events 3815fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills & WifiScanner.REPORT_EVENT_FULL_SCAN_RESULT) != 0) { 3825fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills reportFullResults = true; 3839ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills } 3847e3e85327ca82a83de84b4750e793f2e3d1b3bfcMitchell Wills singleScanFreqs.addChannels(bucketSettings); 3857e3e85327ca82a83de84b4750e793f2e3d1b3bfcMitchell Wills allFreqs.addChannels(bucketSettings); 3869ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills } 3875fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills newScanSettings.setSingleScan(reportFullResults, singleScanFreqs, 3885fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills mPendingSingleScanEventHandler); 389d74ff28cdb01d3f711e0b0f0e99e51fdb221eaf2Roshan Pius int[] hiddenNetworkIds = mPendingSingleScanSettings.hiddenNetworkIds; 390d74ff28cdb01d3f711e0b0f0e99e51fdb221eaf2Roshan Pius if (hiddenNetworkIds != null) { 391d74ff28cdb01d3f711e0b0f0e99e51fdb221eaf2Roshan Pius for (int i = 0; i < hiddenNetworkIds.length; i++) { 392d74ff28cdb01d3f711e0b0f0e99e51fdb221eaf2Roshan Pius hiddenNetworkIdSet.add(hiddenNetworkIds[i]); 393d74ff28cdb01d3f711e0b0f0e99e51fdb221eaf2Roshan Pius } 394d74ff28cdb01d3f711e0b0f0e99e51fdb221eaf2Roshan Pius } 3955fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills mPendingSingleScanSettings = null; 3965fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills mPendingSingleScanEventHandler = null; 3975fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills } 3985fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills 39962bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius if ((newScanSettings.backgroundScanActive || newScanSettings.singleScanActive) 40062bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius && !allFreqs.isEmpty()) { 40162bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius pauseHwPnoScan(); 4022332e9ea1b691fa0ea3a340feec159f2040aa6caRoshan Pius // TODO(b/27677054): Remove this once all PNO scans are started via Scanner 4032332e9ea1b691fa0ea3a340feec159f2040aa6caRoshan Pius mWifiNative.pauseBackgroundScan(); 4047e3e85327ca82a83de84b4750e793f2e3d1b3bfcMitchell Wills Set<Integer> freqs = allFreqs.getSupplicantScanFreqs(); 405d74ff28cdb01d3f711e0b0f0e99e51fdb221eaf2Roshan Pius boolean success = mWifiNative.scan(freqs, hiddenNetworkIdSet); 4065fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills if (success) { 4075fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills // TODO handle scan timeout 40863539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills Log.d(TAG, "Starting wifi scan for freqs=" + freqs 4095fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills + ", background=" + newScanSettings.backgroundScanActive 4105fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills + ", single=" + newScanSettings.singleScanActive); 4115fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills mLastScanSettings = newScanSettings; 4125fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills } else { 41363539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills Log.e(TAG, "Failed to start scan, freqs=" + freqs); 41463539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills // indicate scan failure async 41563539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills mEventHandler.post(new Runnable() { 41663539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills public void run() { 41763539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills newScanSettings.singleScanActive = false; 41863539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills if (newScanSettings.singleScanEventHandler != null) { 41963539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills newScanSettings.singleScanEventHandler 42063539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills .onScanStatus(WifiNative.WIFI_SCAN_FAILED); 42163539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills } 42263539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills } 42363539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills }); 42463539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills // TODO if scans fail enough background scans should be failed as well 4255fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills } 426dcd877d6c143db557884993ea437e2a432cb0ba3Roshan Pius } else if (isHwPnoScanRequired()) { 42762bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius newScanSettings.setHwPnoScan(mPnoEventHandler); 42862bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius boolean success = resumeHwPnoScan(); 429063cfc7e3eef78fcbda24a66f0c473828b39c854Roshan Pius if (success) { 430063cfc7e3eef78fcbda24a66f0c473828b39c854Roshan Pius Log.d(TAG, "Starting wifi PNO scan"); 431063cfc7e3eef78fcbda24a66f0c473828b39c854Roshan Pius mLastScanSettings = newScanSettings; 432063cfc7e3eef78fcbda24a66f0c473828b39c854Roshan Pius } else { 433063cfc7e3eef78fcbda24a66f0c473828b39c854Roshan Pius Log.e(TAG, "Failed to start PNO scan"); 434063cfc7e3eef78fcbda24a66f0c473828b39c854Roshan Pius // indicate scan failure async 435063cfc7e3eef78fcbda24a66f0c473828b39c854Roshan Pius mEventHandler.post(new Runnable() { 436063cfc7e3eef78fcbda24a66f0c473828b39c854Roshan Pius public void run() { 437063cfc7e3eef78fcbda24a66f0c473828b39c854Roshan Pius if (mPnoEventHandler != null) { 438063cfc7e3eef78fcbda24a66f0c473828b39c854Roshan Pius mPnoEventHandler.onPnoScanFailed(); 439063cfc7e3eef78fcbda24a66f0c473828b39c854Roshan Pius } 440063cfc7e3eef78fcbda24a66f0c473828b39c854Roshan Pius // Clean up PNO state, we don't want to continue PNO scanning. 441063cfc7e3eef78fcbda24a66f0c473828b39c854Roshan Pius mPnoSettings = null; 442063cfc7e3eef78fcbda24a66f0c473828b39c854Roshan Pius mPnoEventHandler = null; 443063cfc7e3eef78fcbda24a66f0c473828b39c854Roshan Pius } 444063cfc7e3eef78fcbda24a66f0c473828b39c854Roshan Pius }); 445063cfc7e3eef78fcbda24a66f0c473828b39c854Roshan Pius } 4462332e9ea1b691fa0ea3a340feec159f2040aa6caRoshan Pius } else { 4472332e9ea1b691fa0ea3a340feec159f2040aa6caRoshan Pius // TODO(b/27677054): Remove this once all PNO scans are started via Scanner 4482332e9ea1b691fa0ea3a340feec159f2040aa6caRoshan Pius mWifiNative.resumeBackgroundScan(); 4499ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills } 4509ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills } 4519ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills } 4529ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills 4539ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills @Override 4549ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills public boolean handleMessage(Message msg) { 4559ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills switch(msg.what) { 4569ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills case WifiMonitor.SCAN_FAILED_EVENT: 457f2f6f79242454ff9161f5af772292fa0180436f8Mitchell Wills // TODO indicate failure to caller 4589ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills Log.w(TAG, "Scan failed"); 4599ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills synchronized (mSettingsLock) { 4609ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills mLastScanSettings = null; 4619ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills } 4625fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills processPendingScans(); 4639ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills break; 4649ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills case WifiMonitor.SCAN_RESULTS_EVENT: 4659ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills pollLatestScanData(); 4665fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills processPendingScans(); 4679ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills break; 4689ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills default: 4699ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills // ignore unknown event 4709ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills } 4719ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills return true; 4729ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills } 4739ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills 4749ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills private void pollLatestScanData() { 4755fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills synchronized (mSettingsLock) { 4765fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills if (mLastScanSettings == null) { 4779ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills // got a scan before we started scanning or after scan was canceled 4789ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills return; 4799ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills } 4809ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills 4815fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills if (DBG) Log.d(TAG, "Polling scan data for scan: " + mLastScanSettings.scanId); 4829ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills ArrayList<ScanDetail> nativeResults = mWifiNative.getScanResults(); 4835fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills List<ScanResult> singleScanResults = new ArrayList<>(); 4845fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills List<ScanResult> backgroundScanResults = new ArrayList<>(); 48562bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius List<ScanResult> hwPnoScanResults = new ArrayList<>(); 4869ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills for (int i = 0; i < nativeResults.size(); ++i) { 4879ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills ScanResult result = nativeResults.get(i).getScanResult(); 4889ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills long timestamp_ms = result.timestamp / 1000; // convert us -> ms 4899ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills if (timestamp_ms > mLastScanSettings.startTime) { 4905fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills if (mLastScanSettings.backgroundScanActive) { 4915fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills backgroundScanResults.add(result); 4925fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills } 4935fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills if (mLastScanSettings.singleScanActive 4947e3e85327ca82a83de84b4750e793f2e3d1b3bfcMitchell Wills && mLastScanSettings.singleScanFreqs.containsChannel( 4957e3e85327ca82a83de84b4750e793f2e3d1b3bfcMitchell Wills result.frequency)) { 4965fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills singleScanResults.add(result); 4975fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills } 49862bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius if (mLastScanSettings.hwPnoScanActive) { 49962bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius hwPnoScanResults.add(result); 500063cfc7e3eef78fcbda24a66f0c473828b39c854Roshan Pius } 5015fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills } else { 5029ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills // was a cached result in wpa_supplicant 5039ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills } 5049ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills } 50541e38d84f562e12198f7db0d45f633712cae6cbaMitchell Wills 5065fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills if (mLastScanSettings.backgroundScanActive) { 5075fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills if (mBackgroundScanEventHandler != null) { 5085fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills if ((mLastScanSettings.reportEvents 5095fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills & WifiScanner.REPORT_EVENT_FULL_SCAN_RESULT) != 0) { 5105fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills for (ScanResult scanResult : backgroundScanResults) { 5115fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills mBackgroundScanEventHandler.onFullScanResult(scanResult); 5125fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills } 51341e38d84f562e12198f7db0d45f633712cae6cbaMitchell Wills } 51441e38d84f562e12198f7db0d45f633712cae6cbaMitchell Wills } 51541e38d84f562e12198f7db0d45f633712cae6cbaMitchell Wills 5162771787818003e53e8175036a3d09688c783f350Mitchell Wills Collections.sort(backgroundScanResults, SCAN_RESULT_SORT_COMPARATOR); 5175fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills ScanResult[] scanResultsArray = new ScanResult[Math.min(mLastScanSettings.maxAps, 5185fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills backgroundScanResults.size())]; 5195fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills for (int i = 0; i < scanResultsArray.length; ++i) { 5205fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills scanResultsArray[i] = backgroundScanResults.get(i); 5215fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills } 5229ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills 5235fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills if ((mLastScanSettings.reportEvents & WifiScanner.REPORT_EVENT_NO_BATCH) == 0) { 5245fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills mBackgroundScanBuffer.add(new WifiScanner.ScanData(mLastScanSettings.scanId, 0, 5255fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills scanResultsArray)); 5265fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills } 5279ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills 5285fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills if (mBackgroundScanEventHandler != null) { 5295fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills if ((mLastScanSettings.reportEvents 5305fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills & WifiScanner.REPORT_EVENT_FULL_SCAN_RESULT) != 0 5315fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills || (mLastScanSettings.reportEvents 5325fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills & WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN) != 0 5335fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills || (mLastScanSettings.reportEvents 5345fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills == WifiScanner.REPORT_EVENT_AFTER_BUFFER_FULL 5355fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills && (mBackgroundScanBuffer.size() 5365fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills >= (mBackgroundScanBuffer.capacity() 5375fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills * mLastScanSettings.reportPercentThreshold 5385fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills / 100) 5395fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills || mBackgroundScanBuffer.size() 5405fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills >= mLastScanSettings.reportNumScansThreshold))) { 54163539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills mBackgroundScanEventHandler 54263539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills .onScanStatus(WifiNative.WIFI_SCAN_RESULTS_AVAILABLE); 5435fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills } 5449ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills } 5459ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills 5465fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills if (mHotlistHandler != null) { 5475fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills int event = mHotlistChangeBuffer.processScan(backgroundScanResults); 5485fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills if ((event & ChangeBuffer.EVENT_FOUND) != 0) { 5495fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills mHotlistHandler.onHotlistApFound( 5505fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills mHotlistChangeBuffer.getLastResults(ChangeBuffer.EVENT_FOUND)); 5515fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills } 5525fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills if ((event & ChangeBuffer.EVENT_LOST) != 0) { 5535fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills mHotlistHandler.onHotlistApLost( 5545fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills mHotlistChangeBuffer.getLastResults(ChangeBuffer.EVENT_LOST)); 5555fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills } 5569ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills } 55762bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius // All background scan results when SW PNO scan is active will be reported to the 55862bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius // PNO listener 55962bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius if (mLastScanSettings.swPnoScanActive 56062bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius && mLastScanSettings.pnoScanEventHandler != null) { 56162bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius mLastScanSettings.pnoScanEventHandler.onPnoNetworkFound(scanResultsArray); 56262bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius } 5635fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills } 5645fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills 5655fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills if (mLastScanSettings.singleScanActive 5665fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills && mLastScanSettings.singleScanEventHandler != null) { 5675fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills if (mLastScanSettings.reportSingleScanFullResults) { 5685fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills for (ScanResult scanResult : singleScanResults) { 5695fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills mLastScanSettings.singleScanEventHandler.onFullScanResult(scanResult); 5705fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills } 5719ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills } 5722771787818003e53e8175036a3d09688c783f350Mitchell Wills Collections.sort(singleScanResults, SCAN_RESULT_SORT_COMPARATOR); 5735fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills mLatestSingleScanResult = new WifiScanner.ScanData(mLastScanSettings.scanId, 0, 5745fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills singleScanResults.toArray(new ScanResult[singleScanResults.size()])); 57563539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills mLastScanSettings.singleScanEventHandler 57663539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills .onScanStatus(WifiNative.WIFI_SCAN_RESULTS_AVAILABLE); 5779ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills } 5785fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills 57962bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius if (mLastScanSettings.hwPnoScanActive 580063cfc7e3eef78fcbda24a66f0c473828b39c854Roshan Pius && mLastScanSettings.pnoScanEventHandler != null) { 58162bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius ScanResult[] pnoScanResultsArray = new ScanResult[hwPnoScanResults.size()]; 582063cfc7e3eef78fcbda24a66f0c473828b39c854Roshan Pius for (int i = 0; i < pnoScanResultsArray.length; ++i) { 58362bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius pnoScanResultsArray[i] = hwPnoScanResults.get(i); 584063cfc7e3eef78fcbda24a66f0c473828b39c854Roshan Pius } 585063cfc7e3eef78fcbda24a66f0c473828b39c854Roshan Pius mLastScanSettings.pnoScanEventHandler.onPnoNetworkFound(pnoScanResultsArray); 586063cfc7e3eef78fcbda24a66f0c473828b39c854Roshan Pius } 587063cfc7e3eef78fcbda24a66f0c473828b39c854Roshan Pius 5885fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills mLastScanSettings = null; 5899ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills } 5909ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills } 5919ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills 5929ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills 5939ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills @Override 5949ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills public WifiScanner.ScanData[] getLatestBatchedScanResults(boolean flush) { 5955fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills synchronized (mSettingsLock) { 5965fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills WifiScanner.ScanData[] results = mBackgroundScanBuffer.get(); 59741e38d84f562e12198f7db0d45f633712cae6cbaMitchell Wills if (flush) { 5985fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills mBackgroundScanBuffer.clear(); 59941e38d84f562e12198f7db0d45f633712cae6cbaMitchell Wills } 60041e38d84f562e12198f7db0d45f633712cae6cbaMitchell Wills return results; 6019ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills } 6029ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills } 6039ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills 6042332e9ea1b691fa0ea3a340feec159f2040aa6caRoshan Pius private boolean setNetworkPriorities(WifiNative.PnoNetwork[] networkList) { 6052332e9ea1b691fa0ea3a340feec159f2040aa6caRoshan Pius if (networkList != null) { 6062332e9ea1b691fa0ea3a340feec159f2040aa6caRoshan Pius if (DBG) Log.i(TAG, "Enable network and Set priorities for PNO."); 6072332e9ea1b691fa0ea3a340feec159f2040aa6caRoshan Pius for (WifiNative.PnoNetwork network : networkList) { 6082332e9ea1b691fa0ea3a340feec159f2040aa6caRoshan Pius if (!mWifiNative.setNetworkVariable(network.networkId, 6092332e9ea1b691fa0ea3a340feec159f2040aa6caRoshan Pius WifiConfiguration.priorityVarName, 6102332e9ea1b691fa0ea3a340feec159f2040aa6caRoshan Pius Integer.toString(network.priority))) { 6112332e9ea1b691fa0ea3a340feec159f2040aa6caRoshan Pius Log.e(TAG, "Set priority failed for: " + network.networkId); 6122332e9ea1b691fa0ea3a340feec159f2040aa6caRoshan Pius return false; 6132332e9ea1b691fa0ea3a340feec159f2040aa6caRoshan Pius } 61462bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius if (!mWifiNative.enableNetworkWithoutConnect(network.networkId)) { 6152332e9ea1b691fa0ea3a340feec159f2040aa6caRoshan Pius Log.e(TAG, "Enable network failed for: " + network.networkId); 6162332e9ea1b691fa0ea3a340feec159f2040aa6caRoshan Pius return false; 6172332e9ea1b691fa0ea3a340feec159f2040aa6caRoshan Pius } 6182332e9ea1b691fa0ea3a340feec159f2040aa6caRoshan Pius } 6192332e9ea1b691fa0ea3a340feec159f2040aa6caRoshan Pius } 6202332e9ea1b691fa0ea3a340feec159f2040aa6caRoshan Pius return true; 6212332e9ea1b691fa0ea3a340feec159f2040aa6caRoshan Pius } 6222332e9ea1b691fa0ea3a340feec159f2040aa6caRoshan Pius 62362bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius private boolean startHwPnoScan() { 6242332e9ea1b691fa0ea3a340feec159f2040aa6caRoshan Pius if (!mWifiNative.enableBackgroundScan(true, null)) { 6252332e9ea1b691fa0ea3a340feec159f2040aa6caRoshan Pius return false; 6262332e9ea1b691fa0ea3a340feec159f2040aa6caRoshan Pius } 62762bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius mHwPnoRunning = true; 6282332e9ea1b691fa0ea3a340feec159f2040aa6caRoshan Pius return true; 6292332e9ea1b691fa0ea3a340feec159f2040aa6caRoshan Pius } 6302332e9ea1b691fa0ea3a340feec159f2040aa6caRoshan Pius 63162bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius private boolean stopHwPnoScan() { 6322332e9ea1b691fa0ea3a340feec159f2040aa6caRoshan Pius if (!mWifiNative.enableBackgroundScan(false, null)) { 6332332e9ea1b691fa0ea3a340feec159f2040aa6caRoshan Pius return false; 6342332e9ea1b691fa0ea3a340feec159f2040aa6caRoshan Pius } 63562bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius mHwPnoRunning = false; 6362332e9ea1b691fa0ea3a340feec159f2040aa6caRoshan Pius return true; 6372332e9ea1b691fa0ea3a340feec159f2040aa6caRoshan Pius } 6382332e9ea1b691fa0ea3a340feec159f2040aa6caRoshan Pius 63962bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius private boolean resumeHwPnoScan() { 64062bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius if (!mHwPnoRunning) { 64162bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius return startHwPnoScan(); 6422332e9ea1b691fa0ea3a340feec159f2040aa6caRoshan Pius } 6432332e9ea1b691fa0ea3a340feec159f2040aa6caRoshan Pius return true; 6442332e9ea1b691fa0ea3a340feec159f2040aa6caRoshan Pius } 6452332e9ea1b691fa0ea3a340feec159f2040aa6caRoshan Pius 64662bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius private boolean pauseHwPnoScan() { 64762bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius if (mHwPnoRunning) { 64862bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius return stopHwPnoScan(); 6492332e9ea1b691fa0ea3a340feec159f2040aa6caRoshan Pius } 6502332e9ea1b691fa0ea3a340feec159f2040aa6caRoshan Pius return true; 6512332e9ea1b691fa0ea3a340feec159f2040aa6caRoshan Pius } 6522332e9ea1b691fa0ea3a340feec159f2040aa6caRoshan Pius 653dcd877d6c143db557884993ea437e2a432cb0ba3Roshan Pius /** 654dcd877d6c143db557884993ea437e2a432cb0ba3Roshan Pius * Hw Pno Scan is required only for disconnected PNO when the device supports it. 655dcd877d6c143db557884993ea437e2a432cb0ba3Roshan Pius * @param isConnectedPno Whether this is connected PNO vs disconnected PNO. 656dcd877d6c143db557884993ea437e2a432cb0ba3Roshan Pius * @return true if HW PNO scan is required, false otherwise. 657dcd877d6c143db557884993ea437e2a432cb0ba3Roshan Pius */ 658dcd877d6c143db557884993ea437e2a432cb0ba3Roshan Pius private boolean isHwPnoScanRequired(boolean isConnectedPno) { 659dcd877d6c143db557884993ea437e2a432cb0ba3Roshan Pius return (!isConnectedPno & mHwPnoScanSupported); 660dcd877d6c143db557884993ea437e2a432cb0ba3Roshan Pius } 661dcd877d6c143db557884993ea437e2a432cb0ba3Roshan Pius 662dcd877d6c143db557884993ea437e2a432cb0ba3Roshan Pius private boolean isHwPnoScanRequired() { 663dcd877d6c143db557884993ea437e2a432cb0ba3Roshan Pius if (mPnoSettings == null) return false; 664dcd877d6c143db557884993ea437e2a432cb0ba3Roshan Pius return isHwPnoScanRequired(mPnoSettings.isConnected); 665dcd877d6c143db557884993ea437e2a432cb0ba3Roshan Pius } 666dcd877d6c143db557884993ea437e2a432cb0ba3Roshan Pius 667dcd877d6c143db557884993ea437e2a432cb0ba3Roshan Pius /** 668dcd877d6c143db557884993ea437e2a432cb0ba3Roshan Pius * Sw Pno Scan is required for all connected PNO and for devices those don't support 669dcd877d6c143db557884993ea437e2a432cb0ba3Roshan Pius * HW disconnected PNOscans. 670dcd877d6c143db557884993ea437e2a432cb0ba3Roshan Pius * @param isConnectedPno Whether this is connected PNO vs disconnected PNO. 671dcd877d6c143db557884993ea437e2a432cb0ba3Roshan Pius * @return true if SW PNO scan is required, false otherwise. 672dcd877d6c143db557884993ea437e2a432cb0ba3Roshan Pius */ 673dcd877d6c143db557884993ea437e2a432cb0ba3Roshan Pius private boolean isSwPnoScanRequired(boolean isConnectedPno) { 674dcd877d6c143db557884993ea437e2a432cb0ba3Roshan Pius return (isConnectedPno || !mHwPnoScanSupported); 675dcd877d6c143db557884993ea437e2a432cb0ba3Roshan Pius } 676dcd877d6c143db557884993ea437e2a432cb0ba3Roshan Pius 677dcd877d6c143db557884993ea437e2a432cb0ba3Roshan Pius private boolean isSwPnoScanRequired() { 678dcd877d6c143db557884993ea437e2a432cb0ba3Roshan Pius if (mPnoSettings == null) return false; 679dcd877d6c143db557884993ea437e2a432cb0ba3Roshan Pius return isSwPnoScanRequired(mPnoSettings.isConnected); 680dcd877d6c143db557884993ea437e2a432cb0ba3Roshan Pius } 681dcd877d6c143db557884993ea437e2a432cb0ba3Roshan Pius 6822332e9ea1b691fa0ea3a340feec159f2040aa6caRoshan Pius @Override 6832332e9ea1b691fa0ea3a340feec159f2040aa6caRoshan Pius public boolean setPnoList(WifiNative.PnoSettings settings, 6842332e9ea1b691fa0ea3a340feec159f2040aa6caRoshan Pius WifiNative.PnoEventHandler eventHandler) { 6852332e9ea1b691fa0ea3a340feec159f2040aa6caRoshan Pius synchronized (mSettingsLock) { 6862332e9ea1b691fa0ea3a340feec159f2040aa6caRoshan Pius if (mPnoSettings != null) { 6872332e9ea1b691fa0ea3a340feec159f2040aa6caRoshan Pius Log.w(TAG, "Already running a PNO scan"); 6882332e9ea1b691fa0ea3a340feec159f2040aa6caRoshan Pius return false; 6892332e9ea1b691fa0ea3a340feec159f2040aa6caRoshan Pius } 6902332e9ea1b691fa0ea3a340feec159f2040aa6caRoshan Pius mPnoEventHandler = eventHandler; 6912332e9ea1b691fa0ea3a340feec159f2040aa6caRoshan Pius mPnoSettings = settings; 69262bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius if (mHwPnoScanSupported) { 69362bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius if (!setNetworkPriorities(settings.networkList)) return false; 69462bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius // For supplicant based PNO, we start the scan immediately when we set pno list. 69562bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius processPendingScans(); 69662bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius } 6972332e9ea1b691fa0ea3a340feec159f2040aa6caRoshan Pius return true; 6982332e9ea1b691fa0ea3a340feec159f2040aa6caRoshan Pius } 6992332e9ea1b691fa0ea3a340feec159f2040aa6caRoshan Pius } 7002332e9ea1b691fa0ea3a340feec159f2040aa6caRoshan Pius 7012332e9ea1b691fa0ea3a340feec159f2040aa6caRoshan Pius @Override 7022332e9ea1b691fa0ea3a340feec159f2040aa6caRoshan Pius public boolean resetPnoList(WifiNative.PnoSettings settings) { 7032332e9ea1b691fa0ea3a340feec159f2040aa6caRoshan Pius synchronized (mSettingsLock) { 7042332e9ea1b691fa0ea3a340feec159f2040aa6caRoshan Pius if (mPnoSettings == null) { 7052332e9ea1b691fa0ea3a340feec159f2040aa6caRoshan Pius Log.w(TAG, "No PNO scan running"); 7062332e9ea1b691fa0ea3a340feec159f2040aa6caRoshan Pius return false; 7072332e9ea1b691fa0ea3a340feec159f2040aa6caRoshan Pius } 7082332e9ea1b691fa0ea3a340feec159f2040aa6caRoshan Pius mPnoEventHandler = null; 7092332e9ea1b691fa0ea3a340feec159f2040aa6caRoshan Pius mPnoSettings = null; 71062bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius if (mHwPnoScanSupported) { 71162bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius // For supplicant based PNO, we stop the scan immediately when we reset pno list. 71262bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius return stopHwPnoScan(); 71362bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius } else { 71462bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius return true; 71562bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius } 7162332e9ea1b691fa0ea3a340feec159f2040aa6caRoshan Pius } 7172332e9ea1b691fa0ea3a340feec159f2040aa6caRoshan Pius } 7182332e9ea1b691fa0ea3a340feec159f2040aa6caRoshan Pius 7192332e9ea1b691fa0ea3a340feec159f2040aa6caRoshan Pius @Override 720dcd877d6c143db557884993ea437e2a432cb0ba3Roshan Pius public boolean shouldScheduleBackgroundScanForPno(boolean isConnectedPno) { 721dcd877d6c143db557884993ea437e2a432cb0ba3Roshan Pius // If PNO scan is not supported by the HW or if this is a connected PNO request, revert to 722dcd877d6c143db557884993ea437e2a432cb0ba3Roshan Pius // using a normal periodic background scan. 723dcd877d6c143db557884993ea437e2a432cb0ba3Roshan Pius return !isHwPnoScanRequired(isConnectedPno); 7242332e9ea1b691fa0ea3a340feec159f2040aa6caRoshan Pius } 7252332e9ea1b691fa0ea3a340feec159f2040aa6caRoshan Pius 7269ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills @Override 7279ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills public boolean setHotlist(WifiScanner.HotlistSettings settings, 7289ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills WifiNative.HotlistEventHandler eventHandler) { 7299ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills if (settings == null || eventHandler == null) { 7309ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills return false; 7319ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills } 7325fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills synchronized (mSettingsLock) { 7339ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills mHotlistHandler = eventHandler; 7349ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills mHotlistChangeBuffer.setSettings(settings.bssidInfos, settings.apLostThreshold, 1); 7359ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills return true; 7369ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills } 7379ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills } 7389ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills 7399ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills @Override 7409ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills public void resetHotlist() { 7415fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills synchronized (mSettingsLock) { 7429ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills mHotlistChangeBuffer.clearSettings(); 7439ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills mHotlistHandler = null; 7449ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills } 7459ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills } 7469ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills 74794bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills /* 74894bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills * Significant Wifi Change API is not implemented 74994bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills */ 75094bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills @Override 75194bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills public boolean trackSignificantWifiChange(WifiScanner.WifiChangeSettings settings, 75294bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills WifiNative.SignificantWifiChangeEventHandler handler) { 75394bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills return false; 75494bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills } 75594bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills @Override 75694bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills public void untrackSignificantWifiChange() {} 75794bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills 75894bd575cb4766ed0dfbaad0fc7719a9e9e85a260Mitchell Wills 7599ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills private static class LastScanSettings { 7605fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills public long startTime; 7615fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills 7625fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills public LastScanSettings(long startTime) { 7635fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills this.startTime = startTime; 7645fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills } 7655fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills 7665fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills // Background settings 7675fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills public boolean backgroundScanActive = false; 7685fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills public int scanId; 7695fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills public int maxAps; 7705fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills public int reportEvents; 7715fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills public int reportNumScansThreshold; 7725fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills public int reportPercentThreshold; 7735fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills 7745fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills public void setBackgroundScan(int scanId, int maxAps, int reportEvents, 7759ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills int reportNumScansThreshold, int reportPercentThreshold) { 7765fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills this.backgroundScanActive = true; 7779ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills this.scanId = scanId; 7789ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills this.maxAps = maxAps; 7799ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills this.reportEvents = reportEvents; 7809ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills this.reportNumScansThreshold = reportNumScansThreshold; 7819ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills this.reportPercentThreshold = reportPercentThreshold; 7829ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills } 7835fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills 7845fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills // Single scan settings 7855fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills public boolean singleScanActive = false; 7865fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills public boolean reportSingleScanFullResults; 7877e3e85327ca82a83de84b4750e793f2e3d1b3bfcMitchell Wills public ChannelCollection singleScanFreqs; 7885fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills public WifiNative.ScanEventHandler singleScanEventHandler; 7895fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills 7905fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills public void setSingleScan(boolean reportSingleScanFullResults, 7917e3e85327ca82a83de84b4750e793f2e3d1b3bfcMitchell Wills ChannelCollection singleScanFreqs, 7927e3e85327ca82a83de84b4750e793f2e3d1b3bfcMitchell Wills WifiNative.ScanEventHandler singleScanEventHandler) { 7935fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills singleScanActive = true; 7945fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills this.reportSingleScanFullResults = reportSingleScanFullResults; 7955fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills this.singleScanFreqs = singleScanFreqs; 7965fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills this.singleScanEventHandler = singleScanEventHandler; 7975fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills } 798063cfc7e3eef78fcbda24a66f0c473828b39c854Roshan Pius 79962bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius public boolean hwPnoScanActive = false; 80062bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius public boolean swPnoScanActive = false; 801063cfc7e3eef78fcbda24a66f0c473828b39c854Roshan Pius public WifiNative.PnoEventHandler pnoScanEventHandler; 802063cfc7e3eef78fcbda24a66f0c473828b39c854Roshan Pius 80362bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius 80462bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius public void setHwPnoScan(WifiNative.PnoEventHandler pnoScanEventHandler) { 80562bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius hwPnoScanActive = true; 80662bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius this.pnoScanEventHandler = pnoScanEventHandler; 80762bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius } 80862bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius 80962bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius public void setSwPnoScan(WifiNative.PnoEventHandler pnoScanEventHandler) { 81062bc101940ae1f5e60c4d8861a149b900dbf5e5cRoshan Pius swPnoScanActive = true; 811063cfc7e3eef78fcbda24a66f0c473828b39c854Roshan Pius this.pnoScanEventHandler = pnoScanEventHandler; 812063cfc7e3eef78fcbda24a66f0c473828b39c854Roshan Pius } 8139ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills } 8149ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills 8159ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills 8169ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills private static class ScanBuffer { 8179ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills private final ArrayDeque<WifiScanner.ScanData> mBuffer; 8185fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills private int mCapacity; 8199ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills 8209ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills public ScanBuffer(int capacity) { 8215fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills mCapacity = capacity; 8225fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills mBuffer = new ArrayDeque<>(mCapacity); 8239ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills } 8249ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills 8259ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills public int size() { 8269ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills return mBuffer.size(); 8279ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills } 8289ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills 8299ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills public int capacity() { 8305fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills return mCapacity; 8319ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills } 8329ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills 8339ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills public boolean isFull() { 8345fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills return size() == mCapacity; 8359ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills } 8369ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills 8379ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills public void add(WifiScanner.ScanData scanData) { 8389ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills if (isFull()) { 8399ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills mBuffer.pollFirst(); 8409ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills } 8419ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills mBuffer.offerLast(scanData); 8429ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills } 8439ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills 8449ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills public void clear() { 8459ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills mBuffer.clear(); 8469ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills } 8479ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills 8489ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills public WifiScanner.ScanData[] get() { 8499ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills return mBuffer.toArray(new WifiScanner.ScanData[mBuffer.size()]); 8509ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills } 8519ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills } 8529ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills 8539ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills private static class ChangeBuffer { 8549ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills public static int EVENT_NONE = 0; 8559ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills public static int EVENT_LOST = 1; 8569ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills public static int EVENT_FOUND = 2; 8579ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills 8585fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills public static int STATE_FOUND = 0; 8599ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills 8609ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills private WifiScanner.BssidInfo[] mBssidInfos = null; 8619ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills private int mApLostThreshold; 8629ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills private int mMinEvents; 8639ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills private int[] mLostCount = null; 8649ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills private ScanResult[] mMostRecentResult = null; 8659ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills private int[] mPendingEvent = null; 8669ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills private boolean mFiredEvents = false; 8679ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills 8685fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills private static ScanResult findResult(List<ScanResult> results, String bssid) { 8695fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills for (int i = 0; i < results.size(); ++i) { 8705fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills if (bssid.equalsIgnoreCase(results.get(i).BSSID)) { 8715fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills return results.get(i); 8729ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills } 8739ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills } 8749ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills return null; 8759ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills } 8769ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills 8779ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills public void setSettings(WifiScanner.BssidInfo[] bssidInfos, int apLostThreshold, 8789ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills int minEvents) { 8799ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills mBssidInfos = bssidInfos; 8809ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills if (apLostThreshold <= 0) { 8819ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills mApLostThreshold = 1; 8825fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills } else { 8839ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills mApLostThreshold = apLostThreshold; 8849ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills } 8859ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills mMinEvents = minEvents; 8869ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills if (bssidInfos != null) { 8879ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills mLostCount = new int[bssidInfos.length]; 8889ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills Arrays.fill(mLostCount, mApLostThreshold); // default to lost 8899ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills mMostRecentResult = new ScanResult[bssidInfos.length]; 8909ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills mPendingEvent = new int[bssidInfos.length]; 8919ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills mFiredEvents = false; 8925fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills } else { 8939ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills mLostCount = null; 8949ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills mMostRecentResult = null; 8959ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills mPendingEvent = null; 8969ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills } 8979ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills } 8989ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills 8999ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills public void clearSettings() { 9009ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills setSettings(null, 0, 0); 9019ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills } 9029ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills 9039ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills /** 9049ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills * Get the most recent scan results for APs that triggered the given event on the last call 9059ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills * to {@link #processScan}. 9069ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills */ 9079ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills public ScanResult[] getLastResults(int event) { 9089ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills ArrayList<ScanResult> results = new ArrayList<>(); 9099ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills for (int i = 0; i < mLostCount.length; ++i) { 9109ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills if (mPendingEvent[i] == event) { 9119ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills results.add(mMostRecentResult[i]); 9129ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills } 9139ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills } 9149ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills return results.toArray(new ScanResult[results.size()]); 9159ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills } 9169ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills 9179ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills /** 9189ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills * Process the supplied scan results and determine if any events should be generated based 9199ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills * on the configured settings 9209ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills * @return The events that occurred 9219ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills */ 9225fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills public int processScan(List<ScanResult> scanResults) { 9239ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills if (mBssidInfos == null) { 9249ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills return EVENT_NONE; 9259ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills } 9269ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills 9279ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills // clear events from last time 9289ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills if (mFiredEvents) { 9299ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills mFiredEvents = false; 9309ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills for (int i = 0; i < mLostCount.length; ++i) { 9319ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills mPendingEvent[i] = EVENT_NONE; 9329ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills } 9339ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills } 9349ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills 9359ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills int eventCount = 0; 9369ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills int eventType = EVENT_NONE; 9379ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills for (int i = 0; i < mLostCount.length; ++i) { 9389ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills ScanResult result = findResult(scanResults, mBssidInfos[i].bssid); 9399ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills int rssi = Integer.MIN_VALUE; 9409ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills if (result != null) { 9419ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills mMostRecentResult[i] = result; 9429ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills rssi = result.level; 9439ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills } 9449ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills 9459ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills if (rssi < mBssidInfos[i].low) { 9469ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills if (mLostCount[i] < mApLostThreshold) { 9479ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills mLostCount[i]++; 9489ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills 9499ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills if (mLostCount[i] >= mApLostThreshold) { 9509ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills if (mPendingEvent[i] == EVENT_FOUND) { 9519ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills mPendingEvent[i] = EVENT_NONE; 9525fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills } else { 9539ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills mPendingEvent[i] = EVENT_LOST; 9549ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills } 9559ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills } 9569ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills } 9575fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills } else { 9589ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills if (mLostCount[i] >= mApLostThreshold) { 9599ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills if (mPendingEvent[i] == EVENT_LOST) { 9609ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills mPendingEvent[i] = EVENT_NONE; 9615fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills } else { 9629ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills mPendingEvent[i] = EVENT_FOUND; 9639ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills } 9649ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills } 9659ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills mLostCount[i] = STATE_FOUND; 9669ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills } 9679ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills if (DBG) { 9685fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills Log.d(TAG, "ChangeBuffer BSSID: " + mBssidInfos[i].bssid + "=" + mLostCount[i] 9695fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills + ", " + mPendingEvent[i] + ", rssi=" + rssi); 9709ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills } 9719ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills if (mPendingEvent[i] != EVENT_NONE) { 9729ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills ++eventCount; 9739ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills eventType |= mPendingEvent[i]; 9749ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills } 9759ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills } 9765fa6221c4e507cbc596b6de77d793ec08d690157Mitchell Wills if (DBG) Log.d(TAG, "ChangeBuffer events count=" + eventCount + ": " + eventType); 9779ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills if (eventCount >= mMinEvents) { 9789ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills mFiredEvents = true; 9799ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills return eventType; 9809ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills } 9819ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills return EVENT_NONE; 9829ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills } 9839ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills } 9849ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Wills} 985