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
This commit is contained in:
Robert Greenwalt
2013-08-14 16:07:44 -07:00
parent 7a8d9d6fec
commit 8e628dadc3
6 changed files with 87 additions and 33 deletions

View File

@@ -345,6 +345,12 @@ public final class WifiService extends IWifiManager.Stub {
return mBatchedScanSupported;
}
public void pollBatchedScan() {
enforceChangePermission();
if (mBatchedScanSupported == false) return;
mWifiStateMachine.requestBatchedScanPoll();
}
/**
* see {@link android.net.wifi.WifiManager#requestBatchedScan()}
*/

View File

@@ -51,6 +51,7 @@ public class BatchedScanSettings implements Parcelable {
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 @@ public class BatchedScanSettings implements Parcelable {
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;

View File

@@ -124,5 +124,7 @@ interface IWifiManager
List<BatchedScanResult> getBatchedScanResults(String callingPackage);
boolean isBatchedScanSupported();
void pollBatchedScan();
}

View File

@@ -839,6 +839,32 @@ public class WifiManager {
}
}
/**
* 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}.

View File

@@ -221,8 +221,9 @@ public class WifiNative {
/**
* 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 class WifiNative {
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=<";

View File

@@ -127,6 +127,8 @@ public class WifiStateMachine extends StateMachine {
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 @@ public class WifiStateMachine extends StateMachine {
* 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 @@ public class WifiStateMachine extends StateMachine {
* 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 class WifiStateMachine extends StateMachine {
}
}
public void requestBatchedScanPoll() {
sendMessage(CMD_POLL_BATCHED_SCAN);
}
private void startBatchedScan() {
// first grab any existing data
retrieveBatchedScanData();
@@ -789,8 +796,8 @@ public class WifiStateMachine extends StateMachine {
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 @@ public class WifiStateMachine extends StateMachine {
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 @@ public class WifiStateMachine extends StateMachine {
if (mBatchedScanSettings == null || scansExpected < 1) return;
mBatchedScanMinPollTime = System.currentTimeMillis() +
mBatchedScanSettings.scanIntervalSec * 1000;
if (mBatchedScanSettings.maxScansPerBatch < scansExpected) {
scansExpected = mBatchedScanSettings.maxScansPerBatch;
}
@@ -876,22 +904,18 @@ public class WifiStateMachine extends StateMachine {
* 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 @@ public class WifiStateMachine extends StateMachine {
}
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 @@ public class WifiStateMachine extends StateMachine {
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 @@ public class WifiStateMachine extends StateMachine {
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 @@ public class WifiStateMachine extends StateMachine {
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 @@ public class WifiStateMachine extends StateMachine {
if (mBatchedScanResults.size() > 0) {
mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
}
return nextCount;
return;
}
n = 0;
}
@@ -2266,9 +2281,11 @@ public class WifiStateMachine extends StateMachine {
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 @@ public class WifiStateMachine extends StateMachine {
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;