am e8c51298: Merge "Add BatteryStats for Wifi Batched Scanning." into klp-dev

* commit 'e8c51298a43f607fea7418ced7cc783e6065fe87':
  Add BatteryStats for Wifi Batched Scanning.
This commit is contained in:
Robert Greenwalt
2013-11-07 10:32:53 -08:00
committed by Android Git Automerger
11 changed files with 333 additions and 51 deletions

View File

@ -105,6 +105,11 @@ public abstract class BatteryStats implements Parcelable {
*/
public static final int FOREGROUND_ACTIVITY = 10;
/**
* A constant indicating a wifi batched scan is active
*/
public static final int WIFI_BATCHED_SCAN = 11;
/**
* Include all of the data in the stats, including previously saved data.
*/
@ -270,6 +275,8 @@ public abstract class BatteryStats implements Parcelable {
public abstract void noteFullWifiLockReleasedLocked();
public abstract void noteWifiScanStartedLocked();
public abstract void noteWifiScanStoppedLocked();
public abstract void noteWifiBatchedScanStartedLocked(int csph);
public abstract void noteWifiBatchedScanStoppedLocked();
public abstract void noteWifiMulticastEnabledLocked();
public abstract void noteWifiMulticastDisabledLocked();
public abstract void noteAudioTurnedOnLocked();
@ -281,6 +288,7 @@ public abstract class BatteryStats implements Parcelable {
public abstract long getWifiRunningTime(long batteryRealtime, int which);
public abstract long getFullWifiLockTime(long batteryRealtime, int which);
public abstract long getWifiScanTime(long batteryRealtime, int which);
public abstract long getWifiBatchedScanTime(int csphBin, long batteryRealtime, int which);
public abstract long getWifiMulticastTime(long batteryRealtime,
int which);
public abstract long getAudioTurnedOnTime(long batteryRealtime, int which);
@ -288,6 +296,8 @@ public abstract class BatteryStats implements Parcelable {
public abstract Timer getForegroundActivityTimer();
public abstract Timer getVibratorOnTimer();
public static final int NUM_WIFI_BATCHED_SCAN_BINS = 5;
/**
* Note that these must match the constants in android.os.PowerManager.
* Also, if the user activity types change, the BatteryStatsImpl.VERSION must
@ -2081,9 +2091,11 @@ public abstract class BatteryStats implements Parcelable {
TimeUtils.formatDuration(ew.usedTime, pw);
pw.print(" over ");
TimeUtils.formatDuration(ew.overTime, pw);
pw.print(" (");
pw.print((ew.usedTime*100)/ew.overTime);
pw.println("%)");
if (ew.overTime != 0) {
pw.print(" (");
pw.print((ew.usedTime*100)/ew.overTime);
pw.println("%)");
}
}
}
uidActivity = true;

View File

@ -68,6 +68,8 @@ interface IBatteryStats {
void noteFullWifiLockReleasedFromSource(in WorkSource ws);
void noteWifiScanStartedFromSource(in WorkSource ws);
void noteWifiScanStoppedFromSource(in WorkSource ws);
void noteWifiBatchedScanStartedFromSource(in WorkSource ws, int csph);
void noteWifiBatchedScanStoppedFromSource(in WorkSource ws);
void noteWifiMulticastEnabledFromSource(in WorkSource ws);
void noteWifiMulticastDisabledFromSource(in WorkSource ws);
void noteNetworkInterfaceType(String iface, int type);

View File

@ -84,7 +84,7 @@ public final class BatteryStatsImpl extends BatteryStats {
private static final int MAGIC = 0xBA757475; // 'BATSTATS'
// Current on-disk Parcel version
private static final int VERSION = 66 + (USE_OLD_HISTORY ? 1000 : 0);
private static final int VERSION = 67 + (USE_OLD_HISTORY ? 1000 : 0);
// Maximum number of items we will record in the history.
private static final int MAX_HISTORY_ITEMS = 2000;
@ -154,6 +154,8 @@ public final class BatteryStatsImpl extends BatteryStats {
final ArrayList<StopwatchTimer> mFullWifiLockTimers = new ArrayList<StopwatchTimer>();
final ArrayList<StopwatchTimer> mWifiMulticastTimers = new ArrayList<StopwatchTimer>();
final ArrayList<StopwatchTimer> mWifiScanTimers = new ArrayList<StopwatchTimer>();
final SparseArray<ArrayList<StopwatchTimer>> mWifiBatchedScanTimers =
new SparseArray<ArrayList<StopwatchTimer>>();
// Last partial timers we use for distributing CPU usage.
final ArrayList<StopwatchTimer> mLastPartialTimers = new ArrayList<StopwatchTimer>();
@ -2404,6 +2406,14 @@ public final class BatteryStatsImpl extends BatteryStats {
getUidStatsLocked(uid).noteWifiScanStoppedLocked();
}
public void noteWifiBatchedScanStartedLocked(int uid, int csph) {
getUidStatsLocked(uid).noteWifiBatchedScanStartedLocked(csph);
}
public void noteWifiBatchedScanStoppedLocked(int uid) {
getUidStatsLocked(uid).noteWifiBatchedScanStoppedLocked();
}
int mWifiMulticastNesting = 0;
public void noteWifiMulticastEnabledLocked(int uid) {
@ -2456,6 +2466,20 @@ public final class BatteryStatsImpl extends BatteryStats {
}
}
public void noteWifiBatchedScanStartedFromSourceLocked(WorkSource ws, int csph) {
int N = ws.size();
for (int i=0; i<N; i++) {
noteWifiBatchedScanStartedLocked(ws.get(i), csph);
}
}
public void noteWifiBatchedScanStoppedFromSourceLocked(WorkSource ws) {
int N = ws.size();
for (int i=0; i<N; i++) {
noteWifiBatchedScanStoppedLocked(ws.get(i));
}
}
public void noteWifiMulticastEnabledFromSourceLocked(WorkSource ws) {
int N = ws.size();
for (int i=0; i<N; i++) {
@ -2579,6 +2603,10 @@ public final class BatteryStatsImpl extends BatteryStats {
boolean mWifiScanStarted;
StopwatchTimer mWifiScanTimer;
private static final int NO_BATCHED_SCAN_STARTED = -1;
int mWifiBatchedScanBinStarted = NO_BATCHED_SCAN_STARTED;
StopwatchTimer[] mWifiBatchedScanTimer;
boolean mWifiMulticastEnabled;
StopwatchTimer mWifiMulticastTimer;
@ -2629,6 +2657,7 @@ public final class BatteryStatsImpl extends BatteryStats {
mFullWifiLockTimers, mUnpluggables);
mWifiScanTimer = new StopwatchTimer(Uid.this, WIFI_SCAN,
mWifiScanTimers, mUnpluggables);
mWifiBatchedScanTimer = new StopwatchTimer[NUM_WIFI_BATCHED_SCAN_BINS];
mWifiMulticastTimer = new StopwatchTimer(Uid.this, WIFI_MULTICAST_ENABLED,
mWifiMulticastTimers, mUnpluggables);
}
@ -2718,6 +2747,36 @@ public final class BatteryStatsImpl extends BatteryStats {
}
}
@Override
public void noteWifiBatchedScanStartedLocked(int csph) {
int bin = 0;
while (csph > 8 && bin < NUM_WIFI_BATCHED_SCAN_BINS) {
csph = csph >> 3;
bin++;
}
if (mWifiBatchedScanBinStarted == bin) return;
if (mWifiBatchedScanBinStarted != NO_BATCHED_SCAN_STARTED) {
mWifiBatchedScanTimer[mWifiBatchedScanBinStarted].
stopRunningLocked(BatteryStatsImpl.this);
}
mWifiBatchedScanBinStarted = bin;
if (mWifiBatchedScanTimer[bin] == null) {
makeWifiBatchedScanBin(bin, null);
}
mWifiBatchedScanTimer[bin].startRunningLocked(BatteryStatsImpl.this);
}
@Override
public void noteWifiBatchedScanStoppedLocked() {
if (mWifiBatchedScanBinStarted != NO_BATCHED_SCAN_STARTED) {
mWifiBatchedScanTimer[mWifiBatchedScanBinStarted].
stopRunningLocked(BatteryStatsImpl.this);
mWifiBatchedScanBinStarted = NO_BATCHED_SCAN_STARTED;
}
}
@Override
public void noteWifiMulticastEnabledLocked() {
if (!mWifiMulticastEnabled) {
@ -2853,6 +2912,15 @@ public final class BatteryStatsImpl extends BatteryStats {
return mWifiScanTimer.getTotalTimeLocked(batteryRealtime, which);
}
@Override
public long getWifiBatchedScanTime(int csphBin, long batteryRealtime, int which) {
if (csphBin < 0 || csphBin >= NUM_WIFI_BATCHED_SCAN_BINS) return 0;
if (mWifiBatchedScanTimer[csphBin] == null) {
return 0;
}
return mWifiBatchedScanTimer[csphBin].getTotalTimeLocked(batteryRealtime, which);
}
@Override
public long getWifiMulticastTime(long batteryRealtime, int which) {
if (mWifiMulticastTimer == null) {
@ -2914,6 +2982,24 @@ public final class BatteryStatsImpl extends BatteryStats {
return mUserActivityCounters[type].getCountLocked(which);
}
void makeWifiBatchedScanBin(int i, Parcel in) {
if (i < 0 || i >= NUM_WIFI_BATCHED_SCAN_BINS) return;
ArrayList<StopwatchTimer> collected = mWifiBatchedScanTimers.get(i);
if (collected == null) {
collected = new ArrayList<StopwatchTimer>();
mWifiBatchedScanTimers.put(i, collected);
}
if (in == null) {
mWifiBatchedScanTimer[i] = new StopwatchTimer(this, WIFI_BATCHED_SCAN, collected,
mUnpluggables);
} else {
mWifiBatchedScanTimer[i] = new StopwatchTimer(this, WIFI_BATCHED_SCAN, collected,
mUnpluggables, in);
}
}
void initUserActivityLocked() {
mUserActivityCounters = new Counter[NUM_USER_ACTIVITY_TYPES];
for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) {
@ -2974,6 +3060,14 @@ public final class BatteryStatsImpl extends BatteryStats {
active |= !mWifiScanTimer.reset(BatteryStatsImpl.this, false);
active |= mWifiScanStarted;
}
if (mWifiBatchedScanTimer != null) {
for (int i = 0; i < NUM_WIFI_BATCHED_SCAN_BINS; i++) {
if (mWifiBatchedScanTimer[i] != null) {
active |= !mWifiBatchedScanTimer[i].reset(BatteryStatsImpl.this, false);
}
}
active |= (mWifiBatchedScanBinStarted != NO_BATCHED_SCAN_STARTED);
}
if (mWifiMulticastTimer != null) {
active |= !mWifiMulticastTimer.reset(BatteryStatsImpl.this, false);
active |= mWifiMulticastEnabled;
@ -3080,6 +3174,11 @@ public final class BatteryStatsImpl extends BatteryStats {
if (mWifiScanTimer != null) {
mWifiScanTimer.detach();
}
for (int i = 0; i < NUM_WIFI_BATCHED_SCAN_BINS; i++) {
if (mWifiBatchedScanTimer[i] != null) {
mWifiBatchedScanTimer[i].detach();
}
}
if (mWifiMulticastTimer != null) {
mWifiMulticastTimer.detach();
}
@ -3157,6 +3256,14 @@ public final class BatteryStatsImpl extends BatteryStats {
} else {
out.writeInt(0);
}
for (int i = 0; i < NUM_WIFI_BATCHED_SCAN_BINS; i++) {
if (mWifiBatchedScanTimer[i] != null) {
out.writeInt(1);
mWifiBatchedScanTimer[i].writeToParcel(out, batteryRealtime);
} else {
out.writeInt(0);
}
}
if (mWifiMulticastTimer != null) {
out.writeInt(1);
mWifiMulticastTimer.writeToParcel(out, batteryRealtime);
@ -3266,6 +3373,14 @@ public final class BatteryStatsImpl extends BatteryStats {
} else {
mWifiScanTimer = null;
}
mWifiBatchedScanBinStarted = NO_BATCHED_SCAN_STARTED;
for (int i = 0; i < NUM_WIFI_BATCHED_SCAN_BINS; i++) {
if (in.readInt() != 0) {
makeWifiBatchedScanBin(i, in);
} else {
mWifiBatchedScanTimer[i] = null;
}
}
mWifiMulticastEnabled = false;
if (in.readInt() != 0) {
mWifiMulticastTimer = new StopwatchTimer(Uid.this, WIFI_MULTICAST_ENABLED,
@ -5463,6 +5578,13 @@ public final class BatteryStatsImpl extends BatteryStats {
if (in.readInt() != 0) {
u.mWifiScanTimer.readSummaryFromParcelLocked(in);
}
u.mWifiBatchedScanBinStarted = Uid.NO_BATCHED_SCAN_STARTED;
for (int i = 0; i < Uid.NUM_WIFI_BATCHED_SCAN_BINS; i++) {
if (in.readInt() != 0) {
u.makeWifiBatchedScanBin(i, null);
u.mWifiBatchedScanTimer[i].readSummaryFromParcelLocked(in);
}
}
u.mWifiMulticastEnabled = false;
if (in.readInt() != 0) {
u.mWifiMulticastTimer.readSummaryFromParcelLocked(in);
@ -5674,6 +5796,14 @@ public final class BatteryStatsImpl extends BatteryStats {
} else {
out.writeInt(0);
}
for (int i = 0; i < Uid.NUM_WIFI_BATCHED_SCAN_BINS; i++) {
if (u.mWifiBatchedScanTimer[i] != null) {
out.writeInt(1);
u.mWifiBatchedScanTimer[i].writeSummaryFromParcelLocked(out, NOWREAL);
} else {
out.writeInt(0);
}
}
if (u.mWifiMulticastTimer != null) {
out.writeInt(1);
u.mWifiMulticastTimer.writeSummaryFromParcelLocked(out, NOWREAL);
@ -5909,6 +6039,7 @@ public final class BatteryStatsImpl extends BatteryStats {
mWifiRunningTimers.clear();
mFullWifiLockTimers.clear();
mWifiScanTimers.clear();
mWifiBatchedScanTimers.clear();
mWifiMulticastTimers.clear();
sNumSpeedSteps = in.readInt();

View File

@ -135,6 +135,13 @@ public class PowerProfile {
public static final String POWER_CPU_SPEEDS = "cpu.speeds";
/**
* Power consumed by wif batched scaning. Broken down into bins by
* Channels Scanned per Hour. May do 1-720 scans per hour of 1-100 channels
* for a range of 1-72,000. Going logrithmic (1-8, 9-64, 65-512, 513-4096, 4097-)!
*/
public static final String POWER_WIFI_BATCHED_SCAN = "wifi.batchedscan";
/**
* Battery capacity in milliAmpHour (mAh).
*/
@ -171,7 +178,7 @@ public class PowerProfile {
String element = parser.getName();
if (element == null) break;
if (parsingArray && !element.equals(TAG_ARRAYITEM)) {
// Finish array
sPowerMap.put(arrayName, array.toArray(new Double[array.size()]));

View File

@ -58,4 +58,12 @@
</array>
<!-- This is the battery capacity in mAh (measured at nominal voltage) -->
<item name="battery.capacity">1000</item>
<array name="wifi.batchedscan"> <!-- mA -->
<value>.0002</value> <!-- 1-8/hr -->
<value>.002</value> <!-- 9-64/hr -->
<value>.02</value> <!-- 65-512/hr -->
<value>.2</value> <!-- 513-4,096/hr -->
<value>2</value> <!-- 4097-/hr -->
</array>
</device>

View File

@ -419,6 +419,20 @@ public final class BatteryStatsService extends IBatteryStats.Stub {
}
}
public void noteWifiBatchedScanStartedFromSource(WorkSource ws, int csph) {
enforceCallingPermission();
synchronized (mStats) {
mStats.noteWifiBatchedScanStartedFromSourceLocked(ws, csph);
}
}
public void noteWifiBatchedScanStoppedFromSource(WorkSource ws) {
enforceCallingPermission();
synchronized (mStats) {
mStats.noteWifiBatchedScanStoppedFromSourceLocked(ws);
}
}
public void noteWifiMulticastEnabledFromSource(WorkSource ws) {
enforceCallingPermission();
synchronized (mStats) {

View File

@ -369,15 +369,17 @@ public final class WifiService extends IWifiManager.Stub {
}
private class BatchedScanRequest extends DeathRecipient {
BatchedScanSettings settings;
int uid;
int pid;
final BatchedScanSettings settings;
final int uid;
final int pid;
final WorkSource workSource;
BatchedScanRequest(BatchedScanSettings settings, IBinder binder) {
BatchedScanRequest(BatchedScanSettings settings, IBinder binder, WorkSource ws) {
super(0, null, binder, null);
this.settings = settings;
this.uid = getCallingUid();
this.pid = getCallingPid();
workSource = ws;
}
public void binderDied() {
stopBatchedScan(settings, uid, pid);
@ -406,12 +408,19 @@ public final class WifiService extends IWifiManager.Stub {
/**
* see {@link android.net.wifi.WifiManager#requestBatchedScan()}
*/
public boolean requestBatchedScan(BatchedScanSettings requested, IBinder binder) {
public boolean requestBatchedScan(BatchedScanSettings requested, IBinder binder,
WorkSource workSource) {
enforceChangePermission();
if (workSource != null) {
enforceWorkSourcePermission();
// WifiManager currently doesn't use names, so need to clear names out of the
// supplied WorkSource to allow future WorkSource combining.
workSource.clearNames();
}
if (mBatchedScanSupported == false) return false;
requested = new BatchedScanSettings(requested);
if (requested.isInvalid()) return false;
BatchedScanRequest r = new BatchedScanRequest(requested, binder);
BatchedScanRequest r = new BatchedScanRequest(requested, binder, workSource);
synchronized(mBatchedScanners) {
mBatchedScanners.add(r);
resolveBatchedScannersLocked();
@ -468,18 +477,48 @@ public final class WifiService extends IWifiManager.Stub {
private void resolveBatchedScannersLocked() {
BatchedScanSettings setting = new BatchedScanSettings();
WorkSource responsibleWorkSource = null;
int responsibleUid = 0;
double responsibleCsph = 0; // Channel Scans Per Hour
if (mBatchedScanners.size() == 0) {
mWifiStateMachine.setBatchedScanSettings(null, 0);
mWifiStateMachine.setBatchedScanSettings(null, 0, 0, null);
return;
}
for (BatchedScanRequest r : mBatchedScanners) {
BatchedScanSettings s = r.settings;
// evaluate responsibility
int currentChannelCount;
int currentScanInterval;
double currentCsph;
if (s.channelSet == null || s.channelSet.isEmpty()) {
// all channels - 11 B and 9 A channels roughly.
currentChannelCount = 9 + 11;
} else {
currentChannelCount = s.channelSet.size();
// these are rough est - no real need to correct for reg-domain;
if (s.channelSet.contains("A")) currentChannelCount += (9 - 1);
if (s.channelSet.contains("B")) currentChannelCount += (11 - 1);
}
if (s.scanIntervalSec == BatchedScanSettings.UNSPECIFIED) {
currentScanInterval = BatchedScanSettings.DEFAULT_INTERVAL_SEC;
} else {
currentScanInterval = s.scanIntervalSec;
}
currentCsph = 60 * 60 * currentChannelCount / currentScanInterval;
if (currentCsph > responsibleCsph) {
responsibleUid = r.uid;
responsibleWorkSource = r.workSource;
responsibleCsph = currentCsph;
}
if (s.maxScansPerBatch != BatchedScanSettings.UNSPECIFIED &&
s.maxScansPerBatch < setting.maxScansPerBatch) {
setting.maxScansPerBatch = s.maxScansPerBatch;
responsibleUid = r.uid;
}
if (s.maxApPerScan != BatchedScanSettings.UNSPECIFIED &&
(setting.maxApPerScan == BatchedScanSettings.UNSPECIFIED ||
@ -489,7 +528,6 @@ public final class WifiService extends IWifiManager.Stub {
if (s.scanIntervalSec != BatchedScanSettings.UNSPECIFIED &&
s.scanIntervalSec < setting.scanIntervalSec) {
setting.scanIntervalSec = s.scanIntervalSec;
responsibleUid = r.uid;
}
if (s.maxApForDistance != BatchedScanSettings.UNSPECIFIED &&
(setting.maxApForDistance == BatchedScanSettings.UNSPECIFIED ||
@ -511,7 +549,8 @@ public final class WifiService extends IWifiManager.Stub {
}
setting.constrain();
mWifiStateMachine.setBatchedScanSettings(setting, responsibleUid);
mWifiStateMachine.setBatchedScanSettings(setting, responsibleUid, (int)responsibleCsph,
responsibleWorkSource);
}
private void enforceAccessPermission() {

View File

@ -117,7 +117,7 @@ interface IWifiManager
void enableTdlsWithMacAddress(String remoteMacAddress, boolean enable);
boolean requestBatchedScan(in BatchedScanSettings requested, IBinder binder);
boolean requestBatchedScan(in BatchedScanSettings requested, IBinder binder, in WorkSource ws);
void stopBatchedScan(in BatchedScanSettings requested);

View File

@ -799,7 +799,13 @@ public class WifiManager {
*/
public boolean requestBatchedScan(BatchedScanSettings requested) {
try {
return mService.requestBatchedScan(requested, new Binder());
return mService.requestBatchedScan(requested, new Binder(), null);
} catch (RemoteException e) { return false; }
}
/** @hide */
public boolean requestBatchedScan(BatchedScanSettings requested, WorkSource workSource) {
try {
return mService.requestBatchedScan(requested, new Binder(), workSource);
} catch (RemoteException e) { return false; }
}

View File

@ -39,7 +39,6 @@ import java.util.Locale;
public class WifiNative {
private static final boolean DBG = false;
private static final boolean VDBG = false;
private final String mTAG;
private static final int DEFAULT_GROUP_OWNER_INTENT = 6;
@ -118,12 +117,12 @@ public class WifiNative {
public boolean connectToSupplicant() {
// No synchronization necessary .. it is implemented in WifiMonitor
if (VDBG) localLog(mInterfacePrefix + "connectToSupplicant");
localLog(mInterfacePrefix + "connectToSupplicant");
return connectToSupplicantNative();
}
public void closeSupplicantConnection() {
if (VDBG) localLog(mInterfacePrefix + "closeSupplicantConnection");
localLog(mInterfacePrefix + "closeSupplicantConnection");
closeSupplicantConnectionNative();
}
@ -136,9 +135,9 @@ public class WifiNative {
if (DBG) Log.d(mTAG, "doBoolean: " + command);
synchronized (mLock) {
int cmdId = getNewCmdIdLocked();
if (VDBG) localLog(cmdId + "->" + mInterfacePrefix + command);
localLog(cmdId + "->" + mInterfacePrefix + command);
boolean result = doBooleanCommandNative(mInterfacePrefix + command);
if (VDBG) localLog(cmdId + "<-" + result);
localLog(cmdId + "<-" + result);
if (DBG) Log.d(mTAG, " returned " + result);
return result;
}
@ -148,9 +147,9 @@ public class WifiNative {
if (DBG) Log.d(mTAG, "doInt: " + command);
synchronized (mLock) {
int cmdId = getNewCmdIdLocked();
if (VDBG) localLog(cmdId + "->" + mInterfacePrefix + command);
localLog(cmdId + "->" + mInterfacePrefix + command);
int result = doIntCommandNative(mInterfacePrefix + command);
if (VDBG) localLog(cmdId + "<-" + result);
localLog(cmdId + "<-" + result);
if (DBG) Log.d(mTAG, " returned " + result);
return result;
}
@ -160,9 +159,9 @@ public class WifiNative {
if (DBG) Log.d(mTAG, "doString: " + command);
synchronized (mLock) {
int cmdId = getNewCmdIdLocked();
if (VDBG) localLog(cmdId + "->" + mInterfacePrefix + command);
localLog(cmdId + "->" + mInterfacePrefix + command);
String result = doStringCommandNative(mInterfacePrefix + command);
if (VDBG) localLog(cmdId + "<-" + result);
localLog(cmdId + "<-" + result);
if (DBG) Log.d(mTAG, " returned " + result);
return result;
}
@ -298,7 +297,9 @@ public class WifiNative {
* the firmware can remember before it runs out of buffer space or -1 on error
*/
public String setBatchedScanSettings(BatchedScanSettings settings) {
if (settings == null) return doStringCommand("DRIVER WLS_BATCHING STOP");
if (settings == null) {
return doStringCommand("DRIVER WLS_BATCHING STOP");
}
String cmd = "DRIVER WLS_BATCHING SET SCANFREQ=" + settings.scanIntervalSec;
cmd += " MSCAN=" + settings.maxScansPerBatch;
if (settings.maxApPerScan != BatchedScanSettings.UNSPECIFIED) {

View File

@ -57,6 +57,7 @@ import android.net.wifi.p2p.WifiP2pManager;
import android.net.wifi.p2p.WifiP2pService;
import android.os.BatteryStats;
import android.os.Binder;
import android.os.Bundle;
import android.os.IBinder;
import android.os.INetworkManagementService;
import android.os.Message;
@ -416,7 +417,8 @@ public class WifiStateMachine extends StateMachine {
/* change the batch scan settings.
* arg1 = responsible UID
* obj = the new settings
* arg2 = csph (channel scans per hour)
* obj = bundle with the new settings and the optional worksource
*/
public static final int CMD_SET_BATCHED_SCAN = BASE + 135;
public static final int CMD_START_NEXT_BATCHED_SCAN = BASE + 136;
@ -628,6 +630,15 @@ public class WifiStateMachine extends StateMachine {
private BatchedScanSettings mBatchedScanSettings = null;
/**
* Track the worksource/cost of the current settings and track what's been noted
* to the battery stats, so we can mark the end of the previous when changing.
*/
private WorkSource mBatchedScanWorkSource = null;
private int mBatchedScanCsph = 0;
private WorkSource mNotedBatchedScanWorkSource = null;
private int mNotedBatchedScanCsph = 0;
public WifiStateMachine(Context context, String wlanInterface) {
super("WifiStateMachine");
@ -841,8 +852,14 @@ public class WifiStateMachine extends StateMachine {
/**
* start or stop batched scanning using the given settings
*/
public void setBatchedScanSettings(BatchedScanSettings settings, int callingUid) {
sendMessage(CMD_SET_BATCHED_SCAN, callingUid, 0, settings);
private static final String BATCHED_SETTING = "batched_settings";
private static final String BATCHED_WORKSOURCE = "batched_worksource";
public void setBatchedScanSettings(BatchedScanSettings settings, int callingUid, int csph,
WorkSource workSource) {
Bundle bundle = new Bundle();
bundle.putParcelable(BATCHED_SETTING, settings);
bundle.putParcelable(BATCHED_WORKSOURCE, workSource);
sendMessage(CMD_SET_BATCHED_SCAN, callingUid, csph, bundle);
}
public List<BatchedScanResult> syncGetBatchedScanResultsList() {
@ -861,6 +878,8 @@ public class WifiStateMachine extends StateMachine {
}
private void startBatchedScan() {
if (mBatchedScanSettings == null) return;
if (mDhcpActive) {
if (DBG) log("not starting Batched Scans due to DHCP");
return;
@ -872,10 +891,10 @@ public class WifiStateMachine extends StateMachine {
mAlarmManager.cancel(mBatchedScanIntervalIntent);
String scansExpected = mWifiNative.setBatchedScanSettings(mBatchedScanSettings);
try {
mExpectedBatchedScans = Integer.parseInt(scansExpected);
setNextBatchedAlarm(mExpectedBatchedScans);
if (mExpectedBatchedScans > 0) noteBatchedScanStart();
} catch (NumberFormatException e) {
stopBatchedScan();
loge("Exception parsing WifiNative.setBatchedScanSettings response " + e);
@ -918,25 +937,31 @@ public class WifiStateMachine extends StateMachine {
}
// return true if new/different
private boolean recordBatchedScanSettings(BatchedScanSettings settings) {
if (DBG) log("set batched scan to " + settings);
private boolean recordBatchedScanSettings(int responsibleUid, int csph, Bundle bundle) {
BatchedScanSettings settings = bundle.getParcelable(BATCHED_SETTING);
WorkSource responsibleWorkSource = bundle.getParcelable(BATCHED_WORKSOURCE);
if (DBG) {
log("set batched scan to " + settings + " for uid=" + responsibleUid +
", worksource=" + responsibleWorkSource);
}
if (settings != null) {
// TODO - noteBatchedScanStart(message.arg1);
if (settings.equals(mBatchedScanSettings)) return false;
} else {
if (mBatchedScanSettings == null) return false;
// TODO - noteBatchedScanStop(message.arg1);
}
mBatchedScanSettings = settings;
if (responsibleWorkSource == null) responsibleWorkSource = new WorkSource(responsibleUid);
mBatchedScanWorkSource = responsibleWorkSource;
mBatchedScanCsph = csph;
return true;
}
private void stopBatchedScan() {
mAlarmManager.cancel(mBatchedScanIntervalIntent);
if (mBatchedScanSettings != null) {
retrieveBatchedScanData();
mWifiNative.setBatchedScanSettings(null);
}
retrieveBatchedScanData();
mWifiNative.setBatchedScanSettings(null);
noteBatchedScanStop();
}
private void setNextBatchedAlarm(int scansExpected) {
@ -1164,6 +1189,44 @@ public class WifiStateMachine extends StateMachine {
}
}
private void noteBatchedScanStart() {
// note the end of a previous scan set
if (mNotedBatchedScanWorkSource != null &&
(mNotedBatchedScanWorkSource.equals(mBatchedScanWorkSource) == false ||
mNotedBatchedScanCsph != mBatchedScanCsph)) {
try {
mBatteryStats.noteWifiBatchedScanStoppedFromSource(mNotedBatchedScanWorkSource);
} catch (RemoteException e) {
log(e.toString());
} finally {
mNotedBatchedScanWorkSource = null;
mNotedBatchedScanCsph = 0;
}
}
// note the start of the new
try {
mBatteryStats.noteWifiBatchedScanStartedFromSource(mBatchedScanWorkSource,
mBatchedScanCsph);
mNotedBatchedScanWorkSource = mBatchedScanWorkSource;
mNotedBatchedScanCsph = mBatchedScanCsph;
} catch (RemoteException e) {
log(e.toString());
}
}
private void noteBatchedScanStop() {
if (mNotedBatchedScanWorkSource != null) {
try {
mBatteryStats.noteWifiBatchedScanStoppedFromSource(mNotedBatchedScanWorkSource);
} catch (RemoteException e) {
log(e.toString());
} finally {
mNotedBatchedScanWorkSource = null;
mNotedBatchedScanCsph = 0;
}
}
}
private void startScanNative(int type) {
mWifiNative.scan(type);
mScanResultIsPending = true;
@ -1868,6 +1931,9 @@ public class WifiStateMachine extends StateMachine {
return;
}
// note that all these splits and substrings keep references to the original
// huge string buffer while the amount we really want is generally pretty small
// so make copies instead (one example b/11087956 wasted 400k of heap here).
synchronized(mScanResultCache) {
mScanResults = new ArrayList<ScanResult>();
String[] lines = scanResults.split("\n");
@ -2307,9 +2373,7 @@ public class WifiStateMachine extends StateMachine {
mDhcpActive = false;
if (mBatchedScanSettings != null) {
startBatchedScan();
}
startBatchedScan();
}
private void handleSuccessfulIpConfiguration(DhcpResults dhcpResults) {
@ -2447,7 +2511,7 @@ public class WifiStateMachine extends StateMachine {
}
break;
case CMD_SET_BATCHED_SCAN:
recordBatchedScanSettings((BatchedScanSettings)message.obj);
recordBatchedScanSettings(message.arg1, message.arg2, (Bundle)message.obj);
break;
case CMD_POLL_BATCHED_SCAN:
handleBatchedScanPollRequest();
@ -2960,9 +3024,7 @@ public class WifiStateMachine extends StateMachine {
mDhcpActive = false;
if (mBatchedScanSettings != null) {
startBatchedScan();
}
startBatchedScan();
if (mOperationalMode != CONNECT_MODE) {
mWifiNative.disconnect();
@ -3021,8 +3083,10 @@ public class WifiStateMachine extends StateMachine {
startScanNative(WifiNative.SCAN_WITH_CONNECTION_SETUP);
break;
case CMD_SET_BATCHED_SCAN:
recordBatchedScanSettings((BatchedScanSettings)message.obj);
startBatchedScan();
if (recordBatchedScanSettings(message.arg1, message.arg2,
(Bundle)message.obj)) {
startBatchedScan();
}
break;
case CMD_SET_COUNTRY_CODE:
String country = (String) message.obj;
@ -3160,9 +3224,7 @@ public class WifiStateMachine extends StateMachine {
updateBatteryWorkSource(null);
mScanResults = new ArrayList<ScanResult>();
if (mBatchedScanSettings != null) {
stopBatchedScan();
}
stopBatchedScan();
final Intent intent = new Intent(WifiManager.WIFI_SCAN_AVAILABLE);
intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);