Modify wifi BatchedScan.
Add pollBatchedScan API to allow forced retrieval.
Modified driver API, adding MSCAN, removing nextCount and making
the results look more like normal manual scan results.
bug:9301872
Change-Id: I58bce0624c36e2ad8d3c3f5defcb4d4e155dc8f9
diff --git a/framework/java/android/net/wifi/BatchedScanSettings.java b/framework/java/android/net/wifi/BatchedScanSettings.java
index 82945d6..44a2ab4 100644
--- a/framework/java/android/net/wifi/BatchedScanSettings.java
+++ b/framework/java/android/net/wifi/BatchedScanSettings.java
@@ -51,6 +51,7 @@
public final static int MAX_AP_FOR_DISTANCE = MAX_AP_PER_SCAN;
public final static int DEFAULT_AP_FOR_DISTANCE = 0;
+ public final static int MAX_WIFI_CHANNEL = 196;
/** The expected number of scans per batch. Note that the firmware may drop scans
* leading to fewer scans during the normal batch scan duration. This value need not
@@ -113,7 +114,7 @@
for (String channel : channelSet) {
try {
int i = Integer.parseInt(channel);
- if (i > 0 && i < 197) continue;
+ if (i > 0 && i <= MAX_WIFI_CHANNEL) continue;
} catch (NumberFormatException e) {}
if (channel.equals("A") || channel.equals("B")) continue;
return false;
diff --git a/framework/java/android/net/wifi/IWifiManager.aidl b/framework/java/android/net/wifi/IWifiManager.aidl
index c8cf323..4f68ca0 100644
--- a/framework/java/android/net/wifi/IWifiManager.aidl
+++ b/framework/java/android/net/wifi/IWifiManager.aidl
@@ -124,5 +124,7 @@
List<BatchedScanResult> getBatchedScanResults(String callingPackage);
boolean isBatchedScanSupported();
+
+ void pollBatchedScan();
}
diff --git a/framework/java/android/net/wifi/WifiManager.java b/framework/java/android/net/wifi/WifiManager.java
index 01ca378..a15b664 100644
--- a/framework/java/android/net/wifi/WifiManager.java
+++ b/framework/java/android/net/wifi/WifiManager.java
@@ -840,6 +840,32 @@
}
/**
+ * Force a re-reading of batched scan results. This will attempt
+ * to read more information from the chip, but will do so at the expense
+ * of previous data. Rate limited to the current scan frequency.
+ *
+ * pollBatchedScan will always wait 1 period from the start of the batch
+ * before trying to read from the chip, so if your #scans/batch == 1 this will
+ * have no effect.
+ *
+ * If you had already waited 1 period before calling, this should have
+ * immediate (though async) effect.
+ *
+ * If you call before that 1 period is up this will set up a timer and fetch
+ * results when the 1 period is up.
+ *
+ * Servicing a pollBatchedScan request (immediate or after timed delay) starts a
+ * new batch, so if you were doing 10 scans/batch and called in the 4th scan, you
+ * would get data in the 4th and then again 10 scans later.
+ * @hide
+ */
+ public void pollBatchedScan() {
+ try {
+ mService.pollBatchedScan();
+ } catch (RemoteException e) { }
+ }
+
+ /**
* Return dynamic information about the current Wi-Fi connection, if any is active.
* @return the Wi-Fi information, contained in {@link WifiInfo}.
*/
diff --git a/framework/java/android/net/wifi/WifiNative.java b/framework/java/android/net/wifi/WifiNative.java
index 0359076..48c5ae3 100644
--- a/framework/java/android/net/wifi/WifiNative.java
+++ b/framework/java/android/net/wifi/WifiNative.java
@@ -221,8 +221,9 @@
/**
* Format of command
- * DRIVER WLS_BATCHING SET SCAN_FRQ=x BESTN=y CHANNEL=<z, w, t> RTT=s
+ * DRIVER WLS_BATCHING SET SCAN_FRQ=x MSCAN=r BESTN=y CHANNEL=<z, w, t> RTT=s
* where x is an ascii representation of an integer number of seconds between scans
+ * r is an ascii representation of an integer number of scans per batch
* y is an ascii representation of an integer number of the max AP to remember per scan
* z, w, t represent a 1..n size list of channel numbers and/or 'A', 'B' values
* indicating entire ranges of channels
@@ -235,8 +236,9 @@
public String setBatchedScanSettings(BatchedScanSettings settings) {
if (settings == null) return doStringCommand("DRIVER WLS_BATCHING STOP");
String cmd = "DRIVER WLS_BATCHING SET SCAN_FRQ=" + settings.scanIntervalSec;
+ cmd += " MSCAN=" + settings.maxScansPerBatch;
if (settings.maxApPerScan != BatchedScanSettings.UNSPECIFIED) {
- cmd += " BESTN " + settings.maxApPerScan;
+ cmd += " BESTN=" + settings.maxApPerScan;
}
if (settings.channelSet != null && !settings.channelSet.isEmpty()) {
cmd += " CHANNEL=<";
diff --git a/framework/java/android/net/wifi/WifiStateMachine.java b/framework/java/android/net/wifi/WifiStateMachine.java
index 764c00a..8b7b8ae 100644
--- a/framework/java/android/net/wifi/WifiStateMachine.java
+++ b/framework/java/android/net/wifi/WifiStateMachine.java
@@ -127,6 +127,8 @@
private final List<BatchedScanResult> mBatchedScanResults =
new ArrayList<BatchedScanResult>();
private int mBatchedScanOwnerUid = UNKNOWN_SCAN_SOURCE;
+ private int mExpectedBatchedScans = 0;
+ private long mBatchedScanMinPollTime = 0;
/* Chipset supports background scan */
private final boolean mBackgroundScanSupported;
@@ -366,8 +368,9 @@
* arg1 = responsible UID
* obj = the new settings
*/
- public static final int CMD_SET_BATCH_SCAN = BASE + 135;
+ public static final int CMD_SET_BATCHED_SCAN = BASE + 135;
public static final int CMD_START_NEXT_BATCHED_SCAN = BASE + 136;
+ public static final int CMD_POLL_BATCHED_SCAN = BASE + 137;
public static final int CONNECT_MODE = 1;
public static final int SCAN_ONLY_MODE = 2;
@@ -766,7 +769,7 @@
* start or stop batched scanning using the given settings
*/
public void setBatchedScanSettings(BatchedScanSettings settings, int callingUid) {
- sendMessage(CMD_SET_BATCH_SCAN, callingUid, 0, settings);
+ sendMessage(CMD_SET_BATCHED_SCAN, callingUid, 0, settings);
}
public List<BatchedScanResult> syncGetBatchedScanResultsList() {
@@ -780,6 +783,10 @@
}
}
+ public void requestBatchedScanPoll() {
+ sendMessage(CMD_POLL_BATCHED_SCAN);
+ }
+
private void startBatchedScan() {
// first grab any existing data
retrieveBatchedScanData();
@@ -789,8 +796,8 @@
String scansExpected = mWifiNative.setBatchedScanSettings(mBatchedScanSettings);
try {
- int expected = Integer.parseInt(scansExpected);
- setNextBatchedAlarm(expected);
+ mExpectedBatchedScans = Integer.parseInt(scansExpected);
+ setNextBatchedAlarm(mExpectedBatchedScans);
} catch (NumberFormatException e) {
loge("Exception parsing WifiNative.setBatchedScanSettings response " + e);
}
@@ -803,9 +810,27 @@
private void startNextBatchedScan() {
// first grab any existing data
- int nextCount = retrieveBatchedScanData();
+ retrieveBatchedScanData();
- setNextBatchedAlarm(nextCount);
+ setNextBatchedAlarm(mExpectedBatchedScans);
+ }
+
+ private void handleBatchedScanPollRequest() {
+ // if there is no appropriate PollTime that's because we either aren't
+ // batching or we've already set a time for a poll request
+ if (mBatchedScanMinPollTime == 0) return;
+ if (mBatchedScanSettings == null) return;
+
+ long now = System.currentTimeMillis();
+
+ if (now > mBatchedScanMinPollTime) {
+ // do the poll and reset our timers
+ startNextBatchedScan();
+ } else {
+ mAlarmManager.set(AlarmManager.RTC_WAKEUP, mBatchedScanMinPollTime,
+ mBatchedScanIntervalIntent);
+ mBatchedScanMinPollTime = 0;
+ }
}
// return true if new/different
@@ -832,6 +857,9 @@
if (mBatchedScanSettings == null || scansExpected < 1) return;
+ mBatchedScanMinPollTime = System.currentTimeMillis() +
+ mBatchedScanSettings.scanIntervalSec * 1000;
+
if (mBatchedScanSettings.maxScansPerBatch < scansExpected) {
scansExpected = mBatchedScanSettings.maxScansPerBatch;
}
@@ -876,22 +904,18 @@
* etc
* "----"
*/
- private int retrieveBatchedScanData() {
+ private void retrieveBatchedScanData() {
String rawData = mWifiNative.getBatchedScanResults();
+ mBatchedScanMinPollTime = 0;
if (rawData == null) {
loge("Unexpected null BatchedScanResults");
- return 0;
+ return;
}
- int nextCount = 0;
int scanCount = 0;
- final String END_OF_SCAN = "====";
- final String END_OF_BATCH = "%%%%";
final String END_OF_BATCHES = "----";
final String SCANCOUNT = "scancount=";
- final String NEXTCOUNT = "nextcount=";
final String TRUNCATED = "trunc";
- final String APCOUNT = "apcount=";
final String AGE = "age=";
final String DIST = "dist=";
final String DISTSD = "distsd=";
@@ -905,16 +929,7 @@
}
if (scanCount == 0) {
loge("scanCount not found");
- return 0;
- }
- if (splitData[n].startsWith(NEXTCOUNT)) {
- try {
- nextCount = Integer.parseInt(splitData[n++].substring(NEXTCOUNT.length()));
- } catch (NumberFormatException e) {}
- }
- if (nextCount == 0) {
- loge("nextCount not found");
- return 0;
+ return;
}
final Intent intent = new Intent(WifiManager.BATCHED_SCAN_RESULTS_AVAILABLE_ACTION);
@@ -942,9 +957,9 @@
if (mBatchedScanResults.size() > 0) {
mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
}
- return nextCount;
+ return;
}
- if ((splitData[n].equals(END_OF_SCAN)) || splitData[n].equals(END_OF_BATCH)) {
+ if ((splitData[n].equals(END_STR)) || splitData[n].equals(DELIMITER_STR)) {
if (bssid != null) {
batchedScanResult.scanResults.add(new ScanResult(
wifiSsid, bssid, "", level, freq, tsf, dist, distSd));
@@ -955,7 +970,7 @@
tsf = 0;
dist = distSd = ScanResult.UNSPECIFIED;
}
- if (splitData[n].equals(END_OF_BATCH)) {
+ if (splitData[n].equals(END_STR)) {
if (batchedScanResult.scanResults.size() != 0) {
mBatchedScanResults.add(batchedScanResult);
batchedScanResult = new BatchedScanResult();
@@ -1010,7 +1025,7 @@
rawData = mWifiNative.getBatchedScanResults();
if (rawData == null) {
loge("Unexpected null BatchedScanResults");
- return nextCount;
+ return;
}
splitData = rawData.split("\n");
if (splitData.length == 0 || splitData[0].equals("ok")) {
@@ -1018,7 +1033,7 @@
if (mBatchedScanResults.size() > 0) {
mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
}
- return nextCount;
+ return;
}
n = 0;
}
@@ -2266,9 +2281,11 @@
sendMessageAtFrontOfQueue(CMD_SET_COUNTRY_CODE, countryCode);
}
break;
- case CMD_SET_BATCH_SCAN:
+ case CMD_SET_BATCHED_SCAN:
recordBatchedScanSettings((BatchedScanSettings)message.obj);
break;
+ case CMD_POLL_BATCHED_SCAN:
+ handleBatchedScanPollRequest();
case CMD_START_NEXT_BATCHED_SCAN:
startNextBatchedScan();
break;
@@ -2808,7 +2825,7 @@
noteScanStart(message.arg1, (WorkSource) message.obj);
startScanNative(WifiNative.SCAN_WITH_CONNECTION_SETUP);
break;
- case CMD_SET_BATCH_SCAN:
+ case CMD_SET_BATCHED_SCAN:
recordBatchedScanSettings((BatchedScanSettings)message.obj);
startBatchedScan();
break;