diff options
| -rw-r--r-- | core/java/com/android/internal/os/BatteryStatsImpl.java | 159 | ||||
| -rw-r--r-- | core/tests/coretests/src/com/android/internal/os/BatteryStatsBackgroundStatsTest.java | 59 |
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); |