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

This commit is contained in:
Robert Greenwalt
2013-11-07 18:30:49 +00:00
committed by Android (Google) Code Review
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; 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. * 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 noteFullWifiLockReleasedLocked();
public abstract void noteWifiScanStartedLocked(); public abstract void noteWifiScanStartedLocked();
public abstract void noteWifiScanStoppedLocked(); public abstract void noteWifiScanStoppedLocked();
public abstract void noteWifiBatchedScanStartedLocked(int csph);
public abstract void noteWifiBatchedScanStoppedLocked();
public abstract void noteWifiMulticastEnabledLocked(); public abstract void noteWifiMulticastEnabledLocked();
public abstract void noteWifiMulticastDisabledLocked(); public abstract void noteWifiMulticastDisabledLocked();
public abstract void noteAudioTurnedOnLocked(); 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 getWifiRunningTime(long batteryRealtime, int which);
public abstract long getFullWifiLockTime(long batteryRealtime, int which); public abstract long getFullWifiLockTime(long batteryRealtime, int which);
public abstract long getWifiScanTime(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, public abstract long getWifiMulticastTime(long batteryRealtime,
int which); int which);
public abstract long getAudioTurnedOnTime(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 getForegroundActivityTimer();
public abstract Timer getVibratorOnTimer(); 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. * Note that these must match the constants in android.os.PowerManager.
* Also, if the user activity types change, the BatteryStatsImpl.VERSION must * 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); TimeUtils.formatDuration(ew.usedTime, pw);
pw.print(" over "); pw.print(" over ");
TimeUtils.formatDuration(ew.overTime, pw); TimeUtils.formatDuration(ew.overTime, pw);
pw.print(" ("); if (ew.overTime != 0) {
pw.print((ew.usedTime*100)/ew.overTime); pw.print(" (");
pw.println("%)"); pw.print((ew.usedTime*100)/ew.overTime);
pw.println("%)");
}
} }
} }
uidActivity = true; uidActivity = true;

View File

@ -68,6 +68,8 @@ interface IBatteryStats {
void noteFullWifiLockReleasedFromSource(in WorkSource ws); void noteFullWifiLockReleasedFromSource(in WorkSource ws);
void noteWifiScanStartedFromSource(in WorkSource ws); void noteWifiScanStartedFromSource(in WorkSource ws);
void noteWifiScanStoppedFromSource(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 noteWifiMulticastEnabledFromSource(in WorkSource ws);
void noteWifiMulticastDisabledFromSource(in WorkSource ws); void noteWifiMulticastDisabledFromSource(in WorkSource ws);
void noteNetworkInterfaceType(String iface, int type); 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' private static final int MAGIC = 0xBA757475; // 'BATSTATS'
// Current on-disk Parcel version // 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. // Maximum number of items we will record in the history.
private static final int MAX_HISTORY_ITEMS = 2000; 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> mFullWifiLockTimers = new ArrayList<StopwatchTimer>();
final ArrayList<StopwatchTimer> mWifiMulticastTimers = new ArrayList<StopwatchTimer>(); final ArrayList<StopwatchTimer> mWifiMulticastTimers = new ArrayList<StopwatchTimer>();
final ArrayList<StopwatchTimer> mWifiScanTimers = 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. // Last partial timers we use for distributing CPU usage.
final ArrayList<StopwatchTimer> mLastPartialTimers = new ArrayList<StopwatchTimer>(); final ArrayList<StopwatchTimer> mLastPartialTimers = new ArrayList<StopwatchTimer>();
@ -2404,6 +2406,14 @@ public final class BatteryStatsImpl extends BatteryStats {
getUidStatsLocked(uid).noteWifiScanStoppedLocked(); 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; int mWifiMulticastNesting = 0;
public void noteWifiMulticastEnabledLocked(int uid) { 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) { public void noteWifiMulticastEnabledFromSourceLocked(WorkSource ws) {
int N = ws.size(); int N = ws.size();
for (int i=0; i<N; i++) { for (int i=0; i<N; i++) {
@ -2579,6 +2603,10 @@ public final class BatteryStatsImpl extends BatteryStats {
boolean mWifiScanStarted; boolean mWifiScanStarted;
StopwatchTimer mWifiScanTimer; StopwatchTimer mWifiScanTimer;
private static final int NO_BATCHED_SCAN_STARTED = -1;
int mWifiBatchedScanBinStarted = NO_BATCHED_SCAN_STARTED;
StopwatchTimer[] mWifiBatchedScanTimer;
boolean mWifiMulticastEnabled; boolean mWifiMulticastEnabled;
StopwatchTimer mWifiMulticastTimer; StopwatchTimer mWifiMulticastTimer;
@ -2629,6 +2657,7 @@ public final class BatteryStatsImpl extends BatteryStats {
mFullWifiLockTimers, mUnpluggables); mFullWifiLockTimers, mUnpluggables);
mWifiScanTimer = new StopwatchTimer(Uid.this, WIFI_SCAN, mWifiScanTimer = new StopwatchTimer(Uid.this, WIFI_SCAN,
mWifiScanTimers, mUnpluggables); mWifiScanTimers, mUnpluggables);
mWifiBatchedScanTimer = new StopwatchTimer[NUM_WIFI_BATCHED_SCAN_BINS];
mWifiMulticastTimer = new StopwatchTimer(Uid.this, WIFI_MULTICAST_ENABLED, mWifiMulticastTimer = new StopwatchTimer(Uid.this, WIFI_MULTICAST_ENABLED,
mWifiMulticastTimers, mUnpluggables); 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 @Override
public void noteWifiMulticastEnabledLocked() { public void noteWifiMulticastEnabledLocked() {
if (!mWifiMulticastEnabled) { if (!mWifiMulticastEnabled) {
@ -2853,6 +2912,15 @@ public final class BatteryStatsImpl extends BatteryStats {
return mWifiScanTimer.getTotalTimeLocked(batteryRealtime, which); 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 @Override
public long getWifiMulticastTime(long batteryRealtime, int which) { public long getWifiMulticastTime(long batteryRealtime, int which) {
if (mWifiMulticastTimer == null) { if (mWifiMulticastTimer == null) {
@ -2914,6 +2982,24 @@ public final class BatteryStatsImpl extends BatteryStats {
return mUserActivityCounters[type].getCountLocked(which); 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() { void initUserActivityLocked() {
mUserActivityCounters = new Counter[NUM_USER_ACTIVITY_TYPES]; mUserActivityCounters = new Counter[NUM_USER_ACTIVITY_TYPES];
for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) { 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 |= !mWifiScanTimer.reset(BatteryStatsImpl.this, false);
active |= mWifiScanStarted; 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) { if (mWifiMulticastTimer != null) {
active |= !mWifiMulticastTimer.reset(BatteryStatsImpl.this, false); active |= !mWifiMulticastTimer.reset(BatteryStatsImpl.this, false);
active |= mWifiMulticastEnabled; active |= mWifiMulticastEnabled;
@ -3080,6 +3174,11 @@ public final class BatteryStatsImpl extends BatteryStats {
if (mWifiScanTimer != null) { if (mWifiScanTimer != null) {
mWifiScanTimer.detach(); mWifiScanTimer.detach();
} }
for (int i = 0; i < NUM_WIFI_BATCHED_SCAN_BINS; i++) {
if (mWifiBatchedScanTimer[i] != null) {
mWifiBatchedScanTimer[i].detach();
}
}
if (mWifiMulticastTimer != null) { if (mWifiMulticastTimer != null) {
mWifiMulticastTimer.detach(); mWifiMulticastTimer.detach();
} }
@ -3157,6 +3256,14 @@ public final class BatteryStatsImpl extends BatteryStats {
} else { } else {
out.writeInt(0); 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) { if (mWifiMulticastTimer != null) {
out.writeInt(1); out.writeInt(1);
mWifiMulticastTimer.writeToParcel(out, batteryRealtime); mWifiMulticastTimer.writeToParcel(out, batteryRealtime);
@ -3266,6 +3373,14 @@ public final class BatteryStatsImpl extends BatteryStats {
} else { } else {
mWifiScanTimer = null; 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; mWifiMulticastEnabled = false;
if (in.readInt() != 0) { if (in.readInt() != 0) {
mWifiMulticastTimer = new StopwatchTimer(Uid.this, WIFI_MULTICAST_ENABLED, mWifiMulticastTimer = new StopwatchTimer(Uid.this, WIFI_MULTICAST_ENABLED,
@ -5463,6 +5578,13 @@ public final class BatteryStatsImpl extends BatteryStats {
if (in.readInt() != 0) { if (in.readInt() != 0) {
u.mWifiScanTimer.readSummaryFromParcelLocked(in); 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; u.mWifiMulticastEnabled = false;
if (in.readInt() != 0) { if (in.readInt() != 0) {
u.mWifiMulticastTimer.readSummaryFromParcelLocked(in); u.mWifiMulticastTimer.readSummaryFromParcelLocked(in);
@ -5674,6 +5796,14 @@ public final class BatteryStatsImpl extends BatteryStats {
} else { } else {
out.writeInt(0); 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) { if (u.mWifiMulticastTimer != null) {
out.writeInt(1); out.writeInt(1);
u.mWifiMulticastTimer.writeSummaryFromParcelLocked(out, NOWREAL); u.mWifiMulticastTimer.writeSummaryFromParcelLocked(out, NOWREAL);
@ -5909,6 +6039,7 @@ public final class BatteryStatsImpl extends BatteryStats {
mWifiRunningTimers.clear(); mWifiRunningTimers.clear();
mFullWifiLockTimers.clear(); mFullWifiLockTimers.clear();
mWifiScanTimers.clear(); mWifiScanTimers.clear();
mWifiBatchedScanTimers.clear();
mWifiMulticastTimers.clear(); mWifiMulticastTimers.clear();
sNumSpeedSteps = in.readInt(); sNumSpeedSteps = in.readInt();

View File

@ -135,6 +135,13 @@ public class PowerProfile {
public static final String POWER_CPU_SPEEDS = "cpu.speeds"; 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). * Battery capacity in milliAmpHour (mAh).
*/ */
@ -171,7 +178,7 @@ public class PowerProfile {
String element = parser.getName(); String element = parser.getName();
if (element == null) break; if (element == null) break;
if (parsingArray && !element.equals(TAG_ARRAYITEM)) { if (parsingArray && !element.equals(TAG_ARRAYITEM)) {
// Finish array // Finish array
sPowerMap.put(arrayName, array.toArray(new Double[array.size()])); sPowerMap.put(arrayName, array.toArray(new Double[array.size()]));

View File

@ -58,4 +58,12 @@
</array> </array>
<!-- This is the battery capacity in mAh (measured at nominal voltage) --> <!-- This is the battery capacity in mAh (measured at nominal voltage) -->
<item name="battery.capacity">1000</item> <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> </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) { public void noteWifiMulticastEnabledFromSource(WorkSource ws) {
enforceCallingPermission(); enforceCallingPermission();
synchronized (mStats) { synchronized (mStats) {

View File

@ -369,15 +369,17 @@ public final class WifiService extends IWifiManager.Stub {
} }
private class BatchedScanRequest extends DeathRecipient { private class BatchedScanRequest extends DeathRecipient {
BatchedScanSettings settings; final BatchedScanSettings settings;
int uid; final int uid;
int pid; final int pid;
final WorkSource workSource;
BatchedScanRequest(BatchedScanSettings settings, IBinder binder) { BatchedScanRequest(BatchedScanSettings settings, IBinder binder, WorkSource ws) {
super(0, null, binder, null); super(0, null, binder, null);
this.settings = settings; this.settings = settings;
this.uid = getCallingUid(); this.uid = getCallingUid();
this.pid = getCallingPid(); this.pid = getCallingPid();
workSource = ws;
} }
public void binderDied() { public void binderDied() {
stopBatchedScan(settings, uid, pid); stopBatchedScan(settings, uid, pid);
@ -406,12 +408,19 @@ public final class WifiService extends IWifiManager.Stub {
/** /**
* see {@link android.net.wifi.WifiManager#requestBatchedScan()} * see {@link android.net.wifi.WifiManager#requestBatchedScan()}
*/ */
public boolean requestBatchedScan(BatchedScanSettings requested, IBinder binder) { public boolean requestBatchedScan(BatchedScanSettings requested, IBinder binder,
WorkSource workSource) {
enforceChangePermission(); 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; if (mBatchedScanSupported == false) return false;
requested = new BatchedScanSettings(requested); requested = new BatchedScanSettings(requested);
if (requested.isInvalid()) return false; if (requested.isInvalid()) return false;
BatchedScanRequest r = new BatchedScanRequest(requested, binder); BatchedScanRequest r = new BatchedScanRequest(requested, binder, workSource);
synchronized(mBatchedScanners) { synchronized(mBatchedScanners) {
mBatchedScanners.add(r); mBatchedScanners.add(r);
resolveBatchedScannersLocked(); resolveBatchedScannersLocked();
@ -468,18 +477,48 @@ public final class WifiService extends IWifiManager.Stub {
private void resolveBatchedScannersLocked() { private void resolveBatchedScannersLocked() {
BatchedScanSettings setting = new BatchedScanSettings(); BatchedScanSettings setting = new BatchedScanSettings();
WorkSource responsibleWorkSource = null;
int responsibleUid = 0; int responsibleUid = 0;
double responsibleCsph = 0; // Channel Scans Per Hour
if (mBatchedScanners.size() == 0) { if (mBatchedScanners.size() == 0) {
mWifiStateMachine.setBatchedScanSettings(null, 0); mWifiStateMachine.setBatchedScanSettings(null, 0, 0, null);
return; return;
} }
for (BatchedScanRequest r : mBatchedScanners) { for (BatchedScanRequest r : mBatchedScanners) {
BatchedScanSettings s = r.settings; 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 && if (s.maxScansPerBatch != BatchedScanSettings.UNSPECIFIED &&
s.maxScansPerBatch < setting.maxScansPerBatch) { s.maxScansPerBatch < setting.maxScansPerBatch) {
setting.maxScansPerBatch = s.maxScansPerBatch; setting.maxScansPerBatch = s.maxScansPerBatch;
responsibleUid = r.uid;
} }
if (s.maxApPerScan != BatchedScanSettings.UNSPECIFIED && if (s.maxApPerScan != BatchedScanSettings.UNSPECIFIED &&
(setting.maxApPerScan == BatchedScanSettings.UNSPECIFIED || (setting.maxApPerScan == BatchedScanSettings.UNSPECIFIED ||
@ -489,7 +528,6 @@ public final class WifiService extends IWifiManager.Stub {
if (s.scanIntervalSec != BatchedScanSettings.UNSPECIFIED && if (s.scanIntervalSec != BatchedScanSettings.UNSPECIFIED &&
s.scanIntervalSec < setting.scanIntervalSec) { s.scanIntervalSec < setting.scanIntervalSec) {
setting.scanIntervalSec = s.scanIntervalSec; setting.scanIntervalSec = s.scanIntervalSec;
responsibleUid = r.uid;
} }
if (s.maxApForDistance != BatchedScanSettings.UNSPECIFIED && if (s.maxApForDistance != BatchedScanSettings.UNSPECIFIED &&
(setting.maxApForDistance == BatchedScanSettings.UNSPECIFIED || (setting.maxApForDistance == BatchedScanSettings.UNSPECIFIED ||
@ -511,7 +549,8 @@ public final class WifiService extends IWifiManager.Stub {
} }
setting.constrain(); setting.constrain();
mWifiStateMachine.setBatchedScanSettings(setting, responsibleUid); mWifiStateMachine.setBatchedScanSettings(setting, responsibleUid, (int)responsibleCsph,
responsibleWorkSource);
} }
private void enforceAccessPermission() { private void enforceAccessPermission() {

View File

@ -117,7 +117,7 @@ interface IWifiManager
void enableTdlsWithMacAddress(String remoteMacAddress, boolean enable); 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); void stopBatchedScan(in BatchedScanSettings requested);

View File

@ -799,7 +799,13 @@ public class WifiManager {
*/ */
public boolean requestBatchedScan(BatchedScanSettings requested) { public boolean requestBatchedScan(BatchedScanSettings requested) {
try { 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; } } catch (RemoteException e) { return false; }
} }

View File

@ -39,7 +39,6 @@ import java.util.Locale;
public class WifiNative { public class WifiNative {
private static final boolean DBG = false; private static final boolean DBG = false;
private static final boolean VDBG = false;
private final String mTAG; private final String mTAG;
private static final int DEFAULT_GROUP_OWNER_INTENT = 6; private static final int DEFAULT_GROUP_OWNER_INTENT = 6;
@ -118,12 +117,12 @@ public class WifiNative {
public boolean connectToSupplicant() { public boolean connectToSupplicant() {
// No synchronization necessary .. it is implemented in WifiMonitor // No synchronization necessary .. it is implemented in WifiMonitor
if (VDBG) localLog(mInterfacePrefix + "connectToSupplicant"); localLog(mInterfacePrefix + "connectToSupplicant");
return connectToSupplicantNative(); return connectToSupplicantNative();
} }
public void closeSupplicantConnection() { public void closeSupplicantConnection() {
if (VDBG) localLog(mInterfacePrefix + "closeSupplicantConnection"); localLog(mInterfacePrefix + "closeSupplicantConnection");
closeSupplicantConnectionNative(); closeSupplicantConnectionNative();
} }
@ -136,9 +135,9 @@ public class WifiNative {
if (DBG) Log.d(mTAG, "doBoolean: " + command); if (DBG) Log.d(mTAG, "doBoolean: " + command);
synchronized (mLock) { synchronized (mLock) {
int cmdId = getNewCmdIdLocked(); int cmdId = getNewCmdIdLocked();
if (VDBG) localLog(cmdId + "->" + mInterfacePrefix + command); localLog(cmdId + "->" + mInterfacePrefix + command);
boolean result = doBooleanCommandNative(mInterfacePrefix + command); boolean result = doBooleanCommandNative(mInterfacePrefix + command);
if (VDBG) localLog(cmdId + "<-" + result); localLog(cmdId + "<-" + result);
if (DBG) Log.d(mTAG, " returned " + result); if (DBG) Log.d(mTAG, " returned " + result);
return result; return result;
} }
@ -148,9 +147,9 @@ public class WifiNative {
if (DBG) Log.d(mTAG, "doInt: " + command); if (DBG) Log.d(mTAG, "doInt: " + command);
synchronized (mLock) { synchronized (mLock) {
int cmdId = getNewCmdIdLocked(); int cmdId = getNewCmdIdLocked();
if (VDBG) localLog(cmdId + "->" + mInterfacePrefix + command); localLog(cmdId + "->" + mInterfacePrefix + command);
int result = doIntCommandNative(mInterfacePrefix + command); int result = doIntCommandNative(mInterfacePrefix + command);
if (VDBG) localLog(cmdId + "<-" + result); localLog(cmdId + "<-" + result);
if (DBG) Log.d(mTAG, " returned " + result); if (DBG) Log.d(mTAG, " returned " + result);
return result; return result;
} }
@ -160,9 +159,9 @@ public class WifiNative {
if (DBG) Log.d(mTAG, "doString: " + command); if (DBG) Log.d(mTAG, "doString: " + command);
synchronized (mLock) { synchronized (mLock) {
int cmdId = getNewCmdIdLocked(); int cmdId = getNewCmdIdLocked();
if (VDBG) localLog(cmdId + "->" + mInterfacePrefix + command); localLog(cmdId + "->" + mInterfacePrefix + command);
String result = doStringCommandNative(mInterfacePrefix + command); String result = doStringCommandNative(mInterfacePrefix + command);
if (VDBG) localLog(cmdId + "<-" + result); localLog(cmdId + "<-" + result);
if (DBG) Log.d(mTAG, " returned " + result); if (DBG) Log.d(mTAG, " returned " + result);
return 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 * the firmware can remember before it runs out of buffer space or -1 on error
*/ */
public String setBatchedScanSettings(BatchedScanSettings settings) { 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; String cmd = "DRIVER WLS_BATCHING SET SCANFREQ=" + settings.scanIntervalSec;
cmd += " MSCAN=" + settings.maxScansPerBatch; cmd += " MSCAN=" + settings.maxScansPerBatch;
if (settings.maxApPerScan != BatchedScanSettings.UNSPECIFIED) { 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.net.wifi.p2p.WifiP2pService;
import android.os.BatteryStats; import android.os.BatteryStats;
import android.os.Binder; import android.os.Binder;
import android.os.Bundle;
import android.os.IBinder; import android.os.IBinder;
import android.os.INetworkManagementService; import android.os.INetworkManagementService;
import android.os.Message; import android.os.Message;
@ -416,7 +417,8 @@ public class WifiStateMachine extends StateMachine {
/* change the batch scan settings. /* change the batch scan settings.
* arg1 = responsible UID * 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_SET_BATCHED_SCAN = BASE + 135;
public static final int CMD_START_NEXT_BATCHED_SCAN = BASE + 136; public static final int CMD_START_NEXT_BATCHED_SCAN = BASE + 136;
@ -628,6 +630,15 @@ public class WifiStateMachine extends StateMachine {
private BatchedScanSettings mBatchedScanSettings = null; 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) { public WifiStateMachine(Context context, String wlanInterface) {
super("WifiStateMachine"); super("WifiStateMachine");
@ -841,8 +852,14 @@ public class WifiStateMachine extends StateMachine {
/** /**
* start or stop batched scanning using the given settings * start or stop batched scanning using the given settings
*/ */
public void setBatchedScanSettings(BatchedScanSettings settings, int callingUid) { private static final String BATCHED_SETTING = "batched_settings";
sendMessage(CMD_SET_BATCHED_SCAN, callingUid, 0, 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() { public List<BatchedScanResult> syncGetBatchedScanResultsList() {
@ -861,6 +878,8 @@ public class WifiStateMachine extends StateMachine {
} }
private void startBatchedScan() { private void startBatchedScan() {
if (mBatchedScanSettings == null) return;
if (mDhcpActive) { if (mDhcpActive) {
if (DBG) log("not starting Batched Scans due to DHCP"); if (DBG) log("not starting Batched Scans due to DHCP");
return; return;
@ -872,10 +891,10 @@ public class WifiStateMachine extends StateMachine {
mAlarmManager.cancel(mBatchedScanIntervalIntent); mAlarmManager.cancel(mBatchedScanIntervalIntent);
String scansExpected = mWifiNative.setBatchedScanSettings(mBatchedScanSettings); String scansExpected = mWifiNative.setBatchedScanSettings(mBatchedScanSettings);
try { try {
mExpectedBatchedScans = Integer.parseInt(scansExpected); mExpectedBatchedScans = Integer.parseInt(scansExpected);
setNextBatchedAlarm(mExpectedBatchedScans); setNextBatchedAlarm(mExpectedBatchedScans);
if (mExpectedBatchedScans > 0) noteBatchedScanStart();
} catch (NumberFormatException e) { } catch (NumberFormatException e) {
stopBatchedScan(); stopBatchedScan();
loge("Exception parsing WifiNative.setBatchedScanSettings response " + e); loge("Exception parsing WifiNative.setBatchedScanSettings response " + e);
@ -918,25 +937,31 @@ public class WifiStateMachine extends StateMachine {
} }
// return true if new/different // return true if new/different
private boolean recordBatchedScanSettings(BatchedScanSettings settings) { private boolean recordBatchedScanSettings(int responsibleUid, int csph, Bundle bundle) {
if (DBG) log("set batched scan to " + settings); 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) { if (settings != null) {
// TODO - noteBatchedScanStart(message.arg1);
if (settings.equals(mBatchedScanSettings)) return false; if (settings.equals(mBatchedScanSettings)) return false;
} else { } else {
if (mBatchedScanSettings == null) return false; if (mBatchedScanSettings == null) return false;
// TODO - noteBatchedScanStop(message.arg1);
} }
mBatchedScanSettings = settings; mBatchedScanSettings = settings;
if (responsibleWorkSource == null) responsibleWorkSource = new WorkSource(responsibleUid);
mBatchedScanWorkSource = responsibleWorkSource;
mBatchedScanCsph = csph;
return true; return true;
} }
private void stopBatchedScan() { private void stopBatchedScan() {
mAlarmManager.cancel(mBatchedScanIntervalIntent); mAlarmManager.cancel(mBatchedScanIntervalIntent);
if (mBatchedScanSettings != null) { retrieveBatchedScanData();
retrieveBatchedScanData(); mWifiNative.setBatchedScanSettings(null);
mWifiNative.setBatchedScanSettings(null); noteBatchedScanStop();
}
} }
private void setNextBatchedAlarm(int scansExpected) { 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) { private void startScanNative(int type) {
mWifiNative.scan(type); mWifiNative.scan(type);
mScanResultIsPending = true; mScanResultIsPending = true;
@ -1868,6 +1931,9 @@ public class WifiStateMachine extends StateMachine {
return; 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) { synchronized(mScanResultCache) {
mScanResults = new ArrayList<ScanResult>(); mScanResults = new ArrayList<ScanResult>();
String[] lines = scanResults.split("\n"); String[] lines = scanResults.split("\n");
@ -2307,9 +2373,7 @@ public class WifiStateMachine extends StateMachine {
mDhcpActive = false; mDhcpActive = false;
if (mBatchedScanSettings != null) { startBatchedScan();
startBatchedScan();
}
} }
private void handleSuccessfulIpConfiguration(DhcpResults dhcpResults) { private void handleSuccessfulIpConfiguration(DhcpResults dhcpResults) {
@ -2447,7 +2511,7 @@ public class WifiStateMachine extends StateMachine {
} }
break; break;
case CMD_SET_BATCHED_SCAN: case CMD_SET_BATCHED_SCAN:
recordBatchedScanSettings((BatchedScanSettings)message.obj); recordBatchedScanSettings(message.arg1, message.arg2, (Bundle)message.obj);
break; break;
case CMD_POLL_BATCHED_SCAN: case CMD_POLL_BATCHED_SCAN:
handleBatchedScanPollRequest(); handleBatchedScanPollRequest();
@ -2960,9 +3024,7 @@ public class WifiStateMachine extends StateMachine {
mDhcpActive = false; mDhcpActive = false;
if (mBatchedScanSettings != null) { startBatchedScan();
startBatchedScan();
}
if (mOperationalMode != CONNECT_MODE) { if (mOperationalMode != CONNECT_MODE) {
mWifiNative.disconnect(); mWifiNative.disconnect();
@ -3021,8 +3083,10 @@ public class WifiStateMachine extends StateMachine {
startScanNative(WifiNative.SCAN_WITH_CONNECTION_SETUP); startScanNative(WifiNative.SCAN_WITH_CONNECTION_SETUP);
break; break;
case CMD_SET_BATCHED_SCAN: case CMD_SET_BATCHED_SCAN:
recordBatchedScanSettings((BatchedScanSettings)message.obj); if (recordBatchedScanSettings(message.arg1, message.arg2,
startBatchedScan(); (Bundle)message.obj)) {
startBatchedScan();
}
break; break;
case CMD_SET_COUNTRY_CODE: case CMD_SET_COUNTRY_CODE:
String country = (String) message.obj; String country = (String) message.obj;
@ -3160,9 +3224,7 @@ public class WifiStateMachine extends StateMachine {
updateBatteryWorkSource(null); updateBatteryWorkSource(null);
mScanResults = new ArrayList<ScanResult>(); mScanResults = new ArrayList<ScanResult>();
if (mBatchedScanSettings != null) { stopBatchedScan();
stopBatchedScan();
}
final Intent intent = new Intent(WifiManager.WIFI_SCAN_AVAILABLE); final Intent intent = new Intent(WifiManager.WIFI_SCAN_AVAILABLE);
intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);