summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/com/android/internal/os/BatteryStatsImpl.java159
-rw-r--r--core/tests/coretests/src/com/android/internal/os/BatteryStatsBackgroundStatsTest.java59
2 files changed, 191 insertions, 27 deletions
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index 95513ff421cb..fe778e36a306 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -5274,8 +5274,9 @@ public class BatteryStatsImpl extends BatteryStats {
}
}
- private void noteBluetoothScanStartedLocked(int uid, boolean isUnoptimized) {
- uid = mapUid(uid);
+ private void noteBluetoothScanStartedLocked(WorkChain workChain, int uid,
+ boolean isUnoptimized) {
+ uid = getAttributionUid(uid, workChain);
final long elapsedRealtime = mClocks.elapsedRealtime();
final long uptime = mClocks.uptimeMillis();
if (mBluetoothScanNesting == 0) {
@@ -5286,18 +5287,36 @@ public class BatteryStatsImpl extends BatteryStats {
mBluetoothScanTimer.startRunningLocked(elapsedRealtime);
}
mBluetoothScanNesting++;
+
+ // TODO(statsd): Log WorkChain here if it's non-null.
+ StatsLog.write(StatsLog.BLE_SCAN_STATE_CHANGED, uid, 1);
+ if (isUnoptimized) {
+ StatsLog.write(StatsLog.BLE_UNOPTIMIZED_SCAN_STATE_CHANGED, uid, 1);
+ }
+
getUidStatsLocked(uid).noteBluetoothScanStartedLocked(elapsedRealtime, isUnoptimized);
+ if (workChain != null) {
+ getUidStatsLocked(uid).addBluetoothWorkChain(workChain, isUnoptimized);
+ }
}
public void noteBluetoothScanStartedFromSourceLocked(WorkSource ws, boolean isUnoptimized) {
final int N = ws.size();
for (int i = 0; i < N; i++) {
- noteBluetoothScanStartedLocked(ws.get(i), isUnoptimized);
+ noteBluetoothScanStartedLocked(null, ws.get(i), isUnoptimized);
+ }
+
+ final List<WorkChain> workChains = ws.getWorkChains();
+ if (workChains != null) {
+ for (int i = 0; i < workChains.size(); ++i) {
+ noteBluetoothScanStartedLocked(workChains.get(i), -1, isUnoptimized);
+ }
}
}
- private void noteBluetoothScanStoppedLocked(int uid, boolean isUnoptimized) {
- uid = mapUid(uid);
+ private void noteBluetoothScanStoppedLocked(WorkChain workChain, int uid,
+ boolean isUnoptimized) {
+ uid = getAttributionUid(uid, workChain);
final long elapsedRealtime = mClocks.elapsedRealtime();
final long uptime = mClocks.uptimeMillis();
mBluetoothScanNesting--;
@@ -5308,13 +5327,38 @@ public class BatteryStatsImpl extends BatteryStats {
addHistoryRecordLocked(elapsedRealtime, uptime);
mBluetoothScanTimer.stopRunningLocked(elapsedRealtime);
}
+
+ // TODO(statsd): Log WorkChain here if it's non-null.
+ StatsLog.write(StatsLog.BLE_SCAN_STATE_CHANGED, uid, 0);
+ if (isUnoptimized) {
+ StatsLog.write(StatsLog.BLE_UNOPTIMIZED_SCAN_STATE_CHANGED, uid, 0);
+ }
+
getUidStatsLocked(uid).noteBluetoothScanStoppedLocked(elapsedRealtime, isUnoptimized);
+ if (workChain != null) {
+ getUidStatsLocked(uid).removeBluetoothWorkChain(workChain, isUnoptimized);
+ }
+ }
+
+ private int getAttributionUid(int uid, WorkChain workChain) {
+ if (workChain != null) {
+ return mapUid(workChain.getAttributionUid());
+ }
+
+ return mapUid(uid);
}
public void noteBluetoothScanStoppedFromSourceLocked(WorkSource ws, boolean isUnoptimized) {
final int N = ws.size();
for (int i = 0; i < N; i++) {
- noteBluetoothScanStoppedLocked(ws.get(i), isUnoptimized);
+ noteBluetoothScanStoppedLocked(null, ws.get(i), isUnoptimized);
+ }
+
+ final List<WorkChain> workChains = ws.getWorkChains();
+ if (workChains != null) {
+ for (int i = 0; i < workChains.size(); ++i) {
+ noteBluetoothScanStoppedLocked(workChains.get(i), -1, isUnoptimized);
+ }
}
}
@@ -5328,9 +5372,35 @@ public class BatteryStatsImpl extends BatteryStats {
+ Integer.toHexString(mHistoryCur.states2));
addHistoryRecordLocked(elapsedRealtime, uptime);
mBluetoothScanTimer.stopAllRunningLocked(elapsedRealtime);
+
+
for (int i=0; i<mUidStats.size(); i++) {
BatteryStatsImpl.Uid uid = mUidStats.valueAt(i);
uid.noteResetBluetoothScanLocked(elapsedRealtime);
+
+ StatsLog.write(StatsLog.BLE_SCAN_STATE_CHANGED, uid.getUid(), 0);
+
+ List<WorkChain> allWorkChains = uid.getAllBluetoothWorkChains();
+ if (allWorkChains != null) {
+ for (int j = 0; j < allWorkChains.size(); ++j) {
+ // TODO(statsd) : Log the entire workchain here.
+ StatsLog.write(StatsLog.BLE_SCAN_STATE_CHANGED,
+ allWorkChains.get(j).getAttributionUid(), 0);
+ }
+
+ allWorkChains.clear();
+ }
+
+ List<WorkChain> unoptimizedWorkChains = uid.getUnoptimizedBluetoothWorkChains();
+ if (unoptimizedWorkChains != null) {
+ for (int j = 0; j < unoptimizedWorkChains.size(); ++j) {
+ // TODO(statsd) : Log the entire workchain here.
+ StatsLog.write(StatsLog.BLE_UNOPTIMIZED_SCAN_STATE_CHANGED,
+ unoptimizedWorkChains.get(j).getAttributionUid(), 0);
+ }
+
+ unoptimizedWorkChains.clear();
+ }
}
}
}
@@ -5340,6 +5410,18 @@ public class BatteryStatsImpl extends BatteryStats {
for (int i = 0; i < N; i++) {
int uid = mapUid(ws.get(i));
getUidStatsLocked(uid).noteBluetoothScanResultsLocked(numNewResults);
+ StatsLog.write(StatsLog.BLE_SCAN_RESULT_RECEIVED, uid, numNewResults);
+ }
+
+ final List<WorkChain> workChains = ws.getWorkChains();
+ if (workChains != null) {
+ for (int i = 0; i < workChains.size(); ++i) {
+ final WorkChain wc = workChains.get(i);
+ int uid = mapUid(wc.getAttributionUid());
+ getUidStatsLocked(uid).noteBluetoothScanResultsLocked(numNewResults);
+ // TODO(statsd): Log the entire WorkChain here.
+ StatsLog.write(StatsLog.BLE_SCAN_RESULT_RECEIVED, uid, numNewResults);
+ }
}
}
@@ -6345,6 +6427,15 @@ public class BatteryStatsImpl extends BatteryStats {
*/
final SparseArray<Pid> mPids = new SparseArray<>();
+ /**
+ * The list of WorkChains associated with active bluetooth scans.
+ *
+ * NOTE: This is a hack and it only needs to exist because there's a "reset" API that is
+ * supposed to stop and log all WorkChains that were currently active.
+ */
+ ArrayList<WorkChain> mAllBluetoothChains = null;
+ ArrayList<WorkChain> mUnoptimizedBluetoothChains = null;
+
public Uid(BatteryStatsImpl bsi, int uid) {
mBsi = bsi;
mUid = uid;
@@ -6864,44 +6955,63 @@ public class BatteryStatsImpl extends BatteryStats {
return mBluetoothUnoptimizedScanTimer;
}
- public void noteBluetoothScanStartedLocked(long elapsedRealtimeMs, boolean isUnoptimized) {
+ public void noteBluetoothScanStartedLocked(long elapsedRealtimeMs,
+ boolean isUnoptimized) {
createBluetoothScanTimerLocked().startRunningLocked(elapsedRealtimeMs);
- // TODO(statsd): Possibly use a worksource instead of a uid.
- StatsLog.write(StatsLog.BLE_SCAN_STATE_CHANGED, getUid(), 1);
if (isUnoptimized) {
createBluetoothUnoptimizedScanTimerLocked().startRunningLocked(elapsedRealtimeMs);
- // TODO(statsd): Possibly use a worksource instead of a uid.
- StatsLog.write(StatsLog.BLE_UNOPTIMIZED_SCAN_STATE_CHANGED, getUid(), 1);
}
}
public void noteBluetoothScanStoppedLocked(long elapsedRealtimeMs, boolean isUnoptimized) {
if (mBluetoothScanTimer != null) {
mBluetoothScanTimer.stopRunningLocked(elapsedRealtimeMs);
- if (!mBluetoothScanTimer.isRunningLocked()) { // only tell statsd if truly stopped
- // TODO(statsd): Possibly use a worksource instead of a uid.
- StatsLog.write(StatsLog.BLE_SCAN_STATE_CHANGED, getUid(), 0);
- }
}
if (isUnoptimized && mBluetoothUnoptimizedScanTimer != null) {
mBluetoothUnoptimizedScanTimer.stopRunningLocked(elapsedRealtimeMs);
- if (!mBluetoothUnoptimizedScanTimer.isRunningLocked()) {
- // TODO(statsd): Possibly use a worksource instead of a uid.
- StatsLog.write(StatsLog.BLE_UNOPTIMIZED_SCAN_STATE_CHANGED, getUid(), 0);
- }
}
}
+ public void addBluetoothWorkChain(WorkChain workChain, boolean isUnoptimized) {
+ if (mAllBluetoothChains == null) {
+ mAllBluetoothChains = new ArrayList<WorkChain>(4);
+ }
+
+ if (isUnoptimized && mUnoptimizedBluetoothChains == null) {
+ mUnoptimizedBluetoothChains = new ArrayList<WorkChain>(4);
+ }
+
+ mAllBluetoothChains.add(workChain);
+ if (isUnoptimized) {
+ mUnoptimizedBluetoothChains.add(workChain);
+ }
+ }
+
+ public void removeBluetoothWorkChain(WorkChain workChain, boolean isUnoptimized) {
+ if (mAllBluetoothChains != null) {
+ mAllBluetoothChains.remove(workChain);
+ }
+
+ if (isUnoptimized && mUnoptimizedBluetoothChains != null) {
+ mUnoptimizedBluetoothChains.remove(workChain);
+ }
+ }
+
+ public List<WorkChain> getAllBluetoothWorkChains() {
+ return mAllBluetoothChains;
+ }
+
+ public List<WorkChain> getUnoptimizedBluetoothWorkChains() {
+ return mUnoptimizedBluetoothChains;
+ }
+
+
public void noteResetBluetoothScanLocked(long elapsedRealtimeMs) {
if (mBluetoothScanTimer != null) {
mBluetoothScanTimer.stopAllRunningLocked(elapsedRealtimeMs);
- // TODO(statsd): Possibly use a worksource instead of a uid.
- StatsLog.write(StatsLog.BLE_SCAN_STATE_CHANGED, getUid(), 0);
}
if (mBluetoothUnoptimizedScanTimer != null) {
mBluetoothUnoptimizedScanTimer.stopAllRunningLocked(elapsedRealtimeMs);
- // TODO(statsd): Possibly use a worksource instead of a uid.
- StatsLog.write(StatsLog.BLE_UNOPTIMIZED_SCAN_STATE_CHANGED, getUid(), 0);
}
}
@@ -6923,9 +7033,6 @@ public class BatteryStatsImpl extends BatteryStats {
createBluetoothScanResultCounterLocked().addAtomic(numNewResults);
// Uses background timebase, so the count will only be incremented if uid in background.
createBluetoothScanResultBgCounterLocked().addAtomic(numNewResults);
- // TODO(statsd): Possibly use a worksource instead of a uid.
- // TODO(statsd): This could be in AppScanStats instead, if desired.
- StatsLog.write(StatsLog.BLE_SCAN_RESULT_RECEIVED, getUid(), numNewResults);
}
@Override
diff --git a/core/tests/coretests/src/com/android/internal/os/BatteryStatsBackgroundStatsTest.java b/core/tests/coretests/src/com/android/internal/os/BatteryStatsBackgroundStatsTest.java
index c611a01c6e16..acf30225ea94 100644
--- a/core/tests/coretests/src/com/android/internal/os/BatteryStatsBackgroundStatsTest.java
+++ b/core/tests/coretests/src/com/android/internal/os/BatteryStatsBackgroundStatsTest.java
@@ -194,9 +194,19 @@ public class BatteryStatsBackgroundStatsTest extends TestCase {
@SmallTest
public void testAppBluetoothScan() throws Exception {
+ doTestAppBluetoothScanInternal(new WorkSource(UID));
+ }
+
+ @SmallTest
+ public void testAppBluetoothScan_workChain() throws Exception {
+ WorkSource ws = new WorkSource();
+ ws.createWorkChain().addNode(UID, "foo");
+ doTestAppBluetoothScanInternal(ws);
+ }
+
+ private void doTestAppBluetoothScanInternal(WorkSource ws) throws Exception {
final MockClocks clocks = new MockClocks();
MockBatteryStatsImpl bi = new MockBatteryStatsImpl(clocks);
- WorkSource ws = new WorkSource(UID); // needed for bluetooth
long curr = 0; // realtime in us
// On battery
@@ -263,6 +273,53 @@ public class BatteryStatsBackgroundStatsTest extends TestCase {
}
@SmallTest
+ public void testAppBluetoothScan_workChainAccounting() throws Exception {
+ final MockClocks clocks = new MockClocks();MockBatteryStatsImpl bi = new MockBatteryStatsImpl(clocks);
+ long curr = 0; // realtime in us
+
+ // On battery
+ curr = 1000 * (clocks.realtime = clocks.uptime = 100);
+ bi.updateTimeBasesLocked(true, Display.STATE_ON, curr, curr); // on battery
+
+ // App in foreground
+ bi.noteUidProcessStateLocked(UID, ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND);
+
+ WorkSource ws = new WorkSource();
+ ws.createWorkChain().addNode(500, "foo");
+ ws.createWorkChain().addNode(500, "bar");
+
+ // Test start / stop and reset with isUnoptimized == false.
+ bi.noteBluetoothScanStartedFromSourceLocked(ws, false);
+ BatteryStatsImpl.Uid stats = (BatteryStatsImpl.Uid) bi.getUidStats().get(500);
+ assertEquals(ws.getWorkChains(), stats.getAllBluetoothWorkChains());
+ assertNull(stats.getUnoptimizedBluetoothWorkChains());
+
+ bi.noteBluetoothScanStoppedFromSourceLocked(ws, false);
+ assertTrue(stats.getAllBluetoothWorkChains().isEmpty());
+ assertNull(stats.getUnoptimizedBluetoothWorkChains());
+
+ bi.noteBluetoothScanStartedFromSourceLocked(ws, false);
+ bi.noteResetBluetoothScanLocked();
+ assertTrue(stats.getAllBluetoothWorkChains().isEmpty());
+ assertNull(stats.getUnoptimizedBluetoothWorkChains());
+
+ // Test start / stop and reset with isUnoptimized == true.
+ bi.noteBluetoothScanStartedFromSourceLocked(ws, true);
+ stats = (BatteryStatsImpl.Uid) bi.getUidStats().get(500);
+ assertEquals(ws.getWorkChains(), stats.getAllBluetoothWorkChains());
+ assertEquals(ws.getWorkChains(), stats.getUnoptimizedBluetoothWorkChains());
+
+ bi.noteBluetoothScanStoppedFromSourceLocked(ws, true);
+ assertTrue(stats.getAllBluetoothWorkChains().isEmpty());
+ assertTrue(stats.getUnoptimizedBluetoothWorkChains().isEmpty());
+
+ bi.noteBluetoothScanStartedFromSourceLocked(ws, true);
+ bi.noteResetBluetoothScanLocked();
+ assertTrue(stats.getAllBluetoothWorkChains().isEmpty());
+ assertTrue(stats.getUnoptimizedBluetoothWorkChains().isEmpty());
+ }
+
+ @SmallTest
public void testJob() throws Exception {
final MockClocks clocks = new MockClocks();
MockBatteryStatsImpl bi = new MockBatteryStatsImpl(clocks);