diff options
Diffstat (limited to 'service')
-rw-r--r-- | service/java/com/android/server/wifi/WifiScanningServiceImpl.java | 672 |
1 files changed, 283 insertions, 389 deletions
diff --git a/service/java/com/android/server/wifi/WifiScanningServiceImpl.java b/service/java/com/android/server/wifi/WifiScanningServiceImpl.java index 015730569..f2791af6f 100644 --- a/service/java/com/android/server/wifi/WifiScanningServiceImpl.java +++ b/service/java/com/android/server/wifi/WifiScanningServiceImpl.java @@ -64,6 +64,7 @@ import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.Map; +import java.util.Set; public class WifiScanningServiceImpl extends IWifiScanner.Stub { @@ -197,15 +198,17 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub { case WifiScanner.CMD_STOP_PNO_SCAN: case WifiScanner.CMD_SET_HOTLIST: case WifiScanner.CMD_RESET_HOTLIST: - case WifiScanner.CMD_CONFIGURE_WIFI_CHANGE: - case WifiScanner.CMD_START_TRACKING_CHANGE: - case WifiScanner.CMD_STOP_TRACKING_CHANGE: mBackgroundScanStateMachine.sendMessage(Message.obtain(msg)); break; case WifiScanner.CMD_START_SINGLE_SCAN: case WifiScanner.CMD_STOP_SINGLE_SCAN: mSingleScanStateMachine.sendMessage(Message.obtain(msg)); break; + case WifiScanner.CMD_CONFIGURE_WIFI_CHANGE: + case WifiScanner.CMD_START_TRACKING_CHANGE: + case WifiScanner.CMD_STOP_TRACKING_CHANGE: + mWifiChangeStateMachine.sendMessage(Message.obtain(msg)); + break; default: replyFailed(msg, WifiScanner.REASON_INVALID_REQUEST, "Invalid request"); break; @@ -220,14 +223,15 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub { private static final int CMD_HOTLIST_AP_FOUND = BASE + 2; private static final int CMD_HOTLIST_AP_LOST = BASE + 3; private static final int CMD_WIFI_CHANGE_DETECTED = BASE + 4; - private static final int CMD_WIFI_CHANGES_STABILIZED = BASE + 5; - private static final int CMD_DRIVER_LOADED = BASE + 6; - private static final int CMD_DRIVER_UNLOADED = BASE + 7; - private static final int CMD_SCAN_PAUSED = BASE + 8; - private static final int CMD_SCAN_RESTARTED = BASE + 9; - private static final int CMD_SCAN_FAILED = BASE + 10; - private static final int CMD_PNO_NETWORK_FOUND = BASE + 11; - private static final int CMD_PNO_SCAN_FAILED = BASE + 12; + private static final int CMD_WIFI_CHANGE_NEW_SCAN_RESULTS = BASE + 5; + private static final int CMD_WIFI_CHANGE_TIMEOUT = BASE + 6; + private static final int CMD_DRIVER_LOADED = BASE + 7; + private static final int CMD_DRIVER_UNLOADED = BASE + 8; + private static final int CMD_SCAN_PAUSED = BASE + 9; + private static final int CMD_SCAN_RESTARTED = BASE + 10; + private static final int CMD_SCAN_FAILED = BASE + 11; + private static final int CMD_PNO_NETWORK_FOUND = BASE + 12; + private static final int CMD_PNO_SCAN_FAILED = BASE + 13; private final Context mContext; private final Looper mLooper; @@ -240,6 +244,7 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub { private WifiBackgroundScanStateMachine mBackgroundScanStateMachine; private WifiSingleScanStateMachine mSingleScanStateMachine; + private WifiChangeStateMachine mWifiChangeStateMachine; private ClientHandler mClientHandler; private final IBatteryStats mBatteryStats; private final AlarmManager mAlarmManager; @@ -680,14 +685,12 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub { class WifiBackgroundScanStateMachine extends StateMachine implements WifiNative.ScanEventHandler, WifiNative.HotlistEventHandler, - WifiNative.PnoEventHandler, WifiNative.SignificantWifiChangeEventHandler { + WifiNative.PnoEventHandler { private final DefaultState mDefaultState = new DefaultState(); private final StartedState mStartedState = new StartedState(); private final PausedState mPausedState = new PausedState(); - private final ClientHandlerMap<PnoSettings> mActivePnoScans = - new ClientHandlerMap<>(); private final ClientHandlerMap<ScanSettings> mActiveBackgroundScans = new ClientHandlerMap<ScanSettings>() { @Override @@ -704,6 +707,10 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub { return settings; } }; + private final ClientHandlerMap<PnoSettings> mActivePnoScans = + new ClientHandlerMap<>(); + private final ClientHandlerMap<WifiScanner.HotlistSettings> mActiveHotlistSettings = + new ClientHandlerMap<>(); WifiBackgroundScanStateMachine(Looper looper) { super(TAG, looper); @@ -720,24 +727,22 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub { setInitialState(mDefaultState); } - public ArrayList<ScanSettings> getBackgroundScanSettings() { - return new ArrayList<>(mActiveBackgroundScans.values()); - } - - public ArrayList<ScanSettings> getBackgroundScanSettings(ClientInfo ci) { - return new ArrayList<>(mActiveBackgroundScans.getAllValues(ci)); + public Collection<ScanSettings> getBackgroundScanSettings(ClientInfo ci) { + return mActiveBackgroundScans.getAllValues(ci); } public Map<Integer, ScanSettings> getBackgroundScanSettingsHandlerMap(ClientInfo ci) { return mActiveBackgroundScans.getHandlerToValueMap(ci); } - public void removeActiveBackgroundScanSettings(ClientInfo ci) { + public void removeBackgroundScanSettings(ClientInfo ci) { mActiveBackgroundScans.removeAll(ci); + updateSchedule(); } - public ArrayList<PnoSettings> getActivePnoScanSettings() { - return new ArrayList<>(mActivePnoScans.values()); + public void removeHotlistSettings(ClientInfo ci) { + mActiveHotlistSettings.removeAll(ci); + resetHotlist(); } @Override @@ -789,12 +794,6 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub { } @Override - public void onChangesFound(ScanResult[] results) { - if (DBG) localLog("onWifiChangesFound event received"); - 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); @@ -853,9 +852,6 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub { case WifiScanner.CMD_STOP_SINGLE_SCAN: case WifiScanner.CMD_SET_HOTLIST: case WifiScanner.CMD_RESET_HOTLIST: - case WifiScanner.CMD_CONFIGURE_WIFI_CHANGE: - case WifiScanner.CMD_START_TRACKING_CHANGE: - case WifiScanner.CMD_STOP_TRACKING_CHANGE: case WifiScanner.CMD_GET_SCAN_RESULTS: replyFailed(msg, WifiScanner.REASON_UNSPECIFIED, "not available"); break; @@ -940,21 +936,11 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub { replySucceeded(msg); break; case WifiScanner.CMD_SET_HOTLIST: - setHotlist(ci, msg.arg2, (WifiScanner.HotlistSettings) msg.obj); + addHotlist(ci, msg.arg2, (WifiScanner.HotlistSettings) msg.obj); replySucceeded(msg); break; case WifiScanner.CMD_RESET_HOTLIST: - resetHotlist(ci, msg.arg2); - break; - case WifiScanner.CMD_START_TRACKING_CHANGE: - trackWifiChanges(ci, msg.arg2); - replySucceeded(msg); - break; - case WifiScanner.CMD_STOP_TRACKING_CHANGE: - untrackWifiChanges(ci, msg.arg2); - break; - case WifiScanner.CMD_CONFIGURE_WIFI_CHANGE: - configureWifiChange((WifiScanner.WifiChangeSettings) msg.obj); + removeHotlist(ci, msg.arg2); break; case CMD_SCAN_RESULTS_AVAILABLE: reportScanResults(mScannerImpl.getLatestBatchedScanResults(true)); @@ -962,34 +948,11 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub { case CMD_FULL_SCAN_RESULTS: reportFullScanResult((ScanResult) msg.obj, /* bucketsScanned */ msg.arg2); break; - - case CMD_HOTLIST_AP_FOUND: { - ScanResult[] results = (ScanResult[])msg.obj; - if (DBG) localLog("Found " + results.length + " results"); - Collection<ClientInfo> clients = mClients.values(); - for (ClientInfo ci2 : clients) { - ci2.reportHotlistResults(WifiScanner.CMD_AP_FOUND, results); - } - } - break; - case CMD_HOTLIST_AP_LOST: { - ScanResult[] results = (ScanResult[])msg.obj; - if (DBG) localLog("Lost " + results.length + " results"); - Collection<ClientInfo> clients = mClients.values(); - for (ClientInfo ci2 : clients) { - ci2.reportHotlistResults(WifiScanner.CMD_AP_LOST, results); - } - } - break; - case CMD_WIFI_CHANGE_DETECTED: { - ScanResult[] results = (ScanResult[])msg.obj; - reportWifiChanged(results); - } + case CMD_HOTLIST_AP_FOUND: + reportHotlistResults(WifiScanner.CMD_AP_FOUND, (ScanResult[]) msg.obj); break; - case CMD_WIFI_CHANGES_STABILIZED: { - ScanResult[] results = (ScanResult[])msg.obj; - reportWifiStabilized(results); - } + case CMD_HOTLIST_AP_LOST: + reportHotlistResults(WifiScanner.CMD_AP_LOST, (ScanResult[]) msg.obj); break; case CMD_SCAN_PAUSED: reportScanResults((ScanData[]) msg.obj); @@ -1100,6 +1063,59 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub { } } + private boolean updateSchedule() { + mChannelHelper.updateChannels(); + Collection<ScanSettings> settings = mActiveBackgroundScans.values(); + + mScheduler.updateSchedule(settings); + WifiNative.ScanSettings schedule = mScheduler.getSchedule(); + + if (ScanScheduleUtil.scheduleEquals(mPreviousSchedule, schedule)) { + if (DBG) Log.d(TAG, "schedule updated with no change"); + return true; + } + + mPreviousSchedule = schedule; + + if (schedule.num_buckets == 0) { + mScannerImpl.stopBatchedScan(); + if (DBG) Log.d(TAG, "scan stopped"); + return true; + } else { + Log.d(TAG, "starting scan: " + + "base period=" + schedule.base_period_ms + + ", max ap per scan=" + schedule.max_ap_per_scan + + ", batched scans=" + schedule.report_threshold_num_scans); + for (int b = 0; b < schedule.num_buckets; b++) { + WifiNative.BucketSettings bucket = schedule.buckets[b]; + Log.d(TAG, "bucket " + bucket.bucket + " (" + bucket.period_ms + "ms)" + + "[" + bucket.report_events + "]: " + + ChannelHelper.toString(bucket)); + } + + if (mScannerImpl.startBatchedScan(schedule, this)) { + if (DBG) { + Log.d(TAG, "scan restarted with " + schedule.num_buckets + + " bucket(s) and base period: " + schedule.base_period_ms); + } + return true; + } else { + mPreviousSchedule = null; + loge("error starting scan: " + + "base period=" + schedule.base_period_ms + + ", max ap per scan=" + schedule.max_ap_per_scan + + ", batched scans=" + schedule.report_threshold_num_scans); + for (int b = 0; b < schedule.num_buckets; b++) { + WifiNative.BucketSettings bucket = schedule.buckets[b]; + loge("bucket " + bucket.bucket + " (" + bucket.period_ms + "ms)" + + "[" + bucket.report_events + "]: " + + ChannelHelper.toString(bucket)); + } + return false; + } + } + } + private void removeBackgroundScanRequest(ClientInfo ci, int handler) { if (ci != null) { ScanSettings settings = mActiveBackgroundScans.remove(ci, handler); @@ -1271,6 +1287,83 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub { } mActivePnoScans.clear(); } + + private void addHotlist(ClientInfo ci, int handler, WifiScanner.HotlistSettings settings) { + mActiveHotlistSettings.put(ci, handler, settings); + resetHotlist(); + } + + private void removeHotlist(ClientInfo ci, int handler) { + mActiveHotlistSettings.remove(ci, handler); + resetHotlist(); + } + + private void resetHotlist() { + Collection<WifiScanner.HotlistSettings> settings = mActiveHotlistSettings.values(); + int num_hotlist_ap = 0; + + for (WifiScanner.HotlistSettings s : settings) { + num_hotlist_ap += s.bssidInfos.length; + } + + if (num_hotlist_ap == 0) { + mScannerImpl.resetHotlist(); + } else { + BssidInfo[] bssidInfos = new BssidInfo[num_hotlist_ap]; + int apLostThreshold = Integer.MAX_VALUE; + int index = 0; + for (WifiScanner.HotlistSettings s : settings) { + for (int i = 0; i < s.bssidInfos.length; i++, index++) { + bssidInfos[index] = s.bssidInfos[i]; + } + if (s.apLostThreshold < apLostThreshold) { + apLostThreshold = s.apLostThreshold; + } + } + + WifiScanner.HotlistSettings mergedSettings = new WifiScanner.HotlistSettings(); + mergedSettings.bssidInfos = bssidInfos; + mergedSettings.apLostThreshold = apLostThreshold; + mScannerImpl.setHotlist(mergedSettings, this); + } + } + + private void reportHotlistResults(int what, ScanResult[] results) { + if (DBG) localLog("reportHotlistResults " + what + " results " + results.length); + for (Map.Entry<Pair<ClientInfo, Integer>, WifiScanner.HotlistSettings> entry + : mActiveHotlistSettings.entrySet()) { + ClientInfo ci = entry.getKey().first; + int handler = entry.getKey().second; + WifiScanner.HotlistSettings settings = entry.getValue(); + int num_results = 0; + for (ScanResult result : results) { + for (BssidInfo BssidInfo : settings.bssidInfos) { + if (result.BSSID.equalsIgnoreCase(BssidInfo.bssid)) { + num_results++; + break; + } + } + } + if (num_results == 0) { + // nothing to report + return; + } + ScanResult[] results2 = new ScanResult[num_results]; + int index = 0; + for (ScanResult result : results) { + for (BssidInfo BssidInfo : settings.bssidInfos) { + if (result.BSSID.equalsIgnoreCase(BssidInfo.bssid)) { + results2[index] = result; + index++; + } + } + } + WifiScanner.ParcelableScanResults parcelableScanResults = + new WifiScanner.ParcelableScanResults(results2); + + ci.sendMessage(what, 0, handler, parcelableScanResults); + } + } } private class ClientInfo { @@ -1384,109 +1477,12 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub { mChannel.sendMessage(WifiScanner.CMD_SCAN_RESULT, 0, handler, parcelableScanData); } - private final Map<Integer, WifiScanner.HotlistSettings> mHotlistSettings = - new HashMap<Integer, WifiScanner.HotlistSettings>(); - - void addHostlistSettings(WifiScanner.HotlistSettings settings, int handler) { - mHotlistSettings.put(handler, settings); - } - - void removeHostlistSettings(int handler) { - mHotlistSettings.remove(handler); - } - - Collection<WifiScanner.HotlistSettings> getHotlistSettings() { - return mHotlistSettings.values(); - } - - void reportHotlistResults(int what, ScanResult[] results) { - Iterator<Map.Entry<Integer, WifiScanner.HotlistSettings>> it = - mHotlistSettings.entrySet().iterator(); - while (it.hasNext()) { - Map.Entry<Integer, WifiScanner.HotlistSettings> entry = it.next(); - int handler = entry.getKey(); - WifiScanner.HotlistSettings settings = entry.getValue(); - int num_results = 0; - for (ScanResult result : results) { - for (BssidInfo BssidInfo : settings.bssidInfos) { - if (result.BSSID.equalsIgnoreCase(BssidInfo.bssid)) { - num_results++; - break; - } - } - } - - if (num_results == 0) { - // nothing to report - return; - } - - ScanResult results2[] = new ScanResult[num_results]; - int index = 0; - for (ScanResult result : results) { - for (BssidInfo BssidInfo : settings.bssidInfos) { - if (result.BSSID.equalsIgnoreCase(BssidInfo.bssid)) { - results2[index] = result; - index++; - } - } - } - - WifiScanner.ParcelableScanResults parcelableScanResults = - new WifiScanner.ParcelableScanResults(results2); - - mChannel.sendMessage(what, 0, handler, parcelableScanResults); - } - } - - HashSet<Integer> mSignificantWifiHandlers = new HashSet<Integer>(); - void addSignificantWifiChange(int handler) { - mSignificantWifiHandlers.add(handler); - } - - void removeSignificantWifiChange(int handler) { - mSignificantWifiHandlers.remove(handler); - } - - Collection<Integer> getWifiChangeHandlers() { - return mSignificantWifiHandlers; - } - - void reportWifiChanged(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_WIFI_CHANGE_DETECTED, - 0, handler, parcelableScanResults); - } - } - - void reportWifiStabilized(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_WIFI_CHANGES_STABILIZED, - 0, handler, parcelableScanResults); - } - } - void cleanup() { mDisconnected = true; - mBackgroundScanStateMachine.removeActiveBackgroundScanSettings(this); - updateSchedule(); + mBackgroundScanStateMachine.removeBackgroundScanSettings(this); + mBackgroundScanStateMachine.removeHotlistSettings(this); + mWifiChangeStateMachine.removeWifiChangeHandler(this); - mHotlistSettings.clear(); - resetHotlist(); - - for (Integer handler : mSignificantWifiHandlers) { - untrackWifiChanges(this, handler); - } - - mSignificantWifiHandlers.clear(); localLog("Successfully stopped all requests for client " + this); } } @@ -1522,156 +1518,11 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub { } } - private boolean updateSchedule() { - mChannelHelper.updateChannels(); - Collection<ScanSettings> settings = mBackgroundScanStateMachine.getBackgroundScanSettings(); - - mScheduler.updateSchedule(settings); - WifiNative.ScanSettings schedule = mScheduler.getSchedule(); - - if (ScanScheduleUtil.scheduleEquals(mPreviousSchedule, schedule)) { - if (DBG) Log.d(TAG, "schedule updated with no change"); - return true; - } - - mPreviousSchedule = schedule; - - if (schedule.num_buckets == 0) { - mScannerImpl.stopBatchedScan(); - if (DBG) Log.d(TAG, "scan stopped"); - return true; - } else { - Log.d(TAG, "starting scan: " - + "base period=" + schedule.base_period_ms - + ", max ap per scan=" + schedule.max_ap_per_scan - + ", batched scans=" + schedule.report_threshold_num_scans); - for (int b = 0; b < schedule.num_buckets; b++) { - WifiNative.BucketSettings bucket = schedule.buckets[b]; - Log.d(TAG, "bucket " + bucket.bucket + " (" + bucket.period_ms + "ms)" - + "[" + bucket.report_events + "]: " - + ChannelHelper.toString(bucket)); - } - - if (mScannerImpl.startBatchedScan(schedule, mBackgroundScanStateMachine)) { - if (DBG) Log.d(TAG, "scan restarted with " + schedule.num_buckets - + " bucket(s) and base period: " + schedule.base_period_ms); - return true; - } else { - mPreviousSchedule = null; - loge("error starting scan: " - + "base period=" + schedule.base_period_ms - + ", max ap per scan=" + schedule.max_ap_per_scan - + ", batched scans=" + schedule.report_threshold_num_scans); - for (int b = 0; b < schedule.num_buckets; b++) { - WifiNative.BucketSettings bucket = schedule.buckets[b]; - loge("bucket " + bucket.bucket + " (" + bucket.period_ms + "ms)" - + "[" + bucket.report_events + "]: " - + ChannelHelper.toString(bucket)); - } - return false; - } - } - } - - void resetHotlist() { - Collection<ClientInfo> clients = mClients.values(); - int num_hotlist_ap = 0; - - for (ClientInfo ci : clients) { - Collection<WifiScanner.HotlistSettings> c = ci.getHotlistSettings(); - for (WifiScanner.HotlistSettings s : c) { - num_hotlist_ap += s.bssidInfos.length; - } - } - - if (num_hotlist_ap == 0) { - mScannerImpl.resetHotlist(); - } else { - BssidInfo bssidInfos[] = new BssidInfo[num_hotlist_ap]; - int apLostThreshold = Integer.MAX_VALUE; - int index = 0; - for (ClientInfo ci : clients) { - Collection<WifiScanner.HotlistSettings> settings = ci.getHotlistSettings(); - for (WifiScanner.HotlistSettings s : settings) { - for (int i = 0; i < s.bssidInfos.length; i++, index++) { - bssidInfos[index] = s.bssidInfos[i]; - } - if (s.apLostThreshold < apLostThreshold) { - apLostThreshold = s.apLostThreshold; - } - } - } - - WifiScanner.HotlistSettings settings = new WifiScanner.HotlistSettings(); - settings.bssidInfos = bssidInfos; - settings.apLostThreshold = apLostThreshold; - mScannerImpl.setHotlist(settings, mBackgroundScanStateMachine); - } - } - - void setHotlist(ClientInfo ci, int handler, WifiScanner.HotlistSettings settings) { - ci.addHostlistSettings(settings, handler); - resetHotlist(); - } - - void resetHotlist(ClientInfo ci, int handler) { - ci.removeHostlistSettings(handler); - resetHotlist(); - } - - WifiChangeStateMachine mWifiChangeStateMachine; - - void trackWifiChanges(ClientInfo ci, int handler) { - mWifiChangeStateMachine.enable(); - ci.addSignificantWifiChange(handler); - } - - void untrackWifiChanges(ClientInfo ci, int handler) { - ci.removeSignificantWifiChange(handler); - Collection<ClientInfo> clients = mClients.values(); - for (ClientInfo ci2 : clients) { - if (ci2.getWifiChangeHandlers().size() != 0) { - // there is at least one client watching for - // significant changes; so nothing more to do - return; - } - } - - // no more clients looking for significant wifi changes - // no need to keep the state machine running; disable it - mWifiChangeStateMachine.disable(); - } - - void configureWifiChange(WifiScanner.WifiChangeSettings settings) { - mWifiChangeStateMachine.configure(settings); - } - - void reportWifiChanged(ScanResult results[]) { - Collection<ClientInfo> clients = mClients.values(); - for (ClientInfo ci : clients) { - ci.reportWifiChanged(results); - } - } - - void reportWifiStabilized(ScanResult results[]) { - Collection<ClientInfo> clients = mClients.values(); - for (ClientInfo ci : clients) { - ci.reportWifiStabilized(results); - } - } - class WifiChangeStateMachine extends StateMachine implements WifiNative.SignificantWifiChangeEventHandler { private static final String TAG = "WifiChangeStateMachine"; - private static final int WIFI_CHANGE_CMD_NEW_SCAN_RESULTS = 0; - private static final int WIFI_CHANGE_CMD_CHANGE_DETECTED = 1; - private static final int WIFI_CHANGE_CMD_CHANGE_TIMEOUT = 2; - private static final int WIFI_CHANGE_CMD_ENABLE = 3; - private static final int WIFI_CHANGE_CMD_DISABLE = 4; - private static final int WIFI_CHANGE_CMD_CONFIGURE = 5; - private static final int MAX_APS_TO_TRACK = 3; private static final int MOVING_SCAN_PERIOD_MS = 10000; private static final int STATIONARY_SCAN_PERIOD_MS = 5000; @@ -1686,6 +1537,8 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub { PendingIntent mTimeoutIntent; ScanResult mCurrentBssids[]; + private final Set<Pair<ClientInfo, Integer>> mActiveWifiChangeHandlers = new HashSet<>(); + WifiChangeStateMachine(Looper looper) { super("SignificantChangeStateMachine", looper); @@ -1700,29 +1553,15 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub { setInitialState(mDefaultState); } - public void enable() { - if (mTimeoutIntent == null) { - Intent intent = new Intent(ACTION_TIMEOUT, null); - mTimeoutIntent = PendingIntent.getBroadcast(mContext, 0, intent, 0); - - mContext.registerReceiver( - new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - sendMessage(WIFI_CHANGE_CMD_CHANGE_TIMEOUT); - } - }, new IntentFilter(ACTION_TIMEOUT)); + public void removeWifiChangeHandler(ClientInfo ci) { + Iterator<Pair<ClientInfo, Integer>> iter = mActiveWifiChangeHandlers.iterator(); + while (iter.hasNext()) { + Pair<ClientInfo, Integer> entry = iter.next(); + if (entry.first == ci) { + iter.remove(); + } } - - sendMessage(WIFI_CHANGE_CMD_ENABLE); - } - - public void disable() { - sendMessage(WIFI_CHANGE_CMD_DISABLE); - } - - public void configure(WifiScanner.WifiChangeSettings settings) { - sendMessage(WIFI_CHANGE_CMD_CONFIGURE, settings); + untrackSignificantWifiChangeOnEmpty(); } class DefaultState extends State { @@ -1734,20 +1573,23 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub { @Override public boolean processMessage(Message msg) { if (DBG) localLog("DefaultState state got " + msg); + ClientInfo ci = mClients.get(msg.replyTo); switch (msg.what) { - case WIFI_CHANGE_CMD_ENABLE : + case WifiScanner.CMD_START_TRACKING_CHANGE: + addWifiChangeHandler(ci, msg.arg2); + replySucceeded(msg); transitionTo(mMovingState); break; - case WIFI_CHANGE_CMD_DISABLE: - // nothing to do - break; - case WIFI_CHANGE_CMD_NEW_SCAN_RESULTS: + case WifiScanner.CMD_STOP_TRACKING_CHANGE: // nothing to do break; - case WIFI_CHANGE_CMD_CONFIGURE: + case WifiScanner.CMD_CONFIGURE_WIFI_CHANGE: /* save configuration till we transition to moving state */ deferMessage(msg); break; + case CMD_WIFI_CHANGE_NEW_SCAN_RESULTS: + // nothing to do + break; default: return NOT_HANDLED; } @@ -1765,26 +1607,24 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub { @Override public boolean processMessage(Message msg) { if (DBG) localLog("Stationary state got " + msg); + ClientInfo ci = mClients.get(msg.replyTo); switch (msg.what) { - case WIFI_CHANGE_CMD_ENABLE : - // do nothing - break; - case WIFI_CHANGE_CMD_CHANGE_DETECTED: - if (DBG) localLog("Got wifi change detected"); - reportWifiChanged((ScanResult[])msg.obj); - transitionTo(mMovingState); + case WifiScanner.CMD_START_TRACKING_CHANGE: + addWifiChangeHandler(ci, msg.arg2); + replySucceeded(msg); break; - case WIFI_CHANGE_CMD_DISABLE: - if (DBG) localLog("Got Disable Wifi Change"); - mCurrentBssids = null; - removeScanRequest(); - untrackSignificantWifiChange(); - transitionTo(mDefaultState); + case WifiScanner.CMD_STOP_TRACKING_CHANGE: + removeWifiChangeHandler(ci, msg.arg2); break; - case WIFI_CHANGE_CMD_CONFIGURE: + case WifiScanner.CMD_CONFIGURE_WIFI_CHANGE: /* save configuration till we transition to moving state */ deferMessage(msg); break; + case CMD_WIFI_CHANGE_DETECTED: + if (DBG) localLog("Got wifi change detected"); + reportWifiChanged((ScanResult[]) msg.obj); + transitionTo(mMovingState); + break; default: return NOT_HANDLED; } @@ -1799,24 +1639,46 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub { @Override public void enter() { if (DBG) localLog("Entering MovingState"); + if (mTimeoutIntent == null) { + Intent intent = new Intent(ACTION_TIMEOUT, null); + mTimeoutIntent = PendingIntent.getBroadcast(mContext, 0, intent, 0); + + mContext.registerReceiver( + new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + sendMessage(CMD_WIFI_CHANGE_TIMEOUT); + } + }, new IntentFilter(ACTION_TIMEOUT)); + } issueFullScan(); } @Override public boolean processMessage(Message msg) { if (DBG) localLog("MovingState state got " + msg); + ClientInfo ci = mClients.get(msg.replyTo); switch (msg.what) { - case WIFI_CHANGE_CMD_ENABLE : - // do nothing + case WifiScanner.CMD_START_TRACKING_CHANGE: + addWifiChangeHandler(ci, msg.arg2); + replySucceeded(msg); break; - case WIFI_CHANGE_CMD_DISABLE: - if (DBG) localLog("Got Disable Wifi Change"); - mCurrentBssids = null; - removeScanRequest(); - untrackSignificantWifiChange(); - transitionTo(mDefaultState); + case WifiScanner.CMD_STOP_TRACKING_CHANGE: + removeWifiChangeHandler(ci, msg.arg2); break; - case WIFI_CHANGE_CMD_NEW_SCAN_RESULTS: + case WifiScanner.CMD_CONFIGURE_WIFI_CHANGE: + if (DBG) localLog("Got configuration from app"); + WifiScanner.WifiChangeSettings settings = + (WifiScanner.WifiChangeSettings) msg.obj; + reconfigureScan(settings); + mWifiChangeDetected = false; + long unchangedDelay = settings.unchangedSampleSize * settings.periodInMs; + mAlarmManager.cancel(mTimeoutIntent); + mAlarmManager.setExact(AlarmManager.RTC_WAKEUP, + System.currentTimeMillis() + unchangedDelay, + mTimeoutIntent); + break; + case CMD_WIFI_CHANGE_NEW_SCAN_RESULTS: if (DBG) localLog("Got scan results"); if (mScanResultsPending) { if (DBG) localLog("reconfiguring scan"); @@ -1829,26 +1691,14 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub { mScanResultsPending = false; } break; - case WIFI_CHANGE_CMD_CONFIGURE: - if (DBG) localLog("Got configuration from app"); - WifiScanner.WifiChangeSettings settings = - (WifiScanner.WifiChangeSettings) msg.obj; - reconfigureScan(settings); - mWifiChangeDetected = false; - long unchangedDelay = settings.unchangedSampleSize * settings.periodInMs; - mAlarmManager.cancel(mTimeoutIntent); - mAlarmManager.setExact(AlarmManager.RTC_WAKEUP, - System.currentTimeMillis() + unchangedDelay, - mTimeoutIntent); - break; - case WIFI_CHANGE_CMD_CHANGE_DETECTED: + case CMD_WIFI_CHANGE_DETECTED: if (DBG) localLog("Change detected"); mAlarmManager.cancel(mTimeoutIntent); reportWifiChanged((ScanResult[])msg.obj); mWifiChangeDetected = true; issueFullScan(); break; - case WIFI_CHANGE_CMD_CHANGE_TIMEOUT: + case CMD_WIFI_CHANGE_TIMEOUT: if (DBG) localLog("Got timeout event"); if (mWifiChangeDetected == false) { transitionTo(mStationaryState); @@ -1877,7 +1727,7 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub { } - void reconfigureScan(ScanData[] results, int period) { + private void reconfigureScan(ScanData[] results, int period) { // find brightest APs and set them as sentinels if (results.length < MAX_APS_TO_TRACK) { localLog("too few APs (" + results.length + ") available to track wifi change"); @@ -1963,7 +1813,7 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub { mCurrentBssids = brightest; } - void reconfigureScan(WifiScanner.WifiChangeSettings settings) { + private void reconfigureScan(WifiScanner.WifiChangeSettings settings) { if (settings.bssidInfos.length < MAX_APS_TO_TRACK) { localLog("too few APs (" + settings.bssidInfos.length @@ -2009,19 +1859,19 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub { @Override void deliverScanResults(int handler, ScanData results[]) { if (DBG) localLog("Delivering messages directly"); - sendMessage(WIFI_CHANGE_CMD_NEW_SCAN_RESULTS, 0, 0, results); + sendMessage(CMD_WIFI_CHANGE_NEW_SCAN_RESULTS, 0, 0, results); } } @Override public void onChangesFound(ScanResult results[]) { - sendMessage(WIFI_CHANGE_CMD_CHANGE_DETECTED, 0, 0, results); + sendMessage(CMD_WIFI_CHANGE_DETECTED, 0, 0, results); } ClientInfo mClientInfo = new WifiChangeClientInfo(); private static final int SCAN_COMMAND_ID = 1; - void addScanRequest(ScanSettings settings) { + private void addScanRequest(ScanSettings settings) { if (DBG) localLog("Starting scans"); Message msg = Message.obtain(); msg.what = WifiScanner.CMD_START_BACKGROUND_SCAN; @@ -2030,7 +1880,7 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub { mClientHandler.sendMessage(msg); } - void removeScanRequest() { + private void removeScanRequest() { if (DBG) localLog("Stopping scans"); Message msg = Message.obtain(); msg.what = WifiScanner.CMD_STOP_BACKGROUND_SCAN; @@ -2038,15 +1888,59 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub { mClientHandler.sendMessage(msg); } - void trackSignificantWifiChange(WifiScanner.WifiChangeSettings settings) { + private void trackSignificantWifiChange(WifiScanner.WifiChangeSettings settings) { mScannerImpl.untrackSignificantWifiChange(); mScannerImpl.trackSignificantWifiChange(settings, this); } - void untrackSignificantWifiChange() { + private void untrackSignificantWifiChange() { mScannerImpl.untrackSignificantWifiChange(); } + private void addWifiChangeHandler(ClientInfo ci, int handler) { + mActiveWifiChangeHandlers.add(Pair.create(ci, handler)); + } + + private void removeWifiChangeHandler(ClientInfo ci, int handler) { + mActiveWifiChangeHandlers.remove(Pair.create(ci, handler)); + untrackSignificantWifiChangeOnEmpty(); + } + + private void untrackSignificantWifiChangeOnEmpty() { + if (mActiveWifiChangeHandlers.isEmpty()) { + if (DBG) localLog("Got Disable Wifi Change"); + mCurrentBssids = null; + removeScanRequest(); + untrackSignificantWifiChange(); + transitionTo(mDefaultState); + } + } + + private void reportWifiChanged(ScanResult[] results) { + WifiScanner.ParcelableScanResults parcelableScanResults = + new WifiScanner.ParcelableScanResults(results); + Iterator<Pair<ClientInfo, Integer>> it = mActiveWifiChangeHandlers.iterator(); + while (it.hasNext()) { + Pair<ClientInfo, Integer> entry = it.next(); + ClientInfo ci = entry.first; + int handler = entry.second; + ci.sendMessage(WifiScanner.CMD_WIFI_CHANGE_DETECTED, 0, handler, + parcelableScanResults); + } + } + + private void reportWifiStabilized(ScanResult[] results) { + WifiScanner.ParcelableScanResults parcelableScanResults = + new WifiScanner.ParcelableScanResults(results); + Iterator<Pair<ClientInfo, Integer>> it = mActiveWifiChangeHandlers.iterator(); + while (it.hasNext()) { + Pair<ClientInfo, Integer> entry = it.next(); + ClientInfo ci = entry.first; + int handler = entry.second; + ci.sendMessage(WifiScanner.CMD_WIFI_CHANGES_STABILIZED, 0, handler, + parcelableScanResults); + } + } } private static String toString(int uid, ScanSettings settings) { |