Loading core/java/android/os/BatteryStats.java +17 −2 Original line number Diff line number Diff line Loading @@ -182,7 +182,7 @@ public abstract class BatteryStats implements Parcelable { * New in version 19: * - Wakelock data (wl) gets current and max times. * New in version 20: * - Background timers and counters for: Sensor, BluetoothScan, WifiScan, Jobs. * - Background timers and counters for: Sensor, BluetoothScan, WifiScan, Jobs, Syncs. */ static final String CHECKIN_VERSION = "20"; Loading Loading @@ -3387,9 +3387,13 @@ public abstract class BatteryStats implements Parcelable { // Convert from microseconds to milliseconds with rounding final long totalTime = (timer.getTotalTimeLocked(rawRealtime, which) + 500) / 1000; final int count = timer.getCountLocked(which); final Timer bgTimer = timer.getSubTimer(); final long bgTime = bgTimer != null ? (bgTimer.getTotalTimeLocked(rawRealtime, which) + 500) / 1000 : -1; final int bgCount = bgTimer != null ? bgTimer.getCountLocked(which) : -1; if (totalTime != 0) { dumpLine(pw, uid, category, SYNC_DATA, "\"" + syncs.keyAt(isy) + "\"", totalTime, count); totalTime, count, bgTime, bgCount); } } Loading Loading @@ -4602,6 +4606,10 @@ public abstract class BatteryStats implements Parcelable { // Convert from microseconds to milliseconds with rounding final long totalTime = (timer.getTotalTimeLocked(rawRealtime, which) + 500) / 1000; final int count = timer.getCountLocked(which); final Timer bgTimer = timer.getSubTimer(); final long bgTime = bgTimer != null ? (bgTimer.getTotalTimeLocked(rawRealtime, which) + 500) / 1000 : -1; final int bgCount = bgTimer != null ? bgTimer.getCountLocked(which) : -1; sb.setLength(0); sb.append(prefix); sb.append(" Sync "); Loading @@ -4612,6 +4620,13 @@ public abstract class BatteryStats implements Parcelable { sb.append("realtime ("); sb.append(count); sb.append(" times)"); if (bgTime > 0) { sb.append(", "); formatTimeMs(sb, bgTime); sb.append("background ("); sb.append(bgCount); sb.append(" times)"); } } else { sb.append("(not used)"); } Loading core/java/com/android/internal/os/BatteryStatsImpl.java +15 −15 Original line number Diff line number Diff line Loading @@ -5473,7 +5473,7 @@ public class BatteryStatsImpl extends BatteryStats { /** * The statistics we have collected for this uid's syncs. */ final OverflowArrayMap<StopwatchTimer> mSyncStats; final OverflowArrayMap<DualTimer> mSyncStats; /** * The statistics we have collected for this uid's jobs. Loading Loading @@ -5516,10 +5516,10 @@ public class BatteryStatsImpl extends BatteryStats { return new Wakelock(mBsi, Uid.this); } }; mSyncStats = mBsi.new OverflowArrayMap<StopwatchTimer>(uid) { @Override public StopwatchTimer instantiateObject() { return new StopwatchTimer(mBsi.mClocks, Uid.this, SYNC, null, mBsi.mOnBatteryTimeBase); mSyncStats = mBsi.new OverflowArrayMap<DualTimer>(uid) { @Override public DualTimer instantiateObject() { return new DualTimer(mBsi.mClocks, Uid.this, SYNC, null, mBsi.mOnBatteryTimeBase, mOnBatteryBackgroundTimeBase); } }; mJobStats = mBsi.new OverflowArrayMap<DualTimer>(uid) { Loading Loading @@ -6330,9 +6330,9 @@ public class BatteryStatsImpl extends BatteryStats { } } mWakelockStats.cleanup(); final ArrayMap<String, StopwatchTimer> syncStats = mSyncStats.getMap(); final ArrayMap<String, DualTimer> syncStats = mSyncStats.getMap(); for (int is=syncStats.size()-1; is>=0; is--) { StopwatchTimer timer = syncStats.valueAt(is); DualTimer timer = syncStats.valueAt(is); if (timer.reset(false)) { syncStats.removeAt(is); timer.detach(); Loading Loading @@ -6501,12 +6501,12 @@ public class BatteryStatsImpl extends BatteryStats { wakelock.writeToParcelLocked(out, elapsedRealtimeUs); } final ArrayMap<String, StopwatchTimer> syncStats = mSyncStats.getMap(); final ArrayMap<String, DualTimer> syncStats = mSyncStats.getMap(); int NS = syncStats.size(); out.writeInt(NS); for (int is=0; is<NS; is++) { out.writeString(syncStats.keyAt(is)); StopwatchTimer timer = syncStats.valueAt(is); DualTimer timer = syncStats.valueAt(is); Timer.writeTimerToParcel(out, timer, elapsedRealtimeUs); } Loading Loading @@ -6724,8 +6724,8 @@ public class BatteryStatsImpl extends BatteryStats { for (int j = 0; j < numSyncs; j++) { String syncName = in.readString(); if (in.readInt() != 0) { mSyncStats.add(syncName, new StopwatchTimer(mBsi.mClocks, Uid.this, SYNC, null, timeBase, in)); mSyncStats.add(syncName, new DualTimer(mBsi.mClocks, Uid.this, SYNC, null, mBsi.mOnBatteryTimeBase, mOnBatteryBackgroundTimeBase, in)); } } Loading Loading @@ -7991,7 +7991,7 @@ public class BatteryStatsImpl extends BatteryStats { } public void readSyncSummaryFromParcelLocked(String name, Parcel in) { StopwatchTimer timer = mSyncStats.instantiateObject(); DualTimer timer = mSyncStats.instantiateObject(); timer.readSummaryFromParcelLocked(in); mSyncStats.add(name, timer); } Loading Loading @@ -8044,14 +8044,14 @@ public class BatteryStatsImpl extends BatteryStats { } public void noteStartSyncLocked(String name, long elapsedRealtimeMs) { StopwatchTimer t = mSyncStats.startObject(name); DualTimer t = mSyncStats.startObject(name); if (t != null) { t.startRunningLocked(elapsedRealtimeMs); } } public void noteStopSyncLocked(String name, long elapsedRealtimeMs) { StopwatchTimer t = mSyncStats.stopObject(name); DualTimer t = mSyncStats.stopObject(name); if (t != null) { t.stopRunningLocked(elapsedRealtimeMs); } Loading Loading @@ -11487,7 +11487,7 @@ public class BatteryStatsImpl extends BatteryStats { } } final ArrayMap<String, StopwatchTimer> syncStats = u.mSyncStats.getMap(); final ArrayMap<String, DualTimer> syncStats = u.mSyncStats.getMap(); int NS = syncStats.size(); out.writeInt(NS); for (int is=0; is<NS; is++) { Loading core/tests/coretests/src/com/android/internal/os/BatteryStatsBackgroundStatsTest.java +61 −0 Original line number Diff line number Diff line Loading @@ -249,4 +249,65 @@ public class BatteryStatsBackgroundStatsTest extends TestCase { assertEquals(2, bi.getUidStats().get(UID).getJobStats().size()); bi.noteJobFinishLocked(jobName2, UID); } @SmallTest public void testSyncs() throws Exception { final MockClocks clocks = new MockClocks(); MockBatteryStatsImpl bi = new MockBatteryStatsImpl(clocks); final String syncName = "sync_name"; long curr = 0; // realtime in us // On battery curr = 1000 * (clocks.realtime = clocks.uptime = 100); bi.updateTimeBasesLocked(true, false, curr, curr); // on battery // App in foreground bi.noteUidProcessStateLocked(UID, ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND); // Start timer curr = 1000 * (clocks.realtime = clocks.uptime = 151); bi.noteSyncStartLocked(syncName, UID); // Stop timer curr = 1000 * (clocks.realtime = clocks.uptime = 161); bi.noteSyncFinishLocked(syncName, UID); // Move to background curr = 1000 * (clocks.realtime = clocks.uptime = 202); bi.noteUidProcessStateLocked(UID, ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND); // Start timer curr = 1000 * (clocks.realtime = clocks.uptime = 254); bi.noteSyncStartLocked(syncName, UID); // Off battery curr = 1000 * (clocks.realtime = clocks.uptime = 305); bi.updateTimeBasesLocked(false, false, curr, curr); // off battery // Stop timer curr = 1000 * (clocks.realtime = clocks.uptime = 409); bi.noteSyncFinishLocked(syncName, UID); // Test curr = 1000 * (clocks.realtime = clocks.uptime = 657); final ArrayMap<String, ? extends BatteryStats.Timer> syncs = bi.getUidStats().get(UID).getSyncStats(); assertEquals(1, syncs.size()); BatteryStats.Timer timer = syncs.valueAt(0); BatteryStats.Timer bgTimer = timer.getSubTimer(); long time = timer.getTotalTimeLocked(curr, STATS_SINCE_CHARGED); int count = timer.getCountLocked(STATS_SINCE_CHARGED); int bgCount = bgTimer.getCountLocked(STATS_SINCE_CHARGED); long bgTime = bgTimer.getTotalTimeLocked(curr, STATS_SINCE_CHARGED); assertEquals((161 - 151 + 305 - 254) * 1000, time); assertEquals(2, count); assertEquals(1, bgCount); assertEquals((305 - 254) * 1000, bgTime); // Test that a second sync is separate. curr = 1000 * (clocks.realtime = clocks.uptime = 3000); final String syncName2 = "second_sync"; bi.noteSyncStartLocked(syncName2, UID); assertEquals(2, bi.getUidStats().get(UID).getSyncStats().size()); bi.noteSyncFinishLocked(syncName2, UID); } } Loading
core/java/android/os/BatteryStats.java +17 −2 Original line number Diff line number Diff line Loading @@ -182,7 +182,7 @@ public abstract class BatteryStats implements Parcelable { * New in version 19: * - Wakelock data (wl) gets current and max times. * New in version 20: * - Background timers and counters for: Sensor, BluetoothScan, WifiScan, Jobs. * - Background timers and counters for: Sensor, BluetoothScan, WifiScan, Jobs, Syncs. */ static final String CHECKIN_VERSION = "20"; Loading Loading @@ -3387,9 +3387,13 @@ public abstract class BatteryStats implements Parcelable { // Convert from microseconds to milliseconds with rounding final long totalTime = (timer.getTotalTimeLocked(rawRealtime, which) + 500) / 1000; final int count = timer.getCountLocked(which); final Timer bgTimer = timer.getSubTimer(); final long bgTime = bgTimer != null ? (bgTimer.getTotalTimeLocked(rawRealtime, which) + 500) / 1000 : -1; final int bgCount = bgTimer != null ? bgTimer.getCountLocked(which) : -1; if (totalTime != 0) { dumpLine(pw, uid, category, SYNC_DATA, "\"" + syncs.keyAt(isy) + "\"", totalTime, count); totalTime, count, bgTime, bgCount); } } Loading Loading @@ -4602,6 +4606,10 @@ public abstract class BatteryStats implements Parcelable { // Convert from microseconds to milliseconds with rounding final long totalTime = (timer.getTotalTimeLocked(rawRealtime, which) + 500) / 1000; final int count = timer.getCountLocked(which); final Timer bgTimer = timer.getSubTimer(); final long bgTime = bgTimer != null ? (bgTimer.getTotalTimeLocked(rawRealtime, which) + 500) / 1000 : -1; final int bgCount = bgTimer != null ? bgTimer.getCountLocked(which) : -1; sb.setLength(0); sb.append(prefix); sb.append(" Sync "); Loading @@ -4612,6 +4620,13 @@ public abstract class BatteryStats implements Parcelable { sb.append("realtime ("); sb.append(count); sb.append(" times)"); if (bgTime > 0) { sb.append(", "); formatTimeMs(sb, bgTime); sb.append("background ("); sb.append(bgCount); sb.append(" times)"); } } else { sb.append("(not used)"); } Loading
core/java/com/android/internal/os/BatteryStatsImpl.java +15 −15 Original line number Diff line number Diff line Loading @@ -5473,7 +5473,7 @@ public class BatteryStatsImpl extends BatteryStats { /** * The statistics we have collected for this uid's syncs. */ final OverflowArrayMap<StopwatchTimer> mSyncStats; final OverflowArrayMap<DualTimer> mSyncStats; /** * The statistics we have collected for this uid's jobs. Loading Loading @@ -5516,10 +5516,10 @@ public class BatteryStatsImpl extends BatteryStats { return new Wakelock(mBsi, Uid.this); } }; mSyncStats = mBsi.new OverflowArrayMap<StopwatchTimer>(uid) { @Override public StopwatchTimer instantiateObject() { return new StopwatchTimer(mBsi.mClocks, Uid.this, SYNC, null, mBsi.mOnBatteryTimeBase); mSyncStats = mBsi.new OverflowArrayMap<DualTimer>(uid) { @Override public DualTimer instantiateObject() { return new DualTimer(mBsi.mClocks, Uid.this, SYNC, null, mBsi.mOnBatteryTimeBase, mOnBatteryBackgroundTimeBase); } }; mJobStats = mBsi.new OverflowArrayMap<DualTimer>(uid) { Loading Loading @@ -6330,9 +6330,9 @@ public class BatteryStatsImpl extends BatteryStats { } } mWakelockStats.cleanup(); final ArrayMap<String, StopwatchTimer> syncStats = mSyncStats.getMap(); final ArrayMap<String, DualTimer> syncStats = mSyncStats.getMap(); for (int is=syncStats.size()-1; is>=0; is--) { StopwatchTimer timer = syncStats.valueAt(is); DualTimer timer = syncStats.valueAt(is); if (timer.reset(false)) { syncStats.removeAt(is); timer.detach(); Loading Loading @@ -6501,12 +6501,12 @@ public class BatteryStatsImpl extends BatteryStats { wakelock.writeToParcelLocked(out, elapsedRealtimeUs); } final ArrayMap<String, StopwatchTimer> syncStats = mSyncStats.getMap(); final ArrayMap<String, DualTimer> syncStats = mSyncStats.getMap(); int NS = syncStats.size(); out.writeInt(NS); for (int is=0; is<NS; is++) { out.writeString(syncStats.keyAt(is)); StopwatchTimer timer = syncStats.valueAt(is); DualTimer timer = syncStats.valueAt(is); Timer.writeTimerToParcel(out, timer, elapsedRealtimeUs); } Loading Loading @@ -6724,8 +6724,8 @@ public class BatteryStatsImpl extends BatteryStats { for (int j = 0; j < numSyncs; j++) { String syncName = in.readString(); if (in.readInt() != 0) { mSyncStats.add(syncName, new StopwatchTimer(mBsi.mClocks, Uid.this, SYNC, null, timeBase, in)); mSyncStats.add(syncName, new DualTimer(mBsi.mClocks, Uid.this, SYNC, null, mBsi.mOnBatteryTimeBase, mOnBatteryBackgroundTimeBase, in)); } } Loading Loading @@ -7991,7 +7991,7 @@ public class BatteryStatsImpl extends BatteryStats { } public void readSyncSummaryFromParcelLocked(String name, Parcel in) { StopwatchTimer timer = mSyncStats.instantiateObject(); DualTimer timer = mSyncStats.instantiateObject(); timer.readSummaryFromParcelLocked(in); mSyncStats.add(name, timer); } Loading Loading @@ -8044,14 +8044,14 @@ public class BatteryStatsImpl extends BatteryStats { } public void noteStartSyncLocked(String name, long elapsedRealtimeMs) { StopwatchTimer t = mSyncStats.startObject(name); DualTimer t = mSyncStats.startObject(name); if (t != null) { t.startRunningLocked(elapsedRealtimeMs); } } public void noteStopSyncLocked(String name, long elapsedRealtimeMs) { StopwatchTimer t = mSyncStats.stopObject(name); DualTimer t = mSyncStats.stopObject(name); if (t != null) { t.stopRunningLocked(elapsedRealtimeMs); } Loading Loading @@ -11487,7 +11487,7 @@ public class BatteryStatsImpl extends BatteryStats { } } final ArrayMap<String, StopwatchTimer> syncStats = u.mSyncStats.getMap(); final ArrayMap<String, DualTimer> syncStats = u.mSyncStats.getMap(); int NS = syncStats.size(); out.writeInt(NS); for (int is=0; is<NS; is++) { Loading
core/tests/coretests/src/com/android/internal/os/BatteryStatsBackgroundStatsTest.java +61 −0 Original line number Diff line number Diff line Loading @@ -249,4 +249,65 @@ public class BatteryStatsBackgroundStatsTest extends TestCase { assertEquals(2, bi.getUidStats().get(UID).getJobStats().size()); bi.noteJobFinishLocked(jobName2, UID); } @SmallTest public void testSyncs() throws Exception { final MockClocks clocks = new MockClocks(); MockBatteryStatsImpl bi = new MockBatteryStatsImpl(clocks); final String syncName = "sync_name"; long curr = 0; // realtime in us // On battery curr = 1000 * (clocks.realtime = clocks.uptime = 100); bi.updateTimeBasesLocked(true, false, curr, curr); // on battery // App in foreground bi.noteUidProcessStateLocked(UID, ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND); // Start timer curr = 1000 * (clocks.realtime = clocks.uptime = 151); bi.noteSyncStartLocked(syncName, UID); // Stop timer curr = 1000 * (clocks.realtime = clocks.uptime = 161); bi.noteSyncFinishLocked(syncName, UID); // Move to background curr = 1000 * (clocks.realtime = clocks.uptime = 202); bi.noteUidProcessStateLocked(UID, ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND); // Start timer curr = 1000 * (clocks.realtime = clocks.uptime = 254); bi.noteSyncStartLocked(syncName, UID); // Off battery curr = 1000 * (clocks.realtime = clocks.uptime = 305); bi.updateTimeBasesLocked(false, false, curr, curr); // off battery // Stop timer curr = 1000 * (clocks.realtime = clocks.uptime = 409); bi.noteSyncFinishLocked(syncName, UID); // Test curr = 1000 * (clocks.realtime = clocks.uptime = 657); final ArrayMap<String, ? extends BatteryStats.Timer> syncs = bi.getUidStats().get(UID).getSyncStats(); assertEquals(1, syncs.size()); BatteryStats.Timer timer = syncs.valueAt(0); BatteryStats.Timer bgTimer = timer.getSubTimer(); long time = timer.getTotalTimeLocked(curr, STATS_SINCE_CHARGED); int count = timer.getCountLocked(STATS_SINCE_CHARGED); int bgCount = bgTimer.getCountLocked(STATS_SINCE_CHARGED); long bgTime = bgTimer.getTotalTimeLocked(curr, STATS_SINCE_CHARGED); assertEquals((161 - 151 + 305 - 254) * 1000, time); assertEquals(2, count); assertEquals(1, bgCount); assertEquals((305 - 254) * 1000, bgTime); // Test that a second sync is separate. curr = 1000 * (clocks.realtime = clocks.uptime = 3000); final String syncName2 = "second_sync"; bi.noteSyncStartLocked(syncName2, UID); assertEquals(2, bi.getUidStats().get(UID).getSyncStats().size()); bi.noteSyncFinishLocked(syncName2, UID); } }