diff options
15 files changed, 327 insertions, 1224 deletions
diff --git a/service/java/com/android/server/wifi/HalWifiScannerImpl.java b/service/java/com/android/server/wifi/HalWifiScannerImpl.java index dc6fc1b61..fc5d18f4a 100644 --- a/service/java/com/android/server/wifi/HalWifiScannerImpl.java +++ b/service/java/com/android/server/wifi/HalWifiScannerImpl.java @@ -50,10 +50,14 @@ public class HalWifiScannerImpl extends WifiScannerImpl implements Handler.Callb mWifiNative = wifiNative; mEventHandler = new Handler(looper, this); - WifiMonitor.getInstance().registerHandler(mWifiNative.getInterfaceName(), - WifiMonitor.SCAN_FAILED_EVENT, mEventHandler); - WifiMonitor.getInstance().registerHandler(mWifiNative.getInterfaceName(), - WifiMonitor.SCAN_RESULTS_EVENT, mEventHandler); + // We can't enable these until WifiStateMachine switches to using WifiScanner because + // WifiMonitor only supports sending results to one listener + // TODO Enable these + // Also need to fix tests again when this is enabled + // WifiMonitor.getInstance().registerHandler(mWifiNative.getInterfaceName(), + // WifiMonitor.SCAN_FAILED_EVENT, mEventHandler); + // WifiMonitor.getInstance().registerHandler(mWifiNative.getInterfaceName(), + // WifiMonitor.SCAN_RESULTS_EVENT, mEventHandler); } @Override @@ -62,9 +66,7 @@ public class HalWifiScannerImpl extends WifiScannerImpl implements Handler.Callb case WifiMonitor.SCAN_FAILED_EVENT: Log.w(TAG, "Single scan failed"); if (mSingleScanEventHandler != null) { - if (mSingleScanEventHandler != null) { - mSingleScanEventHandler.onScanStatus(WifiNative.WIFI_SCAN_DISABLED); - } + // TODO indicate failure to caller mSingleScanEventHandler = null; } break; @@ -114,17 +116,9 @@ public class HalWifiScannerImpl extends WifiScannerImpl implements Handler.Callb } mSingleScanEventHandler = eventHandler; - if (!mWifiNative.scan(freqs)) { - Log.e(TAG, "Failed to start scan, freqs=" + freqs); - // indicate scan failure async - mEventHandler.post(new Runnable() { - public void run() { - if (mSingleScanEventHandler != null) { - mSingleScanEventHandler.onScanStatus(WifiNative.WIFI_SCAN_DISABLED); - } - mSingleScanEventHandler = null; - } - }); + if (!mWifiNative.scan(WifiNative.SCAN_WITHOUT_CONNECTION_SETUP, freqs)) { + mSingleScanEventHandler = null; + // TODO call on failure callback in handler } return true; } @@ -154,7 +148,7 @@ public class HalWifiScannerImpl extends WifiScannerImpl implements Handler.Callb Arrays.sort(results, SCAN_RESULT_SORT_COMPARATOR); mLatestSingleScanResult = new WifiScanner.ScanData(0, 0, results); if (mSingleScanEventHandler != null) { - mSingleScanEventHandler.onScanStatus(WifiNative.WIFI_SCAN_RESULTS_AVAILABLE); + mSingleScanEventHandler.onScanResultsAvailable(); mSingleScanEventHandler = null; } } diff --git a/service/java/com/android/server/wifi/ScanDetailUtil.java b/service/java/com/android/server/wifi/ScanDetailUtil.java deleted file mode 100644 index 07eaafbb6..000000000 --- a/service/java/com/android/server/wifi/ScanDetailUtil.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (C) 2016 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.server.wifi; - -import android.net.wifi.ScanResult; - -import com.android.server.wifi.hotspot2.NetworkDetail; - -/** - * Utility for converting a ScanResult to a ScanDetail. - * Only fields that are suppported in ScanResult are copied. - */ -public class ScanDetailUtil { - private ScanDetailUtil() { /* not constructable */ } - - public static ScanDetail toScanDetail(ScanResult scanResult) { - NetworkDetail networkDetail = new NetworkDetail(scanResult.BSSID, - scanResult.informationElements, scanResult.anqpLines, scanResult.frequency); - ScanDetail scanDetail = new ScanDetail(networkDetail, scanResult.wifiSsid, - scanResult.BSSID, scanResult.capabilities, scanResult.level, scanResult.frequency, - scanResult.timestamp); - scanDetail.getScanResult().informationElements = scanResult.informationElements; - scanDetail.getScanResult().anqpLines = scanResult.anqpLines; - return scanDetail; - } - -} diff --git a/service/java/com/android/server/wifi/SupplicantWifiScannerImpl.java b/service/java/com/android/server/wifi/SupplicantWifiScannerImpl.java index 8c8b3f27d..78e213797 100644 --- a/service/java/com/android/server/wifi/SupplicantWifiScannerImpl.java +++ b/service/java/com/android/server/wifi/SupplicantWifiScannerImpl.java @@ -95,10 +95,14 @@ public class SupplicantWifiScannerImpl extends WifiScannerImpl implements Handle mAlarmManager = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE); mEventHandler = new Handler(looper, this); - WifiMonitor.getInstance().registerHandler(mWifiNative.getInterfaceName(), - WifiMonitor.SCAN_FAILED_EVENT, mEventHandler); - WifiMonitor.getInstance().registerHandler(mWifiNative.getInterfaceName(), - WifiMonitor.SCAN_RESULTS_EVENT, mEventHandler); + // We can't enable these until WifiStateMachine switches to using WifiScanner because + // WifiMonitor only supports sending results to one listener + // TODO Enable these + // Also need to fix tests again when this is enabled + // WifiMonitor.getInstance().registerHandler(mWifiNative.getInterfaceName(), + // WifiMonitor.SCAN_FAILED_EVENT, mEventHandler); + // WifiMonitor.getInstance().registerHandler(mWifiNative.getInterfaceName(), + // WifiMonitor.SCAN_RESULTS_EVENT, mEventHandler); } @Override @@ -111,7 +115,6 @@ public class SupplicantWifiScannerImpl extends WifiScannerImpl implements Handle capabilities.max_hotlist_bssids = 0; capabilities.max_significant_wifi_change_aps = 0; // TODO reenable once scan results handlers are enabled again - // NOTE: this only disables background scan requests return false; } @@ -252,8 +255,7 @@ public class SupplicantWifiScannerImpl extends WifiScannerImpl implements Handle } Set<Integer> freqs = new HashSet<>(); - final LastScanSettings newScanSettings = - new LastScanSettings(SystemClock.elapsedRealtime()); + LastScanSettings newScanSettings = new LastScanSettings(SystemClock.elapsedRealtime()); // Update scan settings if there is a pending scan if (!mBackgroundScanPaused) { @@ -356,7 +358,8 @@ public class SupplicantWifiScannerImpl extends WifiScannerImpl implements Handle } if (freqs.size() > 0) { - boolean success = mWifiNative.scan(freqs); + boolean success = mWifiNative.scan( + WifiNative.SCAN_WITHOUT_CONNECTION_SETUP, freqs); if (success) { // TODO handle scan timeout Log.d(TAG, "Starting wifi scan for " + freqs.size() + " freqs" @@ -364,18 +367,8 @@ public class SupplicantWifiScannerImpl extends WifiScannerImpl implements Handle + ", single=" + newScanSettings.singleScanActive); mLastScanSettings = newScanSettings; } else { - Log.e(TAG, "Failed to start scan, freqs=" + freqs); - // indicate scan failure async - mEventHandler.post(new Runnable() { - public void run() { - newScanSettings.singleScanActive = false; - if (newScanSettings.singleScanEventHandler != null) { - newScanSettings.singleScanEventHandler - .onScanStatus(WifiNative.WIFI_SCAN_DISABLED); - } - } - }); - // TODO if scans fail enough background scans should be failed as well + Log.w(TAG, "Failed starting wifi scan for " + freqs.size() + " freqs"); + // TODO indicate failure for single and background scans } } } @@ -464,8 +457,7 @@ public class SupplicantWifiScannerImpl extends WifiScannerImpl implements Handle / 100) || mBackgroundScanBuffer.size() >= mLastScanSettings.reportNumScansThreshold))) { - mBackgroundScanEventHandler - .onScanStatus(WifiNative.WIFI_SCAN_RESULTS_AVAILABLE); + mBackgroundScanEventHandler.onScanStatus(); } } @@ -492,8 +484,7 @@ public class SupplicantWifiScannerImpl extends WifiScannerImpl implements Handle Collections.sort(singleScanResults, SCAN_RESULT_SORT_COMPARATOR); mLatestSingleScanResult = new WifiScanner.ScanData(mLastScanSettings.scanId, 0, singleScanResults.toArray(new ScanResult[singleScanResults.size()])); - mLastScanSettings.singleScanEventHandler - .onScanStatus(WifiNative.WIFI_SCAN_RESULTS_AVAILABLE); + mLastScanSettings.singleScanEventHandler.onScanResultsAvailable(); } mLastScanSettings = null; diff --git a/service/java/com/android/server/wifi/WifiNative.java b/service/java/com/android/server/wifi/WifiNative.java index 0560345f6..8166328dc 100644 --- a/service/java/com/android/server/wifi/WifiNative.java +++ b/service/java/com/android/server/wifi/WifiNative.java @@ -324,9 +324,12 @@ public class WifiNative { } - public boolean scan(Set<Integer> freqs) { + public static final int SCAN_WITHOUT_CONNECTION_SETUP = 1; + public static final int SCAN_WITH_CONNECTION_SETUP = 2; + + public boolean scan(int type, Set<Integer> freqs) { if(freqs == null) { - return scan((String) null); + return scan(type, (String)null); } else if (freqs.size() != 0) { StringBuilder freqList = new StringBuilder(); @@ -337,18 +340,22 @@ public class WifiNative { freqList.append(freq.toString()); first = false; } - return scan(freqList.toString()); + return scan(type, freqList.toString()); } else { return false; } } - private boolean scan(String freqList) { - if (freqList == null) { - return doBooleanCommand("SCAN TYPE=ONLY"); // Scan all channels + private boolean scan(int type, String freqList) { + if (type == SCAN_WITHOUT_CONNECTION_SETUP) { + if (freqList == null) return doBooleanCommand("SCAN TYPE=ONLY"); + else return doBooleanCommand("SCAN TYPE=ONLY freq=" + freqList); + } else if (type == SCAN_WITH_CONNECTION_SETUP) { + if (freqList == null) return doBooleanCommand("SCAN"); + else return doBooleanCommand("SCAN freq=" + freqList); } else { - return doBooleanCommand("SCAN TYPE=ONLY freq=" + freqList); + throw new IllegalArgumentException("Invalid scan type"); } } @@ -670,7 +677,6 @@ public class WifiNative { ScanDetail scan = new ScanDetail(networkDetail, wifiSsid, bssid, flags, level, freq, tsf); scan.getScanResult().informationElements = infoElements; - scan.getScanResult().anqpLines = anqpLines; results.add(scan); } catch (IllegalArgumentException iae) { Log.d(TAG, "Failed to parse information elements: " + iae); @@ -1725,17 +1731,18 @@ public class WifiNative { } public static interface ScanEventHandler { + void onScanResultsAvailable(); void onFullScanResult(ScanResult fullScanResult); - void onScanStatus(int event); + void onScanStatus(); void onScanPaused(WifiScanner.ScanData[] data); void onScanRestarted(); } /* scan status, keep these values in sync with gscan.h */ - public static final int WIFI_SCAN_RESULTS_AVAILABLE = 0; - public static final int WIFI_SCAN_THRESHOLD_NUM_SCANS = 1; - public static final int WIFI_SCAN_THRESHOLD_PERCENT = 2; - public static final int WIFI_SCAN_DISABLED = 3; + private static final int WIFI_SCAN_RESULTS_AVAILABLE = 0; + private static final int WIFI_SCAN_THRESHOLD_NUM_SCANS = 1; + private static final int WIFI_SCAN_THRESHOLD_PERCENT = 2; + private static final int WIFI_SCAN_DISABLED = 3; // Callback from native private static void onScanStatus(int id, int event) { @@ -1744,7 +1751,7 @@ public class WifiNative { || event == WIFI_SCAN_THRESHOLD_PERCENT) { if (handler != null) { // TODO pass event back to framework - handler.onScanStatus(event); + handler.onScanStatus(); } } else if (event == WIFI_SCAN_DISABLED) { diff --git a/service/java/com/android/server/wifi/WifiScanningScheduler.java b/service/java/com/android/server/wifi/WifiScanningScheduler.java index 744afd55c..7b36b9918 100644 --- a/service/java/com/android/server/wifi/WifiScanningScheduler.java +++ b/service/java/com/android/server/wifi/WifiScanningScheduler.java @@ -28,17 +28,17 @@ import java.util.Collection; */ public abstract class WifiScanningScheduler { - static final int DEFAULT_MAX_BUCKETS = 8; - static final int DEFAULT_MAX_CHANNELS = 32; + private static final int DEFAULT_MAX_BUCKETS = 8; + private static final int DEFAULT_MAX_CHANNELS = 32; // anecdotally, some chipsets will fail without explanation with a higher batch size, and // there is apparently no way to retrieve the maximum batch size - static final int DEFAULT_MAX_SCANS_TO_BATCH = 10; - static final int DEFAULT_MAX_AP_PER_SCAN = 32; + private static final int DEFAULT_MAX_SCANS_TO_BATCH = 10; + private static final int DEFAULT_MAX_AP_PER_SCAN = 32; - private int mMaxBuckets = DEFAULT_MAX_BUCKETS; - private int mMaxChannels = DEFAULT_MAX_CHANNELS; - private int mMaxBatch = DEFAULT_MAX_SCANS_TO_BATCH; - private int mMaxApPerScan = DEFAULT_MAX_AP_PER_SCAN; + private static int mMaxBuckets = DEFAULT_MAX_BUCKETS; + private static int mMaxChannels = DEFAULT_MAX_CHANNELS; + private static int mMaxBatch = DEFAULT_MAX_SCANS_TO_BATCH; + private static int mMaxApPerScan = DEFAULT_MAX_AP_PER_SCAN; int getMaxBuckets() { return mMaxBuckets; diff --git a/service/java/com/android/server/wifi/WifiScanningServiceImpl.java b/service/java/com/android/server/wifi/WifiScanningServiceImpl.java index 3d61c1a63..777b3f9b6 100644 --- a/service/java/com/android/server/wifi/WifiScanningServiceImpl.java +++ b/service/java/com/android/server/wifi/WifiScanningServiceImpl.java @@ -43,8 +43,6 @@ import android.os.WorkSource; import android.util.ArrayMap; import android.util.LocalLog; import android.util.Log; -import android.util.Pair; -import android.util.SparseIntArray; import com.android.internal.app.IBatteryStats; import com.android.internal.util.AsyncChannel; @@ -192,15 +190,13 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub { case WifiScanner.CMD_CONFIGURE_WIFI_CHANGE: case WifiScanner.CMD_START_TRACKING_CHANGE: case WifiScanner.CMD_STOP_TRACKING_CHANGE: - mStateMachine.sendMessage(Message.obtain(msg)); - break; case WifiScanner.CMD_START_SINGLE_SCAN: case WifiScanner.CMD_STOP_SINGLE_SCAN: - mSingleScanStateMachine.sendMessage(Message.obtain(msg)); - break; + mStateMachine.sendMessage(Message.obtain(msg)); + return; default: replyFailed(msg, WifiScanner.REASON_INVALID_REQUEST, "Invalid request"); - break; + return; } } } @@ -217,7 +213,7 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub { 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_DISABLED = BASE + 10; + private static final int CMD_STOP_SCAN_INTERNAL = BASE + 10; private final Context mContext; private final Looper mLooper; @@ -228,7 +224,6 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub { private WifiNative.ScanSettings mPreviousSchedule; private WifiScanningStateMachine mStateMachine; - private WifiSingleScanStateMachine mSingleScanStateMachine; private ClientHandler mClientHandler; private final IBatteryStats mBatteryStats; @@ -248,7 +243,6 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub { mClientHandler = new ClientHandler(mLooper); mStateMachine = new WifiScanningStateMachine(mLooper); mWifiChangeStateMachine = new WifiChangeStateMachine(mLooper); - mSingleScanStateMachine = new WifiSingleScanStateMachine(mLooper); mContext.registerReceiver( new BroadcastReceiver() { @@ -259,342 +253,16 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub { if (DBG) localLog("SCAN_AVAILABLE : " + state); if (state == WifiManager.WIFI_STATE_ENABLED) { mStateMachine.sendMessage(CMD_DRIVER_LOADED); - mSingleScanStateMachine.sendMessage(CMD_DRIVER_LOADED); } else if (state == WifiManager.WIFI_STATE_DISABLED) { mStateMachine.sendMessage(CMD_DRIVER_UNLOADED); - mSingleScanStateMachine.sendMessage(CMD_DRIVER_UNLOADED); } } }, new IntentFilter(WifiManager.WIFI_SCAN_AVAILABLE)); mStateMachine.start(); mWifiChangeStateMachine.start(); - mSingleScanStateMachine.start(); - } - - /** - * A map of objects of a WifiScanner client and handler id to an object of type T - */ - private static class ClientHandlerMap<T> extends HashMap<Pair<ClientInfo, Integer>, T> { - public ClientHandlerMap(int initialSize) { - super(initialSize); - } - - public T put(ClientInfo ci, int handler, T value) { - return put(Pair.create(ci, handler), value); - } - - public T get(ClientInfo ci, int handler) { - return get(Pair.create(ci, handler)); - } - - public T remove(ClientInfo ci, int handler) { - return remove(Pair.create(ci, handler)); - } } - /** - * State machine that holds the state of single scans. Scans should only be active in the - * ScanningState. The pending scans and active scans maps are swaped when entering - * ScanningState. Any requests queued while scanning will be placed in the pending queue and - * executed after transitioning back to NotScanningState. - */ - class WifiSingleScanStateMachine extends StateMachine implements WifiNative.ScanEventHandler { - private final DefaultState mDefaultState = new DefaultState(); - private final DriverStartedState mDriverStartedState = new DriverStartedState(); - private final NotScanningState mNotScanningState = new NotScanningState(); - private final ScanningState mScanningState = new ScanningState(); - - private ClientHandlerMap<ScanSettings> mActiveScans = new ClientHandlerMap<>(4); - private ClientHandlerMap<ScanSettings> mPendingScans = new ClientHandlerMap<>(4); - - public WifiSingleScanStateMachine(Looper looper) { - super("WifiSingleScanStateMachine", looper); - - setLogRecSize(128); - setLogOnlyTransitions(false); - - // CHECKSTYLE:OFF IndentationCheck - addState(mDefaultState); - addState(mDriverStartedState, mDefaultState); - addState(mNotScanningState, mDriverStartedState); - addState(mScanningState, mDriverStartedState); - // CHECKSTYLE:ON IndentationCheck - - setInitialState(mDefaultState); - } - - /** - * Called to indicate a change in state for the current scan. - * Will dispatch a coresponding event to the state machine - */ - @Override - public void onScanStatus(int event) { - if (DBG) localLog("onScanStatus event received, event=" + event); - switch(event) { - case WifiNative.WIFI_SCAN_RESULTS_AVAILABLE: - case WifiNative.WIFI_SCAN_THRESHOLD_NUM_SCANS: - case WifiNative.WIFI_SCAN_THRESHOLD_PERCENT: - sendMessage(CMD_SCAN_RESULTS_AVAILABLE); - break; - case WifiNative.WIFI_SCAN_DISABLED: - sendMessage(CMD_SCAN_DISABLED); - break; - default: - Log.e(TAG, "Unknown scan status event: " + event); - break; - } - } - - /** - * Called for each full scan result if requested - */ - @Override - public void onFullScanResult(ScanResult fullScanResult) { - if (DBG) localLog("onFullScanResult received"); - sendMessage(CMD_FULL_SCAN_RESULTS, 0, 0, fullScanResult); - } - - @Override - public void onScanPaused(ScanData scanData[]) { - // should not happen for single scan - Log.e(TAG, "Got scan paused for single scan"); - } - - @Override - public void onScanRestarted() { - // should not happen for single scan - Log.e(TAG, "Got scan restarted for single scan"); - } - - class DefaultState extends State { - @Override - public void enter() { - mActiveScans.clear(); - mPendingScans.clear(); - } - @Override - public boolean processMessage(Message msg) { - switch (msg.what) { - case CMD_DRIVER_LOADED: - transitionTo(mNotScanningState); - return HANDLED; - case CMD_DRIVER_UNLOADED: - transitionTo(mDefaultState); - return HANDLED; - case WifiScanner.CMD_START_SINGLE_SCAN: - case WifiScanner.CMD_STOP_SINGLE_SCAN: - replyFailed(msg, WifiScanner.REASON_UNSPECIFIED, "not available"); - return HANDLED; - case CMD_SCAN_RESULTS_AVAILABLE: - if (DBG) localLog("ignored scan results available event"); - return HANDLED; - case CMD_FULL_SCAN_RESULTS: - if (DBG) localLog("ignored full scan result event"); - return HANDLED; - default: - return NOT_HANDLED; - } - - } - } - - /** - * State representing when the driver is running. This state is not meant to be transitioned - * directly, but is instead indented as a parent state of ScanningState and NotScanningState - * to hold common functionality and handle cleaning up scans when the driver is shut down. - */ - class DriverStartedState extends State { - @Override - public void exit() { - sendOpFailedToAll(mPendingScans, WifiScanner.REASON_UNSPECIFIED, - "Scan was interrupted"); - mPendingScans.clear(); - } - - @Override - public boolean processMessage(Message msg) { - ClientInfo ci = mClients.get(msg.replyTo); - - switch (msg.what) { - case WifiScanner.CMD_START_SINGLE_SCAN: - if (validateAndAddToScanQueue(ci, msg.arg2, (ScanSettings) msg.obj)) { - replySucceeded(msg); - // if were not currently scanning then try to start - if (getCurrentState() != mScanningState) { - tryToStartNewScan(); - } - } else { - replyFailed(msg, WifiScanner.REASON_INVALID_REQUEST, "bad request"); - } - return HANDLED; - case WifiScanner.CMD_STOP_SINGLE_SCAN: - removeSingleScanRequest(ci, msg.arg2); - return HANDLED; - default: - return NOT_HANDLED; - } - } - } - - class NotScanningState extends State { - @Override - public void enter() { - tryToStartNewScan(); - } - - @Override - public boolean processMessage(Message msg) { - return NOT_HANDLED; - } - } - - class ScanningState extends State { - @Override - public void exit() { - // if any scans are still active (never got results available then indicate failure - sendOpFailedToAll(mActiveScans, WifiScanner.REASON_UNSPECIFIED, - "Scan was interrupted"); - mActiveScans.clear(); - } - - // TODO correctly handle battery blaming - @Override - public boolean processMessage(Message msg) { - switch (msg.what) { - case CMD_SCAN_RESULTS_AVAILABLE: - reportScanResults(mScannerImpl.getLatestSingleScanResults()); - mActiveScans.clear(); - transitionTo(mNotScanningState); - return HANDLED; - case CMD_FULL_SCAN_RESULTS: - reportFullScanResult((ScanResult) msg.obj); - return HANDLED; - case CMD_SCAN_DISABLED: - sendOpFailedToAll(mActiveScans, WifiScanner.REASON_UNSPECIFIED, - "Scan was interrupted"); - mActiveScans.clear(); - transitionTo(mNotScanningState); - return HANDLED; - default: - return NOT_HANDLED; - } - } - } - - boolean validateAndAddToScanQueue(ClientInfo ci, int handler, ScanSettings settings) { - if (ci == null) { - Log.d(TAG, "Failing single scan request ClientInfo not found " + handler); - return false; - } - ChannelSpec[] channels = WifiChannelHelper.getChannelsForScanSettings(settings); - if (channels.length == 0) { - Log.d(TAG, "Failing single scan because channel list was empty"); - return false; - } - logScanRequest("validateSingleScanAndAddToScanQueue", ci, handler, settings); - mPendingScans.put(ci, handler, settings); - return true; - } - - void removeSingleScanRequest(ClientInfo ci, int handler) { - if (ci != null) { - logScanRequest("removeSingleScanRequest", ci, handler, null); - mPendingScans.remove(ci, handler); - mActiveScans.remove(ci, handler); - } - } - - void tryToStartNewScan() { - // TODO move merging logic to a scheduler - int reportEvents = WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN; - ArrayList<Integer> allChannels = new ArrayList<>(); - for (ScanSettings settings : mPendingScans.values()) { - ChannelSpec[] channels = WifiChannelHelper.getChannelsForScanSettings(settings); - for (int i = 0; i < channels.length; ++i) { - allChannels.add(channels[i].frequency); - } - if ((settings.reportEvents & WifiScanner.REPORT_EVENT_FULL_SCAN_RESULT) != 0) { - reportEvents |= WifiScanner.REPORT_EVENT_FULL_SCAN_RESULT; - } - } - if (allChannels.size() > 0) { - WifiNative.ScanSettings settings = new WifiNative.ScanSettings(); - settings.num_buckets = 1; - WifiNative.BucketSettings bucketSettings = new WifiNative.BucketSettings(); - bucketSettings.bucket = 0; - bucketSettings.period_ms = 0; - bucketSettings.report_events = reportEvents; - bucketSettings.num_channels = allChannels.size(); - bucketSettings.channels = new WifiNative.ChannelSettings[allChannels.size()]; - for (int i = 0; i < bucketSettings.channels.length; ++i) { - bucketSettings.channels[i] = new WifiNative.ChannelSettings(); - bucketSettings.channels[i].frequency = allChannels.get(i); - } - settings.buckets = new WifiNative.BucketSettings[] {bucketSettings}; - if (mScannerImpl.startSingleScan(settings, this)) { - // swap pending and active scan requests - ClientHandlerMap<ScanSettings> tmp = mActiveScans; - mActiveScans = mPendingScans; - mPendingScans = tmp; - // make sure that the pending list is clear - mPendingScans.clear(); - transitionTo(mScanningState); - } else { - // notify and cancel failed scans - sendOpFailedToAll(mPendingScans, WifiScanner.REASON_UNSPECIFIED, - "Failed to start single scan"); - mPendingScans.clear(); - } - } else { - // notify and cancel failed scans - sendOpFailedToAll(mPendingScans, WifiScanner.REASON_INVALID_REQUEST, - "No channels specified"); - mPendingScans.clear(); - } - } - - void sendOpFailedToAll(ClientHandlerMap<?> clientHandlers, int reason, String description) { - for (Pair<ClientInfo, Integer> key : clientHandlers.keySet()) { - ClientInfo ci = key.first; - int handler = key.second; - ci.sendMessage(WifiScanner.CMD_OP_FAILED, 0, handler, - new WifiScanner.OperationResult(reason, description)); - } - } - - // TODO fix shouldReport checks - // currently these checks work becuase the shouldReport methods don't yet rely on the - // internal state of the scheduler. - void reportFullScanResult(ScanResult result) { - for (Map.Entry<Pair<ClientInfo, Integer>, ScanSettings> entry - : mActiveScans.entrySet()) { - ClientInfo ci = entry.getKey().first; - int handler = entry.getKey().second; - ScanSettings settings = entry.getValue(); - if (mScheduler.shouldReportFullScanResultForSettings(result, settings)) { - ci.sendMessage(WifiScanner.CMD_FULL_SCAN_RESULT, 0, handler, result); - } - } - } - - void reportScanResults(ScanData results) { - for (Map.Entry<Pair<ClientInfo, Integer>, ScanSettings> entry - : mActiveScans.entrySet()) { - ClientInfo ci = entry.getKey().first; - int handler = entry.getKey().second; - ScanSettings settings = entry.getValue(); - ScanData[] resultsArray = new ScanData[] {results}; - ScanData[] resultsToDeliver = - mScheduler.filterResultsForSettings(resultsArray, settings); - WifiScanner.ParcelableScanData parcelableScanData = - new WifiScanner.ParcelableScanData(resultsToDeliver); - ci.sendMessage(WifiScanner.CMD_SCAN_RESULT, 0, handler, parcelableScanData); - } - } - } - - class WifiScanningStateMachine extends StateMachine implements WifiNative.ScanEventHandler, WifiNative.HotlistEventHandler, WifiNative.SignificantWifiChangeEventHandler { @@ -608,31 +276,23 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub { setLogRecSize(512); setLogOnlyTransitions(false); - // CHECKSTYLE:OFF IndentationCheck addState(mDefaultState); addState(mStartedState, mDefaultState); addState(mPausedState, mDefaultState); - // CHECKSTYLE:ON IndentationCheck setInitialState(mDefaultState); } @Override - public void onScanStatus(int event) { - if (DBG) localLog("onScanStatus event received, event=" + event); - switch(event) { - case WifiNative.WIFI_SCAN_RESULTS_AVAILABLE: - case WifiNative.WIFI_SCAN_THRESHOLD_NUM_SCANS: - case WifiNative.WIFI_SCAN_THRESHOLD_PERCENT: - sendMessage(CMD_SCAN_RESULTS_AVAILABLE); - break; - case WifiNative.WIFI_SCAN_DISABLED: - sendMessage(CMD_SCAN_DISABLED); - break; - default: - Log.e(TAG, "Unknown scan status event: " + event); - break; - } + public void onScanResultsAvailable() { + if (DBG) localLog("onScanResultAvailable event received"); + sendMessage(CMD_SCAN_RESULTS_AVAILABLE); + } + + @Override + public void onScanStatus() { + if (DBG) localLog("onScanStatus event received"); + sendMessage(CMD_SCAN_RESULTS_AVAILABLE); } @Override @@ -680,9 +340,6 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub { public boolean processMessage(Message msg) { switch (msg.what) { case CMD_DRIVER_LOADED: - // TODO this should be moved to a common location since it is used outside - // of this state machine. It is ok right now becuase the driver loaded event - // is sent to this state machine first. if (mScannerImpl == null) { mScannerImpl = mScannerImplFactory.create(mContext, mLooper); } @@ -751,19 +408,33 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub { case CMD_DRIVER_UNLOADED: return NOT_HANDLED; case WifiScanner.CMD_START_BACKGROUND_SCAN: - if (addBackgroundScanRequest(ci, msg.arg2, (ScanSettings) msg.obj)) { + if (addScanRequest(ci, msg.arg2, (ScanSettings) msg.obj)) { replySucceeded(msg); } else { replyFailed(msg, WifiScanner.REASON_INVALID_REQUEST, "bad request"); } break; case WifiScanner.CMD_STOP_BACKGROUND_SCAN: - removeBackgroundScanRequest(ci, msg.arg2); + removeScanRequest(ci, msg.arg2); break; case WifiScanner.CMD_GET_SCAN_RESULTS: reportScanResults(mScannerImpl.getLatestBatchedScanResults(true)); replySucceeded(msg); break; + case WifiScanner.CMD_START_SINGLE_SCAN: + if (addSingleScanRequest(ci, msg.arg2, (ScanSettings) msg.obj)) { + replySucceeded(msg); + } else { + replyFailed(msg, WifiScanner.REASON_INVALID_REQUEST, "bad request"); + } + break; + case WifiScanner.CMD_STOP_SINGLE_SCAN: + removeScanRequest(ci, msg.arg2); + break; + case CMD_STOP_SCAN_INTERNAL: + localLog("Removing single shot scan"); + removeScanRequest((ClientInfo) msg.obj, msg.arg2); + break; case WifiScanner.CMD_SET_HOTLIST: setHotlist(ci, msg.arg2, (WifiScanner.HotlistSettings) msg.obj); replySucceeded(msg); @@ -820,10 +491,6 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub { reportScanResults((ScanData[]) msg.obj); transitionTo(mPausedState); break; - case CMD_SCAN_DISABLED: - // TODO handle this gracefully (currently no implementations are know to - // report this) - break; default: return NOT_HANDLED; } @@ -856,14 +523,8 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub { private class ClientInfo { private final AsyncChannel mChannel; - /** - * Indicates if the client is still connected - * If the client is no longer connected then messages to it will be signlently dropped - */ - private boolean mDisconnected = false; private final int mUid; private final WorkSource mWorkSource; - private boolean mScanWorkReported = false; ClientInfo(int uid, AsyncChannel c) { @@ -873,12 +534,6 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub { if (DBG) localLog("New client, channel: " + c); } - void sendMessage(int what, int arg1, int arg2, Object obj) { - if (!mDisconnected) { - mChannel.sendMessage(what, arg1, arg2, obj); - } - } - void reportBatchedScanStart() { if (mUid == 0) return; @@ -905,7 +560,7 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub { int getCsph() { int csph = 0; - for (ScanSettings settings : getBackgroundScanSettings()) { + for (ScanSettings settings : getScanSettings()) { int num_channels = WifiChannelHelper.getChannelsForScanSettings(settings).length; int scans_per_Hour = settings.periodInMs == 0 ? 1 : (3600 * 1000) / settings.periodInMs; @@ -920,7 +575,7 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub { reportBatchedScanStop(); mScanWorkReported = false; } - if (mBackgroundScanSettings.isEmpty()) { + if (mScanSettings.isEmpty() == false) { reportBatchedScanStart(); mScanWorkReported = true; } @@ -928,15 +583,14 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub { @Override public String toString() { - return "ClientInfo[uid=" + mUid + "]"; + return "ClientInfo[uid=" + mUid + ", channel=" + mChannel + "]"; } void dump(FileDescriptor fd, PrintWriter pw, String[] args) { StringBuilder sb = new StringBuilder(); sb.append(toString()); - Iterator<Map.Entry<Integer, ScanSettings>> it = - mBackgroundScanSettings.entrySet().iterator(); + Iterator<Map.Entry<Integer, ScanSettings>> it = mScanSettings.entrySet().iterator(); for (; it.hasNext(); ) { Map.Entry<Integer, ScanSettings> entry = it.next(); sb.append("ScanId ").append(entry.getKey()).append("\n"); @@ -949,26 +603,33 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub { pw.println(sb.toString()); } - private final Map<Integer, ScanSettings> mBackgroundScanSettings = - new HashMap<Integer, ScanSettings>(4); - private final SparseIntArray mBackgroundScanPeriods = new SparseIntArray(4); + HashMap<Integer, ScanSettings> mScanSettings = new HashMap<Integer, ScanSettings>(4); + HashMap<Integer, Integer> mScanPeriods = new HashMap<Integer, Integer>(4); - void addBackgroundScanRequest(ScanSettings settings, int id) { - mBackgroundScanSettings.put(id, settings); + void addScanRequest(ScanSettings settings, int id) { + mScanSettings.put(id, settings); reportScanWorkUpdate(); } - void removeBackgroundScanRequest(int id) { - mBackgroundScanSettings.remove(id); + void removeScanRequest(int id) { + ScanSettings settings = mScanSettings.remove(id); + if (settings != null && settings.periodInMs == 0) { + /* this was a single shot scan */ + mChannel.sendMessage(WifiScanner.CMD_SINGLE_SCAN_COMPLETED, 0, id); + } reportScanWorkUpdate(); } - Collection<ScanSettings> getBackgroundScanSettings() { - return mBackgroundScanSettings.values(); + Iterator<Map.Entry<Integer, ScanSettings>> getScans() { + return mScanSettings.entrySet().iterator(); + } + + Collection<ScanSettings> getScanSettings() { + return mScanSettings.values(); } void reportScanResults(ScanData[] results) { - Iterator<Integer> it = mBackgroundScanSettings.keySet().iterator(); + Iterator<Integer> it = mScanSettings.keySet().iterator(); while (it.hasNext()) { int handler = it.next(); reportScanResults(results, handler); @@ -976,7 +637,7 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub { } void reportScanResults(ScanData[] results, int handler) { - ScanSettings settings = mBackgroundScanSettings.get(handler); + ScanSettings settings = mScanSettings.get(handler); ScanData[] resultsToDeliver = mScheduler.filterResultsForSettings(results, settings); @@ -985,6 +646,11 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub { deliverScanResults(handler, resultsToDeliver); } + + if (settings.periodInMs == 0) { + /* this is a single shot scan; stop the scan now */ + mStateMachine.sendMessage(CMD_STOP_SCAN_INTERNAL, 0, handler, this); + } } void deliverScanResults(int handler, ScanData results[]) { @@ -994,10 +660,10 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub { } void reportFullScanResult(ScanResult result) { - Iterator<Integer> it = mBackgroundScanSettings.keySet().iterator(); + Iterator<Integer> it = mScanSettings.keySet().iterator(); while (it.hasNext()) { int handler = it.next(); - ScanSettings settings = mBackgroundScanSettings.get(handler); + ScanSettings settings = mScanSettings.get(handler); if (mScheduler.shouldReportFullScanResultForSettings(result, settings)) { ScanResult newResult = new ScanResult(result); if (result.informationElements != null) { @@ -1012,18 +678,18 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub { } void reportPeriodChanged(int handler, ScanSettings settings, int newPeriodInMs) { - int prevPeriodInMs = mBackgroundScanPeriods.get(handler, 0); - if (prevPeriodInMs == 0) { - prevPeriodInMs = settings.periodInMs; + Integer prevPeriodObject = mScanPeriods.get(handler); + int prevPeriodInMs = settings.periodInMs; + if (prevPeriodObject != null) { + prevPeriodInMs = prevPeriodObject; } if (prevPeriodInMs != newPeriodInMs) { - mBackgroundScanPeriods.put(handler, newPeriodInMs); mChannel.sendMessage(WifiScanner.CMD_PERIOD_CHANGED, newPeriodInMs, handler); } } - private final Map<Integer, WifiScanner.HotlistSettings> mHotlistSettings = + private final HashMap<Integer, WifiScanner.HotlistSettings> mHotlistSettings = new HashMap<Integer, WifiScanner.HotlistSettings>(); void addHostlistSettings(WifiScanner.HotlistSettings settings, int handler) { @@ -1114,8 +780,7 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub { } void cleanup() { - mDisconnected = true; - mBackgroundScanSettings.clear(); + mScanSettings.clear(); updateSchedule(); mHotlistSettings.clear(); @@ -1164,7 +829,7 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub { private boolean updateSchedule() { ArrayList<ScanSettings> settings = new ArrayList<>(); for (ClientInfo client : mClients.values()) { - settings.addAll(client.getBackgroundScanSettings()); + settings.addAll(client.getScanSettings()); } mScheduler.updateSchedule(settings); @@ -1232,7 +897,7 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub { localLog(sb.toString()); } - boolean addBackgroundScanRequest(ClientInfo ci, int handler, ScanSettings settings) { + boolean addScanRequest(ClientInfo ci, int handler, ScanSettings settings) { // sanity check the input if (ci == null) { Log.d(TAG, "Failing scan request ClientInfo not found " + handler); @@ -1276,22 +941,48 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub { } } - logScanRequest("addBackgroundScanRequest", ci, handler, settings); - ci.addBackgroundScanRequest(settings, handler); + logScanRequest("addScanRequest", ci, handler, settings); + ci.addScanRequest(settings, handler); + + if (updateSchedule()) { + return true; + } else { + ci.removeScanRequest(handler); + localLog("Failing scan request because failed to reset scan"); + return false; + } + } + + boolean addSingleScanRequest(ClientInfo ci, int handler, ScanSettings settings) { + if (ci == null) { + Log.d(TAG, "Failing single scan request ClientInfo not found " + handler); + return false; + } + if (settings.reportEvents == 0) { + settings.reportEvents = WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN; + } + if (settings.periodInMs == 0) { + settings.periodInMs = 10000; // 10s - although second scan should never happen + } + + logScanRequest("addSingleScanRequest", ci, handler, settings); + ci.addScanRequest(settings, handler); if (updateSchedule()) { + /* reset periodInMs to 0 to indicate single shot scan */ + settings.periodInMs = 0; return true; } else { - ci.removeBackgroundScanRequest(handler); + ci.removeScanRequest(handler); localLog("Failing scan request because failed to reset scan"); return false; } } - void removeBackgroundScanRequest(ClientInfo ci, int handler) { + void removeScanRequest(ClientInfo ci, int handler) { if (ci != null) { - logScanRequest("removeBackgroundScanRequest", ci, handler, null); - ci.removeBackgroundScanRequest(handler); + logScanRequest("removeScanRequest", ci, handler, null); + ci.removeScanRequest(handler); updateSchedule(); } } @@ -1434,11 +1125,9 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub { mClients.put(null, mClientInfo); - // CHECKSTYLE:OFF IndentationCheck addState(mDefaultState); - addState(mStationaryState, mDefaultState); - addState(mMovingState, mDefaultState); - // CHECKSTYLE:ON IndentationCheck + addState(mStationaryState, mDefaultState); + addState(mMovingState, mDefaultState); setInitialState(mDefaultState); } @@ -1842,7 +1531,7 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub { } pw.println("listeners:"); for (ClientInfo client : mClients.values()) { - for (ScanSettings settings : client.getBackgroundScanSettings()) { + for (ScanSettings settings : client.getScanSettings()) { pw.println(" " + toString(client.mUid, settings)); } } diff --git a/service/java/com/android/server/wifi/WifiStateMachine.java b/service/java/com/android/server/wifi/WifiStateMachine.java index 1a4c2ece0..ec4d815d6 100644 --- a/service/java/com/android/server/wifi/WifiStateMachine.java +++ b/service/java/com/android/server/wifi/WifiStateMachine.java @@ -1400,6 +1400,8 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiPno getHandler()); mWifiMonitor.registerHandler(mInterfaceName, WifiMonitor.RX_HS20_ANQP_ICON_EVENT, getHandler()); + mWifiMonitor.registerHandler(mInterfaceName, WifiMonitor.SCAN_FAILED_EVENT, getHandler()); + mWifiMonitor.registerHandler(mInterfaceName, WifiMonitor.SCAN_RESULTS_EVENT, getHandler()); mWifiMonitor.registerHandler(mInterfaceName, WifiMonitor.SSID_REENABLED, getHandler()); mWifiMonitor.registerHandler(mInterfaceName, WifiMonitor.SSID_TEMP_DISABLED, getHandler()); mWifiMonitor.registerHandler(mInterfaceName, WifiMonitor.SUP_CONNECTION_EVENT, getHandler()); @@ -1995,7 +1997,7 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiPno } } - private void handleScanRequest(Message message) { + private void handleScanRequest(int type, Message message) { ScanSettings settings = null; WorkSource workSource = null; @@ -2016,7 +2018,7 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiPno } // call wifi native to start the scan - if (startScanNative(freqs)) { + if (startScanNative(type, freqs)) { // only count battery consumption if scan request is accepted noteScanStart(message.arg1, workSource); // a full scan covers everything, clearing scan request buffer @@ -2067,57 +2069,17 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiPno } - // TODO this is a temporary measure to bridge between WifiScanner and WifiStateMachine until - // scan functionality is refactored out of WifiStateMachine. - private WifiScanner.ScanListener mLastNativeScanListener = null; - private volatile ArrayList<ScanDetail> mLastNativeScanResults = new ArrayList<ScanDetail>(); /** * return true iff scan request is accepted */ - private boolean startScanNative(Set<Integer> freqs) { - if (mLastNativeScanListener != null) { - mWifiScanner.stopScan(mLastNativeScanListener); - mLastNativeScanListener = null; - } - WifiScanner.ScanSettings settings = new WifiScanner.ScanSettings(); - if (freqs == null) { - settings.band = WifiScanner.WIFI_BAND_BOTH_WITH_DFS; - } else { - settings.band = WifiScanner.WIFI_BAND_UNSPECIFIED; - int index = 0; - settings.channels = new WifiScanner.ChannelSpec[freqs.size()]; - for (Integer freq : freqs) { - settings.channels[index++] = new WifiScanner.ChannelSpec(freq); - } + private boolean startScanNative(int type, Set<Integer> freqs) { + if (mWifiNative.scan(type, freqs)) { + mIsScanOngoing = true; + mIsFullScanOngoing = (freqs == null); + lastScanFreqs = freqs; + return true; } - settings.reportEvents = WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN - | WifiScanner.REPORT_EVENT_FULL_SCAN_RESULT; - mLastNativeScanListener = new WifiScanner.ScanListener() { - private final ArrayList<ScanDetail> mNewScanResults = new ArrayList<>(); - - public void onSuccess() { - // the scan started successfully, but has not completed yet - } - public void onFailure(int reason, String description) { - Log.e(TAG, "Scan failed: reason=" + reason + ", " + description); - sendMessage(WifiMonitor.SCAN_FAILED_EVENT); - } - public void onResults(WifiScanner.ScanData[] results) { - mLastNativeScanResults = mNewScanResults; - sendMessage(WifiMonitor.SCAN_RESULTS_EVENT); - } - public void onFullResult(ScanResult fullScanResult) { - mNewScanResults.add(ScanDetailUtil.toScanDetail(fullScanResult)); - } - public void onPeriodChanged(int periodInMs) { - // does not occur for single scan - } - }; - mWifiScanner.startScan(settings, mLastNativeScanListener); - mIsScanOngoing = true; - mIsFullScanOngoing = (freqs == null); - lastScanFreqs = freqs; - return true; + return false; } /** @@ -3981,7 +3943,7 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiPno mNumScanResultsKnown = 0; mNumScanResultsReturned = 0; - ArrayList<ScanDetail> scanResults = mLastNativeScanResults; + ArrayList<ScanDetail> scanResults = mWifiNative.getScanResults(); if (scanResults.isEmpty()) { mScanResults = new ArrayList<>(); @@ -5051,6 +5013,13 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiPno mDhcpActive = false; } + void connectScanningService() { + + if (mWifiScanner == null) { + mWifiScanner = (WifiScanner) mContext.getSystemService(Context.WIFI_SCANNING_SERVICE); + } + } + private void handleIPv4Success(DhcpResults dhcpResults, int reason) { if (PDBG) { @@ -6186,17 +6155,11 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiPno class DriverStartedState extends State { @Override public void enter() { + if (PDBG) { logd("DriverStartedState enter"); } - // We can't do this in the constructor because WifiStateMachine is created before the - // wifi scanning service is initialized - if (mWifiScanner == null) { - mWifiScanner = - (WifiScanner) mContext.getSystemService(Context.WIFI_SCANNING_SERVICE); - } - mWifiLogger.startLogging(mVerboseLoggingLevel > 0); mIsRunning = true; updateBatteryWorkSource(null); @@ -6289,7 +6252,7 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiPno switch(message.what) { case CMD_START_SCAN: - handleScanRequest(message); + handleScanRequest(WifiNative.SCAN_WITHOUT_CONNECTION_SETUP, message); break; case CMD_SET_FREQUENCY_BAND: int band = message.arg1; @@ -6302,7 +6265,7 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiPno // Flush old data - like scan results mWifiNative.bssFlush(); // Fetch the latest scan results when frequency band is set - // startScanNative(null); +// startScanNative(WifiNative.SCAN_WITHOUT_CONNECTION_SETUP, null); if (PDBG) logd("done set frequency band " + band); @@ -6578,7 +6541,7 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiPno // Handle scan. All the connection related commands are // handled only in ConnectModeState case CMD_START_SCAN: - handleScanRequest(message); + handleScanRequest(WifiNative.SCAN_WITHOUT_CONNECTION_SETUP, message); break; case WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT: SupplicantState state = handleSupplicantStateChange(message); @@ -7076,6 +7039,11 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiPno class ConnectModeState extends State { @Override + public void enter() { + connectScanningService(); + } + + @Override public boolean processMessage(Message message) { WifiConfiguration config; int netId; @@ -8121,7 +8089,8 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiPno logd("starting scan for " + config.configKey() + " with " + freqs); //} // Call wifi native to start the scan - if (startScanNative(freqs)) { + if (startScanNative( + WifiNative.SCAN_WITHOUT_CONNECTION_SETUP, freqs)) { // Only count battery consumption if scan request is accepted noteScanStart(SCAN_ALARM_SOURCE, null); messageHandlingStatus = MESSAGE_HANDLING_STATUS_OK; @@ -8414,7 +8383,8 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiPno + fullBandConnectedTimeIntervalMilli); } } - handleScanRequest(message); + handleScanRequest( + WifiNative.SCAN_WITHOUT_CONNECTION_SETUP, message); } else { if (!startScanForConfiguration( currentConfiguration, restrictChannelList)) { @@ -8435,7 +8405,8 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiPno + fullBandConnectedTimeIntervalMilli); } } - handleScanRequest(message); + handleScanRequest( + WifiNative.SCAN_WITHOUT_CONNECTION_SETUP, message); } } @@ -9386,7 +9357,7 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiPno } /* Disable background scan temporarily during a regular scan */ enableBackgroundScan(false); - handleScanRequest(message); + handleScanRequest(WifiNative.SCAN_WITHOUT_CONNECTION_SETUP, message); ret = HANDLED; } else { diff --git a/tests/wifitests/src/com/android/server/wifi/BaseWifiScannerImplTest.java b/tests/wifitests/src/com/android/server/wifi/BaseWifiScannerImplTest.java index 9a21843f4..0ff439152 100644 --- a/tests/wifitests/src/com/android/server/wifi/BaseWifiScannerImplTest.java +++ b/tests/wifitests/src/com/android/server/wifi/BaseWifiScannerImplTest.java @@ -25,6 +25,7 @@ import static com.android.server.wifi.ScanTestUtil.setupMockChannels; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.any; +import static org.mockito.Mockito.anyInt; import static org.mockito.Mockito.eq; import static org.mockito.Mockito.inOrder; import static org.mockito.Mockito.mock; @@ -139,7 +140,7 @@ public abstract class BaseWifiScannerImplTest { WifiNative.ScanEventHandler eventHandler2 = mock(WifiNative.ScanEventHandler.class); // scan start succeeds - when(mWifiNative.scan(any(Set.class))).thenReturn(true); + when(mWifiNative.scan(anyInt(), any(Set.class))).thenReturn(true); assertTrue(mScanner.startSingleScan(settings, eventHandler)); assertFalse("second scan while first scan running should fail immediately", @@ -163,13 +164,12 @@ public abstract class BaseWifiScannerImplTest { InOrder order = inOrder(eventHandler, mWifiNative); // scan fails - when(mWifiNative.scan(any(Set.class))).thenReturn(false); + when(mWifiNative.scan(anyInt(), any(Set.class))).thenReturn(false); // start scan assertTrue(mScanner.startSingleScan(settings, eventHandler)); - mLooper.dispatchAll(); - order.verify(eventHandler).onScanStatus(WifiNative.WIFI_SCAN_DISABLED); + // TODO expect failure callback once implemented verifyNoMoreInteractions(eventHandler); } @@ -213,7 +213,7 @@ public abstract class BaseWifiScannerImplTest { InOrder order = inOrder(eventHandler, mWifiNative); // scans succeed - when(mWifiNative.scan(any(Set.class))).thenReturn(true); + when(mWifiNative.scan(anyInt(), any(Set.class))).thenReturn(true); // start first scan assertTrue(mScanner.startSingleScan(settings, eventHandler)); @@ -257,7 +257,7 @@ public abstract class BaseWifiScannerImplTest { InOrder order = inOrder(eventHandler, mWifiNative); // scan succeeds - when(mWifiNative.scan(any(Set.class))).thenReturn(true); + when(mWifiNative.scan(anyInt(), any(Set.class))).thenReturn(true); // start scan assertTrue(mScanner.startSingleScan(settings, eventHandler)); @@ -270,7 +270,8 @@ public abstract class BaseWifiScannerImplTest { protected void expectSuccessfulSingleScan(InOrder order, WifiNative.ScanEventHandler eventHandler, Set<Integer> expectedScan, ScanResults results, boolean expectFullResults) { - order.verify(mWifiNative).scan(eq(expectedScan)); + order.verify(mWifiNative).scan(eq(WifiNative.SCAN_WITHOUT_CONNECTION_SETUP), + eq(expectedScan)); when(mWifiNative.getScanResults()).thenReturn(results.getScanDetailArrayList()); @@ -285,7 +286,7 @@ public abstract class BaseWifiScannerImplTest { } } - order.verify(eventHandler).onScanStatus(WifiNative.WIFI_SCAN_RESULTS_AVAILABLE); + order.verify(eventHandler).onScanResultsAvailable(); assertScanDataEquals(results.getScanData(), mScanner.getLatestSingleScanResults()); } } diff --git a/tests/wifitests/src/com/android/server/wifi/HalWifiScannerTest.java b/tests/wifitests/src/com/android/server/wifi/HalWifiScannerTest.java index d253ff723..162fc2c0c 100644 --- a/tests/wifitests/src/com/android/server/wifi/HalWifiScannerTest.java +++ b/tests/wifitests/src/com/android/server/wifi/HalWifiScannerTest.java @@ -16,10 +16,13 @@ package com.android.server.wifi; +import android.os.Handler; import android.test.suitebuilder.annotation.SmallTest; import org.junit.Before; +import java.lang.reflect.Field; + /** * Unit tests for {@link com.android.server.wifi.HalWifiScannerImpl}. */ @@ -29,5 +32,14 @@ public class HalWifiScannerTest extends BaseWifiScannerImplTest { @Before public void setUp() throws Exception { mScanner = new HalWifiScannerImpl(WifiNative.getWlanNativeInterface(), mLooper.getLooper()); + + // TODO remove this once HalWifiScannerImpl wifi monitor registration is enabled + Field eventHandlerField = HalWifiScannerImpl.class.getDeclaredField("mEventHandler"); + eventHandlerField.setAccessible(true); + Handler eventHandler = (Handler) eventHandlerField.get(mScanner); + WifiMonitor.getInstance().registerHandler(mWifiNative.getInterfaceName(), + WifiMonitor.SCAN_FAILED_EVENT, eventHandler); + WifiMonitor.getInstance().registerHandler(mWifiNative.getInterfaceName(), + WifiMonitor.SCAN_RESULTS_EVENT, eventHandler); } } diff --git a/tests/wifitests/src/com/android/server/wifi/MultiClientSchedulerTest.java b/tests/wifitests/src/com/android/server/wifi/MultiClientSchedulerTest.java index 94ce31d38..97da4a473 100644 --- a/tests/wifitests/src/com/android/server/wifi/MultiClientSchedulerTest.java +++ b/tests/wifitests/src/com/android/server/wifi/MultiClientSchedulerTest.java @@ -16,8 +16,6 @@ package com.android.server.wifi; -import static com.android.server.wifi.ScanTestUtil.NativeScanSettingsBuilder; -import static com.android.server.wifi.ScanTestUtil.assertNativeScanSettingsEquals; import static com.android.server.wifi.ScanTestUtil.channelsToSpec; import static com.android.server.wifi.ScanTestUtil.createRequest; import static com.android.server.wifi.ScanTestUtil.getAllChannels; @@ -46,6 +44,7 @@ import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashSet; +import java.util.Set; /** * Unit tests for {@link com.android.server.wifi.MultiClientScheduler}. @@ -460,23 +459,43 @@ public class MultiClientSchedulerTest { mScheduler.updateSchedule(requests); WifiNative.ScanSettings schedule = mScheduler.getSchedule(); - int expectedPeriod = computeExpectedPeriod(settings.periodInMs); - NativeScanSettingsBuilder expectedBuilder = new NativeScanSettingsBuilder() - .withBasePeriod(expectedPeriod) - .withMaxApPerScan(settings.numBssidsPerScan == 0 - ? DEFAULT_MAX_AP_PER_SCAN - : settings.numBssidsPerScan) - .withMaxScansToCache(settings.maxScansToCache == 0 - ? DEFAULT_MAX_BATCH - : settings.maxScansToCache); + assertEquals("base_period_ms", computeExpectedPeriod(settings.periodInMs), + schedule.base_period_ms); + assertBuckets(schedule, 1); - if (settings.band == WifiScanner.WIFI_BAND_UNSPECIFIED) { - expectedBuilder.addBucketWithChannels(expectedPeriod, settings.reportEvents, - getAllChannels(settings)); + if (settings.numBssidsPerScan == 0) { + assertEquals("bssids per scan", DEFAULT_MAX_AP_PER_SCAN, schedule.max_ap_per_scan); } else { - expectedBuilder.addBucketWithBand(expectedPeriod, settings.reportEvents, settings.band); + assertEquals("bssids per scan", settings.numBssidsPerScan, schedule.max_ap_per_scan); + } + if (settings.maxScansToCache == 0) { + assertEquals("scans to cache", DEFAULT_MAX_BATCH, + schedule.report_threshold_num_scans); + } else { + assertEquals("scans to cache", settings.maxScansToCache, + schedule.report_threshold_num_scans); + } + assertEquals("reportEvents", settings.reportEvents, schedule.buckets[0].report_events); + assertEquals("period", computeExpectedPeriod(settings.periodInMs), + schedule.buckets[0].period_ms); + if (settings.band == WifiScanner.WIFI_BAND_UNSPECIFIED) { + assertEquals("band", settings.band, schedule.buckets[0].band); + Set<Integer> expectedChannels = new HashSet<>(); + for (ChannelSpec channel : getAllChannels(settings)) { + expectedChannels.add(channel.frequency); + } + Set<Integer> actualChannels = new HashSet<>(); + for (ChannelSpec channel : getAllChannels(schedule.buckets[0])) { + actualChannels.add(channel.frequency); + } + assertEquals("channels", expectedChannels, actualChannels); + } + else { + assertEquals("band", settings.band, schedule.buckets[0].band); + assertEquals("num_channels", 0, schedule.buckets[0].num_channels); + assertTrue("channels", schedule.buckets[0].channels == null + || schedule.buckets[0].channels.length == 0); } - assertNativeScanSettingsEquals(expectedBuilder.build(), schedule); } private void assertBuckets(WifiNative.ScanSettings schedule, int numBuckets) { diff --git a/tests/wifitests/src/com/android/server/wifi/ScanResults.java b/tests/wifitests/src/com/android/server/wifi/ScanResults.java index b6007b26c..d418451fc 100644 --- a/tests/wifitests/src/com/android/server/wifi/ScanResults.java +++ b/tests/wifitests/src/com/android/server/wifi/ScanResults.java @@ -28,9 +28,7 @@ import java.math.BigInteger; import java.nio.charset.Charset; import java.util.ArrayList; import java.util.Arrays; -import java.util.Collections; import java.util.Comparator; -import java.util.List; import java.util.Random; /** @@ -41,29 +39,6 @@ public class ScanResults { private final ScanData mScanData; private final ScanResult[] mScanResults; - private ScanResults(ArrayList<ScanDetail> scanDetails, ScanData scanData, - ScanResult[] scanResults) { - mScanDetails.addAll(scanDetails); - mScanData = scanData; - mScanResults = scanResults; - } - - public static ScanResults merge(ScanResults... others) { - ArrayList<ScanDetail> scanDetails = new ArrayList<>(); - ArrayList<ScanResult> scanDataResults = new ArrayList<>(); - ArrayList<ScanResult> rawScanResults = new ArrayList<>(); - for (ScanResults other : others) { - scanDetails.addAll(other.getScanDetailArrayList()); - scanDataResults.addAll(Arrays.asList(other.getScanData().getResults())); - rawScanResults.addAll(Arrays.asList(other.getRawScanResults())); - } - Collections.sort(scanDataResults, SCAN_RESULT_RSSI_COMPARATOR); - int id = others[0].getScanData().getId(); - return new ScanResults(scanDetails, new ScanData(id, 0, scanDataResults - .toArray(new ScanResult[scanDataResults.size()])), - rawScanResults.toArray(new ScanResult[rawScanResults.size()])); - } - private static String generateBssid(Random r) { return String.format("%02X:%02X:%02X:%02X:%02X:%02X", r.nextInt(256), r.nextInt(256), r.nextInt(256), @@ -127,14 +102,11 @@ public class ScanResults { int rssi = r.nextInt(40) - 99; // -99 to -60 ScanResult.InformationElement ie[] = new ScanResult.InformationElement[1]; ie[0] = generateSsidIe(ssid); - List<String> anqpLines = new ArrayList<>(); - NetworkDetail nd = new NetworkDetail(bssid, ie, anqpLines, freq); + NetworkDetail nd = new NetworkDetail(bssid, ie, new ArrayList<String>(), freq); ScanDetail detail = new ScanDetail(nd, WifiSsid.createFromAsciiEncoded(ssid), bssid, "", rssi, freq, Long.MAX_VALUE); /* needed so that scan results aren't rejected because there older than scan start */ - detail.getScanResult().informationElements = ie; - detail.getScanResult().anqpLines = anqpLines; results[i] = detail; } return results; diff --git a/tests/wifitests/src/com/android/server/wifi/ScanTestUtil.java b/tests/wifitests/src/com/android/server/wifi/ScanTestUtil.java index cc583e420..3b06c0386 100644 --- a/tests/wifitests/src/com/android/server/wifi/ScanTestUtil.java +++ b/tests/wifitests/src/com/android/server/wifi/ScanTestUtil.java @@ -18,7 +18,6 @@ package com.android.server.wifi; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.when; import android.net.wifi.ScanResult; @@ -28,6 +27,8 @@ import android.net.wifi.WifiScanner.ScanData; import android.net.wifi.WifiScanner.ScanSettings; import android.net.wifi.WifiSsid; +import com.android.server.wifi.WifiNative.BucketSettings; + import java.lang.reflect.Field; import java.util.Arrays; import java.util.HashSet; @@ -114,10 +115,6 @@ public class ScanTestUtil { mSettings.report_threshold_num_scans = maxScans; return this; } - public NativeScanSettingsBuilder withMaxPercentToCache(int percent) { - mSettings.report_threshold_percent = percent; - return this; - } public NativeScanSettingsBuilder addBucketWithBand( int period, int reportEvents, int band) { @@ -131,11 +128,6 @@ public class ScanTestUtil { public NativeScanSettingsBuilder addBucketWithChannels( int period, int reportEvents, int... channels) { - return addBucketWithChannels(period, reportEvents, channelsToSpec(channels)); - } - - public NativeScanSettingsBuilder addBucketWithChannels( - int period, int reportEvents, ChannelSpec... channels) { WifiNative.BucketSettings bucket = new WifiNative.BucketSettings(); bucket.bucket = mSettings.num_buckets; bucket.band = WifiScanner.WIFI_BAND_UNSPECIFIED; @@ -143,7 +135,7 @@ public class ScanTestUtil { bucket.channels = new WifiNative.ChannelSettings[channels.length]; for (int i = 0; i < channels.length; ++i) { bucket.channels[i] = new WifiNative.ChannelSettings(); - bucket.channels[i].frequency = channels[i].frequency; + bucket.channels[i].frequency = channels[i]; } bucket.period_ms = period; bucket.report_events = reportEvents; @@ -162,26 +154,6 @@ public class ScanTestUtil { } } - public static WifiNative.ScanSettings computeSingleScanNativeSettings( - WifiScanner.ScanSettings requestSettings) { - return createSingleScanNativeSettings(requestSettings.reportEvents, - getAllChannels(requestSettings)); - } - - public static WifiNative.ScanSettings createSingleScanNativeSettings( - int reportEvents, ChannelSpec... channels) { - // TODO requests using bands should be scheduled using the band, but are currently - // converted to channels before scheduling. This should probably change - return new NativeScanSettingsBuilder() - .withBasePeriod(0) - .withMaxApPerScan(0) - .withMaxPercentToCache(0) - .withMaxScansToCache(0) - .addBucketWithChannels(0, - reportEvents | WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN, channels) - .build(); - } - public static Set<Integer> createFreqSet(int... elements) { Set<Integer> set = new HashSet<>(); for (int e : elements) { @@ -265,46 +237,7 @@ public class ScanTestUtil { return channelSpecs; } - public static void assertNativeScanSettingsEquals(WifiNative.ScanSettings expected, - WifiNative.ScanSettings actual) { - assertEquals("bssids per scan", expected.max_ap_per_scan, actual.max_ap_per_scan); - assertEquals("scans to cache", expected.report_threshold_num_scans, - actual.report_threshold_num_scans); - assertEquals("percent to cache", expected.report_threshold_percent, - actual.report_threshold_percent); - assertEquals("base period", expected.base_period_ms, actual.base_period_ms); - - assertEquals("number of buckets", expected.num_buckets, actual.num_buckets); - assertNotNull("buckets was null", actual.buckets); - for (int i = 0; i < expected.buckets.length; ++i) { - assertNotNull("buckets[" + i + "] was null", actual.buckets[i]); - assertEquals("buckets[" + i + "].period", - expected.buckets[i].period_ms, actual.buckets[i].period_ms); - assertEquals("buckets[" + i + "].reportEvents", - expected.buckets[i].report_events, actual.buckets[i].report_events); - - assertEquals("buckets[" + i + "].band", - expected.buckets[i].band, actual.buckets[i].band); - if (expected.buckets[i].band == WifiScanner.WIFI_BAND_UNSPECIFIED) { - Set<Integer> expectedChannels = new HashSet<>(); - for (ChannelSpec channel : getAllChannels(expected.buckets[i])) { - expectedChannels.add(channel.frequency); - } - Set<Integer> actualChannels = new HashSet<>(); - for (ChannelSpec channel : getAllChannels(actual.buckets[i])) { - actualChannels.add(channel.frequency); - } - assertEquals("channels", expectedChannels, actualChannels); - } else { - assertEquals("buckets[" + i + "].num_channels", 0, actual.buckets[i].num_channels); - assertTrue("buckets[" + i + "].channels", - actual.buckets[i].channels == null - || actual.buckets[i].channels.length == 0); - } - } - } - - public static ChannelSpec[] getAllChannels(WifiNative.BucketSettings bucket) { + public static ChannelSpec[] getAllChannels(BucketSettings bucket) { if (bucket.band == WifiScanner.WIFI_BAND_UNSPECIFIED) { ChannelSpec[] channels = new ChannelSpec[bucket.num_channels]; for (int i = 0; i < bucket.num_channels; i++) { diff --git a/tests/wifitests/src/com/android/server/wifi/SupplicantWifiScannerTest.java b/tests/wifitests/src/com/android/server/wifi/SupplicantWifiScannerTest.java index 94b9dc330..b08e52dc8 100644 --- a/tests/wifitests/src/com/android/server/wifi/SupplicantWifiScannerTest.java +++ b/tests/wifitests/src/com/android/server/wifi/SupplicantWifiScannerTest.java @@ -22,6 +22,7 @@ import static com.android.server.wifi.ScanTestUtil.createFreqSet; import static org.junit.Assert.assertEquals; import static org.mockito.Mockito.any; +import static org.mockito.Mockito.anyInt; import static org.mockito.Mockito.eq; import static org.mockito.Mockito.inOrder; import static org.mockito.Mockito.mock; @@ -31,12 +32,14 @@ import static org.mockito.Mockito.when; import android.net.wifi.ScanResult; import android.net.wifi.WifiScanner; import android.net.wifi.WifiSsid; +import android.os.Handler; import android.test.suitebuilder.annotation.SmallTest; import org.junit.Before; import org.junit.Test; import org.mockito.InOrder; +import java.lang.reflect.Field; import java.util.ArrayList; import java.util.Set; @@ -50,6 +53,15 @@ public class SupplicantWifiScannerTest extends BaseWifiScannerImplTest { public void setup() throws Exception { mScanner = new SupplicantWifiScannerImpl(mContext, WifiNative.getWlanNativeInterface(), mLooper.getLooper()); + + // TODO remove this once SupplicantWifiScannerImpl wifi monitor registration is enabled + Field eventHandlerField = SupplicantWifiScannerImpl.class.getDeclaredField("mEventHandler"); + eventHandlerField.setAccessible(true); + Handler eventHandler = (Handler) eventHandlerField.get(mScanner); + WifiMonitor.getInstance().registerHandler(mWifiNative.getInterfaceName(), + WifiMonitor.SCAN_FAILED_EVENT, eventHandler); + WifiMonitor.getInstance().registerHandler(mWifiNative.getInterfaceName(), + WifiMonitor.SCAN_RESULTS_EVENT, eventHandler); } @Test @@ -320,7 +332,7 @@ public class SupplicantWifiScannerTest extends BaseWifiScannerImplTest { InOrder order = inOrder(eventHandler, mWifiNative); // All scans fail - when(mWifiNative.scan(any(Set.class))).thenReturn(false); + when(mWifiNative.scan(anyInt(), any(Set.class))).thenReturn(false); // Start scan mScanner.startBatchedScan(settings, eventHandler); @@ -355,7 +367,7 @@ public class SupplicantWifiScannerTest extends BaseWifiScannerImplTest { InOrder order = inOrder(eventHandler, mWifiNative); // All scan starts succeed - when(mWifiNative.scan(any(Set.class))).thenReturn(true); + when(mWifiNative.scan(anyInt(), any(Set.class))).thenReturn(true); // Start scan mScanner.startBatchedScan(settings, eventHandler); @@ -400,7 +412,7 @@ public class SupplicantWifiScannerTest extends BaseWifiScannerImplTest { InOrder order = inOrder(eventHandler, mWifiNative); // All scan starts succeed - when(mWifiNative.scan(any(Set.class))).thenReturn(true); + when(mWifiNative.scan(anyInt(), any(Set.class))).thenReturn(true); // Start scan mScanner.startBatchedScan(settings, eventHandler); @@ -455,7 +467,7 @@ public class SupplicantWifiScannerTest extends BaseWifiScannerImplTest { InOrder order = inOrder(eventHandler, mWifiNative); // All scan starts succeed - when(mWifiNative.scan(any(Set.class))).thenReturn(true); + when(mWifiNative.scan(anyInt(), any(Set.class))).thenReturn(true); // Start scan mScanner.startBatchedScan(settings, eventHandler); @@ -465,7 +477,8 @@ public class SupplicantWifiScannerTest extends BaseWifiScannerImplTest { // alarm for next period assertEquals(1, mAlarmManager.getPendingCount()); - order.verify(mWifiNative).scan(eq(expectedPeriods[0].getScanFreqs())); + order.verify(mWifiNative).scan(eq(WifiNative.SCAN_WITHOUT_CONNECTION_SETUP), + eq(expectedPeriods[0].getScanFreqs())); mScanner.pauseBatchedScan(); @@ -531,7 +544,7 @@ public class SupplicantWifiScannerTest extends BaseWifiScannerImplTest { InOrder order = inOrder(eventHandler, mWifiNative); // All scan starts succeed - when(mWifiNative.scan(any(Set.class))).thenReturn(true); + when(mWifiNative.scan(anyInt(), any(Set.class))).thenReturn(true); // Start scan mScanner.startBatchedScan(settings, eventHandler); @@ -570,7 +583,7 @@ public class SupplicantWifiScannerTest extends BaseWifiScannerImplTest { InOrder order = inOrder(eventHandler, mWifiNative); // All scans succeed - when(mWifiNative.scan(any(Set.class))).thenReturn(true); + when(mWifiNative.scan(anyInt(), any(Set.class))).thenReturn(true); // Start scan mScanner.startBatchedScan(settings, eventHandler); @@ -630,7 +643,7 @@ public class SupplicantWifiScannerTest extends BaseWifiScannerImplTest { ArrayList<ScanDetail> nativeResults, WifiScanner.ScanData[] expectedScanResults, ScanResult[] fullResults, int periodId) { // Verify scan started - order.verify(mWifiNative).scan(eq(scanFreqs)); + order.verify(mWifiNative).scan(eq(WifiNative.SCAN_WITHOUT_CONNECTION_SETUP), eq(scanFreqs)); // Setup scan results when(mWifiNative.getScanResults()).thenReturn(nativeResults); @@ -647,7 +660,7 @@ public class SupplicantWifiScannerTest extends BaseWifiScannerImplTest { if (expectedScanResults != null) { // Verify scan results delivered - order.verify(eventHandler).onScanStatus(WifiNative.WIFI_SCAN_RESULTS_AVAILABLE); + order.verify(eventHandler).onScanStatus(); assertScanDatasEquals("period[" + periodId + "].", expectedScanResults, mScanner.getLatestBatchedScanResults(true)); } @@ -656,26 +669,22 @@ public class SupplicantWifiScannerTest extends BaseWifiScannerImplTest { private void expectFailedScanStart(InOrder order, WifiNative.ScanEventHandler eventHandler, Set<Integer> scanFreqs) { // Verify scan started - order.verify(mWifiNative).scan(eq(scanFreqs)); - - // TODO verify failure event + order.verify(mWifiNative).scan(eq(WifiNative.SCAN_WITHOUT_CONNECTION_SETUP), eq(scanFreqs)); } private void expectFailedEventScan(InOrder order, WifiNative.ScanEventHandler eventHandler, Set<Integer> scanFreqs) { // Verify scan started - order.verify(mWifiNative).scan(eq(scanFreqs)); + order.verify(mWifiNative).scan(eq(WifiNative.SCAN_WITHOUT_CONNECTION_SETUP), eq(scanFreqs)); // Notify scan has failed mWifiMonitor.sendMessage(mWifiNative.getInterfaceName(), WifiMonitor.SCAN_FAILED_EVENT); assertEquals("dispatch message after results event", 1, mLooper.dispatchAll()); - - // TODO verify failure event } private void dispatchOnlyAlarm() { assertEquals("dispatch only one alarm", 1, mAlarmManager.dispatchAll()); - mLooper.dispatchAll(); + assertEquals("dispatch only one message", 1, mLooper.dispatchAll()); } private static class ScanPeriod { diff --git a/tests/wifitests/src/com/android/server/wifi/WifiScanningServiceTest.java b/tests/wifitests/src/com/android/server/wifi/WifiScanningServiceTest.java index 42d89525a..4093936b6 100644 --- a/tests/wifitests/src/com/android/server/wifi/WifiScanningServiceTest.java +++ b/tests/wifitests/src/com/android/server/wifi/WifiScanningServiceTest.java @@ -16,21 +16,12 @@ package com.android.server.wifi; -import static com.android.server.wifi.ScanTestUtil.NativeScanSettingsBuilder; -import static com.android.server.wifi.ScanTestUtil.assertNativeScanSettingsEquals; -import static com.android.server.wifi.ScanTestUtil.assertScanDatasEquals; -import static com.android.server.wifi.ScanTestUtil.channelsToSpec; -import static com.android.server.wifi.ScanTestUtil.computeSingleScanNativeSettings; import static com.android.server.wifi.ScanTestUtil.createRequest; -import static com.android.server.wifi.ScanTestUtil.createSingleScanNativeSettings; import static com.android.server.wifi.ScanTestUtil.installWlanWifiNative; import static com.android.server.wifi.ScanTestUtil.setupMockChannels; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; import static org.mockito.Mockito.any; -import static org.mockito.Mockito.inOrder; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; import static org.mockito.Mockito.validateMockitoUsage; @@ -57,7 +48,6 @@ import org.junit.After; import org.junit.Before; import org.junit.Test; import org.mockito.ArgumentCaptor; -import org.mockito.InOrder; import org.mockito.Mock; import org.mockito.MockitoAnnotations; @@ -99,16 +89,13 @@ public class WifiScanningServiceTest { } - /** - * Internal BroadcastReceiver that WifiScanningServiceImpl uses to listen for broadcasts - * this is initialized by calling startServiceAndLoadDriver - */ - BroadcastReceiver mBroadcastReceiver; + ArgumentCaptor<BroadcastReceiver> mBroadcastReceiverCaptor = + ArgumentCaptor.forClass(BroadcastReceiver.class); private void sendWifiScanAvailable(int scanAvailable) { Intent intent = new Intent(WifiManager.WIFI_SCAN_AVAILABLE); intent.putExtra(WifiManager.EXTRA_SCAN_AVAILABLE, scanAvailable); - mBroadcastReceiver.onReceive(mContext, intent); + mBroadcastReceiverCaptor.getValue().onReceive(mContext, intent); } private WifiScanner.ScanSettings generateValidScanSettings() { @@ -125,96 +112,45 @@ public class WifiScanningServiceTest { return controlChannel; } - private Message verifyHandleMessageAndGetMessage(InOrder order, Handler handler) { + private Message sendRequest(BidirectionalAsyncChannel controlChannel, Handler handler, + Message msg) { + controlChannel.sendMessage(msg); + mLooper.dispatchAll(); ArgumentCaptor<Message> messageCaptor = ArgumentCaptor.forClass(Message.class); - order.verify(handler).handleMessage(messageCaptor.capture()); + verify(handler).handleMessage(messageCaptor.capture()); return messageCaptor.getValue(); } - private void verifyScanResultsRecieved(InOrder order, Handler handler, int listenerId, - WifiScanner.ScanData... expected) { - Message scanResultMessage = verifyHandleMessageAndGetMessage(order, handler); - assertScanResultsMessage(listenerId, expected, scanResultMessage); - } - - private void assertScanResultsMessage(int listenerId, WifiScanner.ScanData[] expected, - Message scanResultMessage) { - assertEquals("what", WifiScanner.CMD_SCAN_RESULT, scanResultMessage.what); - assertEquals("listenerId", listenerId, scanResultMessage.arg2); - assertScanDatasEquals(expected, - ((WifiScanner.ParcelableScanData) scanResultMessage.obj).getResults()); - } - - private void sendBackgroundScanRequest(BidirectionalAsyncChannel controlChannel, - int scanRequestId, WifiScanner.ScanSettings settings) { - controlChannel.sendMessage(Message.obtain(null, WifiScanner.CMD_START_BACKGROUND_SCAN, 0, - scanRequestId, settings)); - } - - private void sendSingleScanRequest(BidirectionalAsyncChannel controlChannel, - int scanRequestId, WifiScanner.ScanSettings settings) { - controlChannel.sendMessage(Message.obtain(null, WifiScanner.CMD_START_SINGLE_SCAN, 0, - scanRequestId, settings)); - } - - private void verifySuccessfulResponse(InOrder order, Handler handler, int arg2) { - Message response = verifyHandleMessageAndGetMessage(order, handler); - assertSuccessfulResponse(arg2, response); - } - - private void assertSuccessfulResponse(int arg2, Message response) { - if (response.what == WifiScanner.CMD_OP_FAILED) { - WifiScanner.OperationResult result = (WifiScanner.OperationResult) response.obj; - fail("response indicates failure, reason=" + result.reason - + ", description=" + result.description); - } else { - assertEquals("response.what", WifiScanner.CMD_OP_SUCCEEDED, response.what); - assertEquals("response.arg2", arg2, response.arg2); - } + private void sendAndAssertSuccessfulyBackgroundScan(BidirectionalAsyncChannel controlChannel, + Handler handler, int scanRequestId, WifiScanner.ScanSettings settings) { + Message response = sendRequest(controlChannel, handler, + Message.obtain(null, WifiScanner.CMD_START_BACKGROUND_SCAN, 0, scanRequestId, + settings)); + assertEquals("response.what", WifiScanner.CMD_OP_SUCCEEDED, response.what); + assertEquals("response.arg2", scanRequestId, response.arg2); + assertEquals("response.obj", null, response.obj); } - private void verifyFailedResponse(InOrder order, Handler handler, int arg2, + private void sendAndAssertFailedBackgroundScan(BidirectionalAsyncChannel controlChannel, + Handler handler, int scanRequestId, WifiScanner.ScanSettings settings, int expectedErrorReason, String expectedErrorDescription) { - Message response = verifyHandleMessageAndGetMessage(order, handler); - assertFailedResponse(arg2, expectedErrorReason, expectedErrorDescription, response); + Message response = sendRequest(controlChannel, handler, + Message.obtain(null, WifiScanner.CMD_START_BACKGROUND_SCAN, 0, scanRequestId, + settings)); + assertFailedResponse(scanRequestId, expectedErrorReason, expectedErrorDescription, + response); } private void assertFailedResponse(int arg2, int expectedErrorReason, String expectedErrorDescription, Message response) { - if (response.what == WifiScanner.CMD_OP_SUCCEEDED) { - fail("response indicates success"); - } else { - assertEquals("response.what", WifiScanner.CMD_OP_FAILED, response.what); - assertEquals("response.arg2", arg2, response.arg2); - WifiScanner.OperationResult result = (WifiScanner.OperationResult) response.obj; - assertEquals("response.obj.reason", - expectedErrorReason, result.reason); - assertEquals("response.obj.description", - expectedErrorDescription, result.description); - } + assertEquals("response.what", WifiScanner.CMD_OP_FAILED, response.what); + assertEquals("response.arg2", arg2, response.arg2); + assertEquals("response.obj.reason", + expectedErrorReason, ((WifiScanner.OperationResult) response.obj).reason); + assertEquals("response.obj.description", + expectedErrorDescription, ((WifiScanner.OperationResult) response.obj).description); } - private WifiNative.ScanEventHandler verifyStartSingleScan(InOrder order, - WifiNative.ScanSettings expected) { - ArgumentCaptor<WifiNative.ScanSettings> scanSettingsCaptor = - ArgumentCaptor.forClass(WifiNative.ScanSettings.class); - ArgumentCaptor<WifiNative.ScanEventHandler> scanEventHandlerCaptor = - ArgumentCaptor.forClass(WifiNative.ScanEventHandler.class); - order.verify(mWifiScannerImpl).startSingleScan(scanSettingsCaptor.capture(), - scanEventHandlerCaptor.capture()); - assertNativeScanSettingsEquals(expected, scanSettingsCaptor.getValue()); - return scanEventHandlerCaptor.getValue(); - } - - private void verifyStartBackgroundScan(InOrder order, WifiNative.ScanSettings expected) { - ArgumentCaptor<WifiNative.ScanSettings> scanSettingsCaptor = - ArgumentCaptor.forClass(WifiNative.ScanSettings.class); - order.verify(mWifiScannerImpl).startBatchedScan(scanSettingsCaptor.capture(), - any(WifiNative.ScanEventHandler.class)); - assertNativeScanSettingsEquals(expected, scanSettingsCaptor.getValue()); - } - - private static final int MAX_AP_PER_SCAN = 16; private void startServiceAndLoadDriver() { mWifiScanningServiceImpl.startService(); when(mWifiScannerImpl.getScanCapabilities(any(WifiNative.ScanCapabilities.class))) @@ -222,7 +158,7 @@ public class WifiScanningServiceTest { public boolean answer(WifiNative.ScanCapabilities capabilities) { capabilities.max_scan_cache_size = Integer.MAX_VALUE; capabilities.max_scan_buckets = 8; - capabilities.max_ap_cache_per_scan = MAX_AP_PER_SCAN; + capabilities.max_ap_cache_per_scan = 16; capabilities.max_rssi_sample_size = 8; capabilities.max_scan_reporting_threshold = 10; capabilities.max_hotlist_bssids = 0; @@ -230,12 +166,8 @@ public class WifiScanningServiceTest { return true; } }); - ArgumentCaptor<BroadcastReceiver> broadcastReceiverCaptor = - ArgumentCaptor.forClass(BroadcastReceiver.class); verify(mContext) - .registerReceiver(broadcastReceiverCaptor.capture(), any(IntentFilter.class)); - mBroadcastReceiver = broadcastReceiverCaptor.getValue(); - + .registerReceiver(mBroadcastReceiverCaptor.capture(), any(IntentFilter.class)); sendWifiScanAvailable(WifiManager.WIFI_STATE_ENABLED); mLooper.dispatchAll(); } @@ -253,10 +185,8 @@ public class WifiScanningServiceTest { Handler handler = mock(Handler.class); BidirectionalAsyncChannel controlChannel = connectChannel(handler); - InOrder order = inOrder(handler); - sendBackgroundScanRequest(controlChannel, 122, generateValidScanSettings()); - mLooper.dispatchAll(); - verifyFailedResponse(order, handler, 122, WifiScanner.REASON_UNSPECIFIED, "not available"); + sendAndAssertFailedBackgroundScan(controlChannel, handler, 122, generateValidScanSettings(), + WifiScanner.REASON_UNSPECIFIED, "not available"); } @Test @@ -266,12 +196,10 @@ public class WifiScanningServiceTest { Handler handler = mock(Handler.class); BidirectionalAsyncChannel controlChannel = connectChannel(handler); - InOrder order = inOrder(handler); when(mWifiScannerImpl.startBatchedScan(any(WifiNative.ScanSettings.class), any(WifiNative.ScanEventHandler.class))).thenReturn(true); - sendBackgroundScanRequest(controlChannel, 192, generateValidScanSettings()); - mLooper.dispatchAll(); - verifySuccessfulResponse(order, handler, 192); + sendAndAssertSuccessfulyBackgroundScan(controlChannel, handler, 192, + generateValidScanSettings()); } @Test @@ -280,368 +208,9 @@ public class WifiScanningServiceTest { Handler handler = mock(Handler.class); BidirectionalAsyncChannel controlChannel = connectChannel(handler); - InOrder order = inOrder(handler, mWifiScannerImpl); - controlChannel.sendMessage(Message.obtain(null, Protocol.BASE_WIFI_MANAGER)); - mLooper.dispatchAll(); - verifyFailedResponse(order, handler, 0, WifiScanner.REASON_INVALID_REQUEST, - "Invalid request"); - } - - private void doSuccessfulSingleScan(WifiScanner.ScanSettings requestSettings, - WifiNative.ScanSettings nativeSettings, ScanResults results) { - int requestId = 12; - startServiceAndLoadDriver(); - - Handler handler = mock(Handler.class); - BidirectionalAsyncChannel controlChannel = connectChannel(handler); - InOrder order = inOrder(handler, mWifiScannerImpl); - - when(mWifiScannerImpl.startSingleScan(any(WifiNative.ScanSettings.class), - any(WifiNative.ScanEventHandler.class))).thenReturn(true); - - sendSingleScanRequest(controlChannel, requestId, requestSettings); - - mLooper.dispatchAll(); - WifiNative.ScanEventHandler eventHandler = verifyStartSingleScan(order, nativeSettings); - verifySuccessfulResponse(order, handler, requestId); - - when(mWifiScannerImpl.getLatestSingleScanResults()) - .thenReturn(results.getScanData()); - eventHandler.onScanStatus(WifiNative.WIFI_SCAN_RESULTS_AVAILABLE); - - mLooper.dispatchAll(); - verifyScanResultsRecieved(order, handler, 12, results.getScanData()); - verifyNoMoreInteractions(handler); - } - - @Test - public void sendSingleScanBandRequest() throws Exception { - WifiScanner.ScanSettings requestSettings = createRequest(WifiScanner.WIFI_BAND_BOTH, 0, - 0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN); - doSuccessfulSingleScan(requestSettings, computeSingleScanNativeSettings(requestSettings), - ScanResults.create(0, 2400, 5150, 5175)); - } - - @Test - public void sendSingleScanChannelsRequest() throws Exception { - WifiScanner.ScanSettings requestSettings = createRequest(channelsToSpec(2400), 0, - 0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN); - doSuccessfulSingleScan(requestSettings, computeSingleScanNativeSettings(requestSettings), - ScanResults.create(0, 2400, 2400, 2400)); + Message response = sendRequest(controlChannel, handler, + Message.obtain(null, Protocol.BASE_WIFI_MANAGER)); + assertFailedResponse(0, WifiScanner.REASON_INVALID_REQUEST, "Invalid request", response); } - @Test - public void sendSingleScanRequestWhichFailsToStart() throws Exception { - WifiScanner.ScanSettings requestSettings = createRequest(WifiScanner.WIFI_BAND_BOTH, 0, - 0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN); - int requestId = 33; - - startServiceAndLoadDriver(); - - Handler handler = mock(Handler.class); - BidirectionalAsyncChannel controlChannel = connectChannel(handler); - InOrder order = inOrder(handler, mWifiScannerImpl); - - // scan fails - when(mWifiScannerImpl.startSingleScan(any(WifiNative.ScanSettings.class), - any(WifiNative.ScanEventHandler.class))).thenReturn(false); - - sendSingleScanRequest(controlChannel, requestId, requestSettings); - - mLooper.dispatchAll(); - // Scan is successfully queue, but then fails to execute - ArgumentCaptor<Message> messageCaptor = ArgumentCaptor.forClass(Message.class); - order.verify(handler, times(2)).handleMessage(messageCaptor.capture()); - assertSuccessfulResponse(requestId, messageCaptor.getAllValues().get(0)); - assertFailedResponse(requestId, WifiScanner.REASON_UNSPECIFIED, - "Failed to start single scan", messageCaptor.getAllValues().get(1)); - } - - @Test - public void sendSingleScanRequestWhichFailsAfterStart() throws Exception { - WifiScanner.ScanSettings requestSettings = createRequest(WifiScanner.WIFI_BAND_BOTH, 0, - 0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN); - int requestId = 33; - - startServiceAndLoadDriver(); - - Handler handler = mock(Handler.class); - BidirectionalAsyncChannel controlChannel = connectChannel(handler); - InOrder order = inOrder(handler, mWifiScannerImpl); - - // successful start - when(mWifiScannerImpl.startSingleScan(any(WifiNative.ScanSettings.class), - any(WifiNative.ScanEventHandler.class))).thenReturn(true); - - sendSingleScanRequest(controlChannel, requestId, requestSettings); - - // Scan is successfully queue - mLooper.dispatchAll(); - WifiNative.ScanEventHandler eventHandler = - verifyStartSingleScan(order, computeSingleScanNativeSettings(requestSettings)); - verifySuccessfulResponse(order, handler, requestId); - - // but then fails to execute - eventHandler.onScanStatus(WifiNative.WIFI_SCAN_DISABLED); - mLooper.dispatchAll(); - verifyFailedResponse(order, handler, requestId, - WifiScanner.REASON_UNSPECIFIED, "Scan was interrupted"); - } - - // TODO Add more single scan tests - // * disable wifi while scanning - // * disable wifi while scanning with pending scan - - @Test - public void sendSingleScanRequestAfterPreviousCompletes() { - WifiScanner.ScanSettings requestSettings1 = createRequest(channelsToSpec(2400), 0, - 0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN); - int requestId1 = 12; - ScanResults results1 = ScanResults.create(0, 2400); - - - WifiScanner.ScanSettings requestSettings2 = createRequest(channelsToSpec(2450, 5175), 0, - 0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN); - int requestId2 = 13; - ScanResults results2 = ScanResults.create(0, 2450); - - - startServiceAndLoadDriver(); - - when(mWifiScannerImpl.startSingleScan(any(WifiNative.ScanSettings.class), - any(WifiNative.ScanEventHandler.class))).thenReturn(true); - - Handler handler = mock(Handler.class); - BidirectionalAsyncChannel controlChannel = connectChannel(handler); - InOrder order = inOrder(handler, mWifiScannerImpl); - - // Run scan 1 - sendSingleScanRequest(controlChannel, requestId1, requestSettings1); - - mLooper.dispatchAll(); - WifiNative.ScanEventHandler eventHandler1 = verifyStartSingleScan(order, - computeSingleScanNativeSettings(requestSettings1)); - verifySuccessfulResponse(order, handler, requestId1); - - // dispatch scan 1 results - when(mWifiScannerImpl.getLatestSingleScanResults()) - .thenReturn(results1.getScanData()); - eventHandler1.onScanStatus(WifiNative.WIFI_SCAN_RESULTS_AVAILABLE); - - mLooper.dispatchAll(); - verifyScanResultsRecieved(order, handler, requestId1, results1.getScanData()); - - // Run scan 2 - sendSingleScanRequest(controlChannel, requestId2, requestSettings2); - - mLooper.dispatchAll(); - WifiNative.ScanEventHandler eventHandler2 = verifyStartSingleScan(order, - computeSingleScanNativeSettings(requestSettings2)); - verifySuccessfulResponse(order, handler, requestId2); - - // dispatch scan 2 results - when(mWifiScannerImpl.getLatestSingleScanResults()) - .thenReturn(results2.getScanData()); - eventHandler2.onScanStatus(WifiNative.WIFI_SCAN_RESULTS_AVAILABLE); - - mLooper.dispatchAll(); - verifyScanResultsRecieved(order, handler, requestId2, results2.getScanData()); - } - - @Test - public void sendSingleScanRequestWhilePreviousScanRunning() { - WifiScanner.ScanSettings requestSettings1 = createRequest(channelsToSpec(2400), 0, - 0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN); - int requestId1 = 12; - ScanResults results1 = ScanResults.create(0, 2400); - - WifiScanner.ScanSettings requestSettings2 = createRequest(channelsToSpec(2450, 5175), 0, - 0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN); - int requestId2 = 13; - ScanResults results2 = ScanResults.create(0, 2450); - - - startServiceAndLoadDriver(); - - when(mWifiScannerImpl.startSingleScan(any(WifiNative.ScanSettings.class), - any(WifiNative.ScanEventHandler.class))).thenReturn(true); - - Handler handler = mock(Handler.class); - BidirectionalAsyncChannel controlChannel = connectChannel(handler); - InOrder handlerOrder = inOrder(handler); - InOrder nativeOrder = inOrder(mWifiScannerImpl); - - // Run scan 1 - sendSingleScanRequest(controlChannel, requestId1, requestSettings1); - - mLooper.dispatchAll(); - WifiNative.ScanEventHandler eventHandler1 = verifyStartSingleScan(nativeOrder, - computeSingleScanNativeSettings(requestSettings1)); - verifySuccessfulResponse(handlerOrder, handler, requestId1); - - // Queue scan 2 (will not run because previous is in progress) - sendSingleScanRequest(controlChannel, requestId2, requestSettings2); - mLooper.dispatchAll(); - verifySuccessfulResponse(handlerOrder, handler, requestId2); - - // dispatch scan 1 results - when(mWifiScannerImpl.getLatestSingleScanResults()) - .thenReturn(results1.getScanData()); - eventHandler1.onScanStatus(WifiNative.WIFI_SCAN_RESULTS_AVAILABLE); - - mLooper.dispatchAll(); - verifyScanResultsRecieved(handlerOrder, handler, requestId1, results1.getScanData()); - - // now that the first scan completed we expect the second one to start - WifiNative.ScanEventHandler eventHandler2 = verifyStartSingleScan(nativeOrder, - computeSingleScanNativeSettings(requestSettings2)); - - // dispatch scan 2 results - when(mWifiScannerImpl.getLatestSingleScanResults()) - .thenReturn(results2.getScanData()); - eventHandler2.onScanStatus(WifiNative.WIFI_SCAN_RESULTS_AVAILABLE); - - mLooper.dispatchAll(); - verifyScanResultsRecieved(handlerOrder, handler, requestId2, results2.getScanData()); - } - - - - @Test - public void sendMultipleSingleScanRequestWhilePreviousScanRunning() { - WifiScanner.ScanSettings requestSettings1 = createRequest(channelsToSpec(2400), 0, - 0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN); - int requestId1 = 12; - ScanResults results1 = ScanResults.create(0, 2400); - - WifiScanner.ScanSettings requestSettings2 = createRequest(channelsToSpec(2450, 5175), 0, - 0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN); - int requestId2 = 13; - ScanResults results2 = ScanResults.create(0, 2450, 5175, 2450); - - WifiScanner.ScanSettings requestSettings3 = createRequest(channelsToSpec(5150), 0, - 0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN); - int requestId3 = 15; - ScanResults results3 = ScanResults.create(0, 5150, 5150, 5150, 5150); - - WifiNative.ScanSettings nativeSettings2and3 = createSingleScanNativeSettings( - WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN, channelsToSpec(2450, 5175, 5150)); - ScanResults results2and3 = ScanResults.merge(results2, results3); - - - startServiceAndLoadDriver(); - - when(mWifiScannerImpl.startSingleScan(any(WifiNative.ScanSettings.class), - any(WifiNative.ScanEventHandler.class))).thenReturn(true); - - Handler handler = mock(Handler.class); - BidirectionalAsyncChannel controlChannel = connectChannel(handler); - InOrder handlerOrder = inOrder(handler); - InOrder nativeOrder = inOrder(mWifiScannerImpl); - - // Run scan 1 - sendSingleScanRequest(controlChannel, requestId1, requestSettings1); - - mLooper.dispatchAll(); - WifiNative.ScanEventHandler eventHandler1 = verifyStartSingleScan(nativeOrder, - computeSingleScanNativeSettings(requestSettings1)); - verifySuccessfulResponse(handlerOrder, handler, requestId1); - - // Queue scan 2 (will not run because previous is in progress) - sendSingleScanRequest(controlChannel, requestId2, requestSettings2); - mLooper.dispatchAll(); - verifySuccessfulResponse(handlerOrder, handler, requestId2); - - // Queue scan 3 (will not run because previous is in progress) - sendSingleScanRequest(controlChannel, requestId3, requestSettings3); - mLooper.dispatchAll(); - verifySuccessfulResponse(handlerOrder, handler, requestId3); - - // dispatch scan 1 results - when(mWifiScannerImpl.getLatestSingleScanResults()) - .thenReturn(results1.getScanData()); - eventHandler1.onScanStatus(WifiNative.WIFI_SCAN_RESULTS_AVAILABLE); - - mLooper.dispatchAll(); - verifyScanResultsRecieved(handlerOrder, handler, requestId1, results1.getScanData()); - - // now that the first scan completed we expect the second and third ones to start - WifiNative.ScanEventHandler eventHandler2and3 = verifyStartSingleScan(nativeOrder, - nativeSettings2and3); - - // dispatch scan 2 and 3 results - when(mWifiScannerImpl.getLatestSingleScanResults()) - .thenReturn(results2and3.getScanData()); - eventHandler2and3.onScanStatus(WifiNative.WIFI_SCAN_RESULTS_AVAILABLE); - - mLooper.dispatchAll(); - - // unfortunatally the order that these events are dispatched is dependant on the order which - // they are iterated through internally - ArgumentCaptor<Message> messageCaptor = ArgumentCaptor.forClass(Message.class); - handlerOrder.verify(handler, times(2)).handleMessage(messageCaptor.capture()); - int firstListenerId = messageCaptor.getAllValues().get(0).arg2; - assertTrue(firstListenerId + " was neither " + requestId2 + " nor " + requestId3, - firstListenerId == requestId2 || firstListenerId == requestId3); - if (firstListenerId == requestId2) { - assertScanResultsMessage(requestId2, - new WifiScanner.ScanData[] {results2.getScanData()}, - messageCaptor.getAllValues().get(0)); - assertScanResultsMessage(requestId3, - new WifiScanner.ScanData[] {results3.getScanData()}, - messageCaptor.getAllValues().get(1)); - } else { - assertScanResultsMessage(requestId3, - new WifiScanner.ScanData[] {results3.getScanData()}, - messageCaptor.getAllValues().get(0)); - assertScanResultsMessage(requestId2, - new WifiScanner.ScanData[] {results2.getScanData()}, - messageCaptor.getAllValues().get(1)); - } - } - - private void doSuccessfulBackgroundScan(WifiScanner.ScanSettings requestSettings, - WifiNative.ScanSettings nativeSettings) { - startServiceAndLoadDriver(); - - Handler handler = mock(Handler.class); - BidirectionalAsyncChannel controlChannel = connectChannel(handler); - InOrder order = inOrder(handler, mWifiScannerImpl); - - when(mWifiScannerImpl.startBatchedScan(any(WifiNative.ScanSettings.class), - any(WifiNative.ScanEventHandler.class))).thenReturn(true); - - sendBackgroundScanRequest(controlChannel, 12, requestSettings); - mLooper.dispatchAll(); - verifyStartBackgroundScan(order, nativeSettings); - verifySuccessfulResponse(order, handler, 12); - verifyNoMoreInteractions(handler); - } - - @Test - public void sendBackgroundScanBandRequest() throws Exception { - WifiScanner.ScanSettings requestSettings = createRequest(WifiScanner.WIFI_BAND_BOTH, 20000, - 0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN); - WifiNative.ScanSettings nativeSettings = new NativeScanSettingsBuilder() - .withBasePeriod(20000) - .withMaxApPerScan(MAX_AP_PER_SCAN) - .withMaxScansToCache(WifiScanningScheduler.DEFAULT_MAX_SCANS_TO_BATCH) - .addBucketWithBand(20000, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN, - WifiScanner.WIFI_BAND_BOTH) - .build(); - doSuccessfulBackgroundScan(requestSettings, nativeSettings); - } - - @Test - public void sendBackgroundScanChannelsRequest() throws Exception { - WifiScanner.ScanSettings requestSettings = createRequest(channelsToSpec(5150), 20000, - 0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN); - WifiNative.ScanSettings nativeSettings = new NativeScanSettingsBuilder() - .withBasePeriod(20000) - .withMaxApPerScan(MAX_AP_PER_SCAN) - .withMaxScansToCache(WifiScanningScheduler.DEFAULT_MAX_SCANS_TO_BATCH) - .addBucketWithChannels(20000, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN, 5150) - .build(); - doSuccessfulBackgroundScan(requestSettings, nativeSettings); - } } diff --git a/tests/wifitests/src/com/android/server/wifi/WifiStateMachineTest.java b/tests/wifitests/src/com/android/server/wifi/WifiStateMachineTest.java index 096a7397e..c092f0d79 100644 --- a/tests/wifitests/src/com/android/server/wifi/WifiStateMachineTest.java +++ b/tests/wifitests/src/com/android/server/wifi/WifiStateMachineTest.java @@ -41,7 +41,6 @@ import android.net.wifi.ScanResult; import android.net.wifi.SupplicantState; import android.net.wifi.WifiConfiguration; import android.net.wifi.WifiManager; -import android.net.wifi.WifiScanner; import android.net.wifi.WifiSsid; import android.net.wifi.p2p.IWifiP2pManager; import android.os.BatteryStats; @@ -74,7 +73,6 @@ import com.android.server.wifi.p2p.WifiP2pServiceImpl; import org.junit.After; import org.junit.Before; import org.junit.Test; -import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.MockitoAnnotations; @@ -85,7 +83,6 @@ import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.ArrayList; -import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -195,8 +192,6 @@ public class WifiStateMachineTest { when(context.getSystemService(Context.CONNECTIVITY_SERVICE)).thenReturn( mock(ConnectivityManager.class)); - when(context.getSystemService(Context.WIFI_SCANNING_SERVICE)).thenReturn(mWifiScanner); - return context; } @@ -261,20 +256,16 @@ public class WifiStateMachineTest { ScanDetail detail = new ScanDetail(nd, sWifiSsid, sBSSID, "", rssi, sFreq, Long.MAX_VALUE /* needed so that scan results aren't rejected because there older than scan start */); - detail.getScanResult().informationElements = ie; - detail.getScanResult().anqpLines = new ArrayList<String>(); return detail; } - private ScanResult[] getMockScanResults() { + private ArrayList<ScanDetail> getMockScanResults() { ScanResults sr = ScanResults.create(0, 2412, 2437, 2462, 5180, 5220, 5745, 5825); - // copy generated results and add space on the end for one more - ScanResult[] results = Arrays.copyOf(sr.getScanData().getResults(), - sr.getScanData().getResults().length + 1); + ArrayList<ScanDetail> list = sr.getScanDetailArrayList(); int rssi = -65; - results[results.length - 1] = getGoogleGuestScanDetail(rssi).getScanResult(); - return results; + list.add(getGoogleGuestScanDetail(rssi)); + return list; } static final String sSSID = "\"GoogleGuest\""; @@ -292,7 +283,6 @@ public class WifiStateMachineTest { MockWifiMonitor mWifiMonitor; @Mock WifiNative mWifiNative; - @Mock WifiScanner mWifiScanner; @Mock SupplicantStateTracker mSupplicantStateTracker; @Mock WifiMetrics mWifiMetrics; @@ -520,27 +510,14 @@ public class WifiStateMachineTest { mWsm.startScan(-1, 0, null, null); wait(200); - ArgumentCaptor<WifiScanner.ScanSettings> scanSettingsCaptor = - ArgumentCaptor.forClass(WifiScanner.ScanSettings.class); - ArgumentCaptor<WifiScanner.ScanListener> scanListenerCaptor = - ArgumentCaptor.forClass(WifiScanner.ScanListener.class); - verify(mWifiScanner).startScan(scanSettingsCaptor.capture(), scanListenerCaptor.capture()); - assertEquals("band", WifiScanner.WIFI_BAND_BOTH_WITH_DFS, - scanSettingsCaptor.getValue().band); - assertEquals("reportEvents", WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN - | WifiScanner.REPORT_EVENT_FULL_SCAN_RESULT, - scanSettingsCaptor.getValue().reportEvents); - - ScanResult[] results = getMockScanResults(); - for (ScanResult result : results) { - scanListenerCaptor.getValue().onFullResult(result); - } - scanListenerCaptor.getValue().onResults( - new WifiScanner.ScanData[] {new WifiScanner.ScanData(0, 0, results)}); + verify(mWifiNative).scan(WifiNative.SCAN_WITHOUT_CONNECTION_SETUP, null); + + when(mWifiNative.getScanResults()).thenReturn(getMockScanResults()); + mWsm.sendMessage(WifiMonitor.SCAN_RESULTS_EVENT); wait(200); - List<ScanResult> reportedResults = mWsm.syncGetScanResultsList(); - assertEquals(8, reportedResults.size()); + List<ScanResult> results = mWsm.syncGetScanResultsList(); + assertEquals(8, results.size()); } @Test |