summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRobert Greenwalt <rgreenwalt@google.com>2013-11-07 10:39:43 -0800
committerAndroid Git Automerger <android-git-automerger@android.com>2013-11-07 10:39:43 -0800
commitc3eef19047b897bfb6e3cf42220d5146b187c66e (patch)
treed790ba2a57195512e0c264ff77e950a12cbe51f0
parent03be79b35ca7060f383075a43ff19c8a9d63a7c0 (diff)
parentf1612bcfdd2cb517948f14369fd0977ceb55d19c (diff)
downloadframeworks_base-c3eef19047b897bfb6e3cf42220d5146b187c66e.zip
frameworks_base-c3eef19047b897bfb6e3cf42220d5146b187c66e.tar.gz
frameworks_base-c3eef19047b897bfb6e3cf42220d5146b187c66e.tar.bz2
am f1612bcf: am e8c51298: Merge "Add BatteryStats for Wifi Batched Scanning." into klp-dev
* commit 'f1612bcfdd2cb517948f14369fd0977ceb55d19c': Add BatteryStats for Wifi Batched Scanning.
-rw-r--r--core/java/android/os/BatteryStats.java18
-rw-r--r--core/java/com/android/internal/app/IBatteryStats.aidl2
-rw-r--r--core/java/com/android/internal/os/BatteryStatsImpl.java131
-rw-r--r--core/java/com/android/internal/os/PowerProfile.java9
-rw-r--r--core/res/res/xml/power_profile.xml8
-rw-r--r--services/java/com/android/server/am/BatteryStatsService.java14
-rw-r--r--services/java/com/android/server/wifi/WifiService.java59
-rw-r--r--wifi/java/android/net/wifi/IWifiManager.aidl2
-rw-r--r--wifi/java/android/net/wifi/WifiManager.java8
-rw-r--r--wifi/java/android/net/wifi/WifiNative.java21
-rw-r--r--wifi/java/android/net/wifi/WifiStateMachine.java110
11 files changed, 332 insertions, 50 deletions
diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java
index 447c985..b1a9ea3 100644
--- a/core/java/android/os/BatteryStats.java
+++ b/core/java/android/os/BatteryStats.java
@@ -106,6 +106,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.
*/
public static final int STATS_SINCE_CHARGED = 0;
@@ -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;
diff --git a/core/java/com/android/internal/app/IBatteryStats.aidl b/core/java/com/android/internal/app/IBatteryStats.aidl
index 525517c..43c4b49 100644
--- a/core/java/com/android/internal/app/IBatteryStats.aidl
+++ b/core/java/com/android/internal/app/IBatteryStats.aidl
@@ -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);
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index da12d91..2e5fcec 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -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);
}
@@ -2719,6 +2748,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) {
mWifiMulticastEnabled = true;
@@ -2854,6 +2913,15 @@ public final class BatteryStatsImpl extends BatteryStats {
}
@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) {
return 0;
@@ -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();
diff --git a/core/java/com/android/internal/os/PowerProfile.java b/core/java/com/android/internal/os/PowerProfile.java
index 99a6843..94750d3 100644
--- a/core/java/com/android/internal/os/PowerProfile.java
+++ b/core/java/com/android/internal/os/PowerProfile.java
@@ -136,6 +136,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).
*/
public static final String POWER_BATTERY_CAPACITY = "battery.capacity";
@@ -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()]));
diff --git a/core/res/res/xml/power_profile.xml b/core/res/res/xml/power_profile.xml
index 7af3b9c..3215e17 100644
--- a/core/res/res/xml/power_profile.xml
+++ b/core/res/res/xml/power_profile.xml
@@ -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>
diff --git a/services/java/com/android/server/am/BatteryStatsService.java b/services/java/com/android/server/am/BatteryStatsService.java
index 0dd950e..2d59678 100644
--- a/services/java/com/android/server/am/BatteryStatsService.java
+++ b/services/java/com/android/server/am/BatteryStatsService.java
@@ -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) {
diff --git a/services/java/com/android/server/wifi/WifiService.java b/services/java/com/android/server/wifi/WifiService.java
index d471b57..f2efde1 100644
--- a/services/java/com/android/server/wifi/WifiService.java
+++ b/services/java/com/android/server/wifi/WifiService.java
@@ -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() {
diff --git a/wifi/java/android/net/wifi/IWifiManager.aidl b/wifi/java/android/net/wifi/IWifiManager.aidl
index 5a1928c..149bda6 100644
--- a/wifi/java/android/net/wifi/IWifiManager.aidl
+++ b/wifi/java/android/net/wifi/IWifiManager.aidl
@@ -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);
diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java
index 7fc8bef..3b47e63 100644
--- a/wifi/java/android/net/wifi/WifiManager.java
+++ b/wifi/java/android/net/wifi/WifiManager.java
@@ -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; }
}
diff --git a/wifi/java/android/net/wifi/WifiNative.java b/wifi/java/android/net/wifi/WifiNative.java
index 520668e..c2f278a 100644
--- a/wifi/java/android/net/wifi/WifiNative.java
+++ b/wifi/java/android/net/wifi/WifiNative.java
@@ -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) {
diff --git a/wifi/java/android/net/wifi/WifiStateMachine.java b/wifi/java/android/net/wifi/WifiStateMachine.java
index 78da7e7..eedd66f 100644
--- a/wifi/java/android/net/wifi/WifiStateMachine.java
+++ b/wifi/java/android/net/wifi/WifiStateMachine.java
@@ -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);