Loading core/java/android/os/BatteryStats.java +6 −0 Original line number Original line Diff line number Diff line Loading @@ -845,6 +845,12 @@ public abstract class BatteryStats implements Parcelable { * Returns cpu active time of an uid. * Returns cpu active time of an uid. */ */ public abstract long getCpuActiveTime(); public abstract long getCpuActiveTime(); /** * Returns cpu active time of a UID while in the specified process state. */ public abstract long getCpuActiveTime(int procState); /** /** * Returns cpu times of an uid on each cluster * Returns cpu times of an uid on each cluster */ */ Loading core/java/com/android/internal/os/BatteryStatsImpl.java +160 −18 Original line number Original line Diff line number Diff line Loading @@ -160,7 +160,7 @@ public 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 static final int VERSION = 203; static final int VERSION = 204; // The maximum number of names wakelocks we will keep track of // The maximum number of names wakelocks we will keep track of // per uid; once the limit is reached, we batch the remaining wakelocks // per uid; once the limit is reached, we batch the remaining wakelocks Loading Loading @@ -1786,6 +1786,89 @@ public class BatteryStatsImpl extends BatteryStats { } } } } private static class TimeMultiStateCounter implements TimeBaseObs { private final TimeBase mTimeBase; private final LongMultiStateCounter mCounter; private TimeMultiStateCounter(TimeBase timeBase, Parcel in, long timestampMs) { mTimeBase = timeBase; mCounter = LongMultiStateCounter.CREATOR.createFromParcel(in); mCounter.setEnabled(mTimeBase.isRunning(), timestampMs); timeBase.add(this); } private TimeMultiStateCounter(TimeBase timeBase, int stateCount, long timestampMs) { mTimeBase = timeBase; mCounter = new LongMultiStateCounter(stateCount); mCounter.setEnabled(mTimeBase.isRunning(), timestampMs); timeBase.add(this); } private void writeToParcel(Parcel out) { mCounter.writeToParcel(out, 0); } @Override public void onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs) { mCounter.setEnabled(true, elapsedRealtimeUs / 1000); } @Override public void onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs) { mCounter.setEnabled(false, elapsedRealtimeUs / 1000); } public LongMultiStateCounter getCounter() { return mCounter; } public int getStateCount() { return mCounter.getStateCount(); } public void setTrackingEnabled(boolean enabled, long timestampMs) { mCounter.setEnabled(enabled && mTimeBase.isRunning(), timestampMs); } private void setState(@BatteryConsumer.ProcessState int processState, long elapsedRealtimeMs) { mCounter.setState(processState, elapsedRealtimeMs); } private void update(long value, long timestampMs) { mCounter.updateValue(value, timestampMs); } /** * Returns accumulated count for the specified state. */ public long getCountLocked(int procState) { return mCounter.getCount(procState); } public void logState(Printer pw, String prefix) { pw.println(prefix + "mCounter=" + mCounter); } /** * Clears state of this counter. */ @Override public boolean reset(boolean detachIfReset, long elapsedRealtimeUs /* unused */) { mCounter.reset(); if (detachIfReset) { detach(); } return true; } @Override public void detach() { mTimeBase.remove(this); } } private static class TimeInFreqMultiStateCounter implements TimeBaseObs { private static class TimeInFreqMultiStateCounter implements TimeBaseObs { private final TimeBase mTimeBase; private final TimeBase mTimeBase; private final LongArrayMultiStateCounter mCounter; private final LongArrayMultiStateCounter mCounter; Loading Loading @@ -8024,7 +8107,7 @@ public class BatteryStatsImpl extends BatteryStats { LongSamplingCounter mUserCpuTime; LongSamplingCounter mUserCpuTime; LongSamplingCounter mSystemCpuTime; LongSamplingCounter mSystemCpuTime; LongSamplingCounter[][] mCpuClusterSpeedTimesUs; LongSamplingCounter[][] mCpuClusterSpeedTimesUs; LongSamplingCounter mCpuActiveTimeMs; TimeMultiStateCounter mCpuActiveTimeMs; LongSamplingCounterArray mCpuFreqTimeMs; LongSamplingCounterArray mCpuFreqTimeMs; LongSamplingCounterArray mScreenOffCpuFreqTimeMs; LongSamplingCounterArray mScreenOffCpuFreqTimeMs; Loading Loading @@ -8147,7 +8230,6 @@ public class BatteryStatsImpl extends BatteryStats { mUserCpuTime = new LongSamplingCounter(mBsi.mOnBatteryTimeBase); mUserCpuTime = new LongSamplingCounter(mBsi.mOnBatteryTimeBase); mSystemCpuTime = new LongSamplingCounter(mBsi.mOnBatteryTimeBase); mSystemCpuTime = new LongSamplingCounter(mBsi.mOnBatteryTimeBase); mCpuActiveTimeMs = new LongSamplingCounter(mBsi.mOnBatteryTimeBase); mCpuClusterTimesMs = new LongSamplingCounterArray(mBsi.mOnBatteryTimeBase); mCpuClusterTimesMs = new LongSamplingCounterArray(mBsi.mOnBatteryTimeBase); mWakelockStats = mBsi.new OverflowArrayMap<Wakelock>(uid) { mWakelockStats = mBsi.new OverflowArrayMap<Wakelock>(uid) { Loading Loading @@ -8190,11 +8272,13 @@ public class BatteryStatsImpl extends BatteryStats { mProcessState = procState; mProcessState = procState; getProcStateTimeCounter().setState(procState, elapsedTimeMs); getProcStateTimeCounter().setState(procState, elapsedTimeMs); getProcStateScreenOffTimeCounter().setState(procState, elapsedTimeMs); getProcStateScreenOffTimeCounter().setState(procState, elapsedTimeMs); final int batteryConsumerProcessState = mapUidProcessStateToBatteryConsumerProcessState(procState); getCpuActiveTimeCounter().setState(batteryConsumerProcessState, elapsedTimeMs); final MeasuredEnergyStats energyStats = final MeasuredEnergyStats energyStats = getOrCreateMeasuredEnergyStatsIfSupportedLocked(); getOrCreateMeasuredEnergyStatsIfSupportedLocked(); if (energyStats != null) { if (energyStats != null) { energyStats.setState(mapUidProcessStateToBatteryConsumerProcessState(procState), energyStats.setState(batteryConsumerProcessState, elapsedTimeMs); elapsedTimeMs); } } } } Loading @@ -8208,9 +8292,39 @@ public class BatteryStatsImpl extends BatteryStats { return nullIfAllZeros(mScreenOffCpuFreqTimeMs, which); return nullIfAllZeros(mScreenOffCpuFreqTimeMs, which); } } private TimeMultiStateCounter getCpuActiveTimeCounter() { if (mCpuActiveTimeMs == null) { final long timestampMs = mBsi.mClock.elapsedRealtime(); mCpuActiveTimeMs = new TimeMultiStateCounter(mBsi.mOnBatteryTimeBase, BatteryConsumer.PROCESS_STATE_COUNT, timestampMs); mCpuActiveTimeMs.setState( mapUidProcessStateToBatteryConsumerProcessState(mProcessState), timestampMs); } return mCpuActiveTimeMs; } @Override @Override public long getCpuActiveTime() { public long getCpuActiveTime() { return mCpuActiveTimeMs.getCountLocked(STATS_SINCE_CHARGED); if (mCpuActiveTimeMs == null) { return 0; } long activeTime = 0; for (int procState = 0; procState < BatteryConsumer.PROCESS_STATE_COUNT; procState++) { activeTime += mCpuActiveTimeMs.getCountLocked(procState); } return activeTime; } @Override public long getCpuActiveTime(int procState) { if (mCpuActiveTimeMs == null || procState < 0 || procState >= BatteryConsumer.PROCESS_STATE_COUNT) { return 0; } return mCpuActiveTimeMs.getCountLocked(procState); } } @Override @Override Loading Loading @@ -9914,7 +10028,13 @@ public class BatteryStatsImpl extends BatteryStats { LongSamplingCounterArray.writeToParcel(out, mCpuFreqTimeMs); LongSamplingCounterArray.writeToParcel(out, mCpuFreqTimeMs); LongSamplingCounterArray.writeToParcel(out, mScreenOffCpuFreqTimeMs); LongSamplingCounterArray.writeToParcel(out, mScreenOffCpuFreqTimeMs); if (mCpuActiveTimeMs != null) { out.writeInt(mCpuActiveTimeMs.getStateCount()); mCpuActiveTimeMs.writeToParcel(out); mCpuActiveTimeMs.writeToParcel(out); } else { out.writeInt(0); } mCpuClusterTimesMs.writeToParcel(out); mCpuClusterTimesMs.writeToParcel(out); if (mProcStateTimeMs != null) { if (mProcStateTimeMs != null) { Loading Loading @@ -10217,11 +10337,18 @@ public class BatteryStatsImpl extends BatteryStats { mScreenOffCpuFreqTimeMs = LongSamplingCounterArray.readFromParcel( mScreenOffCpuFreqTimeMs = LongSamplingCounterArray.readFromParcel( in, mBsi.mOnBatteryScreenOffTimeBase); in, mBsi.mOnBatteryScreenOffTimeBase); mCpuActiveTimeMs = new LongSamplingCounter(mBsi.mOnBatteryTimeBase, in); mCpuClusterTimesMs = new LongSamplingCounterArray(mBsi.mOnBatteryTimeBase, in); final long timestampMs = mBsi.mClock.elapsedRealtime(); final long timestampMs = mBsi.mClock.elapsedRealtime(); int stateCount = in.readInt(); int stateCount = in.readInt(); if (stateCount != 0) { final TimeMultiStateCounter counter = new TimeMultiStateCounter( mBsi.mOnBatteryTimeBase, in, timestampMs); if (stateCount == BatteryConsumer.PROCESS_STATE_COUNT) { mCpuActiveTimeMs = counter; } } mCpuClusterTimesMs = new LongSamplingCounterArray(mBsi.mOnBatteryTimeBase, in); stateCount = in.readInt(); if (stateCount != 0) { if (stateCount != 0) { // Read the object from the Parcel, whether it's usable or not // Read the object from the Parcel, whether it's usable or not TimeInFreqMultiStateCounter counter = new TimeInFreqMultiStateCounter( TimeInFreqMultiStateCounter counter = new TimeInFreqMultiStateCounter( Loading Loading @@ -11135,12 +11262,14 @@ public class BatteryStatsImpl extends BatteryStats { updateOnBatteryBgTimeBase(uptimeMs * 1000, elapsedRealtimeMs * 1000); updateOnBatteryBgTimeBase(uptimeMs * 1000, elapsedRealtimeMs * 1000); updateOnBatteryScreenOffBgTimeBase(uptimeMs * 1000, elapsedRealtimeMs * 1000); updateOnBatteryScreenOffBgTimeBase(uptimeMs * 1000, elapsedRealtimeMs * 1000); final int batteryConsumerProcessState = mapUidProcessStateToBatteryConsumerProcessState(mProcessState); getCpuActiveTimeCounter().setState(batteryConsumerProcessState, elapsedRealtimeMs); final MeasuredEnergyStats energyStats = final MeasuredEnergyStats energyStats = getOrCreateMeasuredEnergyStatsIfSupportedLocked(); getOrCreateMeasuredEnergyStatsIfSupportedLocked(); if (energyStats != null) { if (energyStats != null) { energyStats.setState( energyStats.setState(batteryConsumerProcessState, elapsedRealtimeMs); mapUidProcessStateToBatteryConsumerProcessState(mProcessState), elapsedRealtimeMs); } } } } Loading Loading @@ -14344,7 +14473,7 @@ public class BatteryStatsImpl extends BatteryStats { public void readKernelUidCpuActiveTimesLocked(boolean onBattery) { public void readKernelUidCpuActiveTimesLocked(boolean onBattery) { final long startTimeMs = mClock.uptimeMillis(); final long startTimeMs = mClock.uptimeMillis(); final long elapsedRealtimeMs = mClock.elapsedRealtime(); final long elapsedRealtimeMs = mClock.elapsedRealtime(); mCpuUidActiveTimeReader.readDelta(false, (uid, cpuActiveTimesMs) -> { mCpuUidActiveTimeReader.readAbsolute((uid, cpuActiveTimesMs) -> { uid = mapUid(uid); uid = mapUid(uid); if (Process.isIsolated(uid)) { if (Process.isIsolated(uid)) { if (DEBUG) Slog.w(TAG, "Got active times for an isolated uid: " + uid); if (DEBUG) Slog.w(TAG, "Got active times for an isolated uid: " + uid); Loading @@ -14355,7 +14484,7 @@ public class BatteryStatsImpl extends BatteryStats { return; return; } } final Uid u = getUidStatsLocked(uid, elapsedRealtimeMs, startTimeMs); final Uid u = getUidStatsLocked(uid, elapsedRealtimeMs, startTimeMs); u.mCpuActiveTimeMs.addCountLocked(cpuActiveTimesMs, onBattery); u.getCpuActiveTimeCounter().update(cpuActiveTimesMs, mClock.elapsedRealtime()); }); }); final long elapsedTimeMs = mClock.uptimeMillis() - startTimeMs; final long elapsedTimeMs = mClock.uptimeMillis() - startTimeMs; Loading Loading @@ -16496,13 +16625,20 @@ public class BatteryStatsImpl extends BatteryStats { u.mScreenOffCpuFreqTimeMs = LongSamplingCounterArray.readSummaryFromParcelLocked( u.mScreenOffCpuFreqTimeMs = LongSamplingCounterArray.readSummaryFromParcelLocked( in, mOnBatteryScreenOffTimeBase); in, mOnBatteryScreenOffTimeBase); u.mCpuActiveTimeMs.readSummaryFromParcelLocked(in); int stateCount = in.readInt(); if (stateCount != 0) { final TimeMultiStateCounter counter = new TimeMultiStateCounter( mOnBatteryTimeBase, in, mClock.elapsedRealtime()); if (stateCount == BatteryConsumer.PROCESS_STATE_COUNT) { u.mCpuActiveTimeMs = counter; } } u.mCpuClusterTimesMs.readSummaryFromParcelLocked(in); u.mCpuClusterTimesMs.readSummaryFromParcelLocked(in); detachIfNotNull(u.mProcStateTimeMs); detachIfNotNull(u.mProcStateTimeMs); u.mProcStateTimeMs = null; u.mProcStateTimeMs = null; int stateCount = in.readInt(); stateCount = in.readInt(); if (stateCount != 0) { if (stateCount != 0) { // Read the object from the Parcel, whether it's usable or not // Read the object from the Parcel, whether it's usable or not TimeInFreqMultiStateCounter counter = new TimeInFreqMultiStateCounter( TimeInFreqMultiStateCounter counter = new TimeInFreqMultiStateCounter( Loading Loading @@ -17025,7 +17161,13 @@ public class BatteryStatsImpl extends BatteryStats { LongSamplingCounterArray.writeSummaryToParcelLocked(out, u.mCpuFreqTimeMs); LongSamplingCounterArray.writeSummaryToParcelLocked(out, u.mCpuFreqTimeMs); LongSamplingCounterArray.writeSummaryToParcelLocked(out, u.mScreenOffCpuFreqTimeMs); LongSamplingCounterArray.writeSummaryToParcelLocked(out, u.mScreenOffCpuFreqTimeMs); u.mCpuActiveTimeMs.writeSummaryFromParcelLocked(out); if (u.mCpuActiveTimeMs != null) { out.writeInt(u.mCpuActiveTimeMs.getStateCount()); u.mCpuActiveTimeMs.writeToParcel(out); } else { out.writeInt(0); } u.mCpuClusterTimesMs.writeSummaryToParcelLocked(out); u.mCpuClusterTimesMs.writeSummaryToParcelLocked(out); if (u.mProcStateTimeMs != null) { if (u.mProcStateTimeMs != null) { core/java/com/android/internal/os/CpuPowerCalculator.java +8 −6 Original line number Original line Diff line number Diff line Loading @@ -184,16 +184,14 @@ public class CpuPowerCalculator extends PowerCalculator { continue; continue; } } // TODO(b/191921016): use per-state CPU active time final long cpuActiveTime = 0; // TODO(b/191921016): use per-state CPU cluster times // TODO(b/191921016): use per-state CPU cluster times final long[] cpuClusterTimes = null; final long[] cpuClusterTimes = null; final long[] cpuFreqTimes = u.getCpuFreqTimes(BatteryStats.STATS_SINCE_CHARGED, final long[] cpuFreqTimes = u.getCpuFreqTimes(BatteryStats.STATS_SINCE_CHARGED, uidProcState); uidProcState); if (cpuActiveTime != 0 || cpuClusterTimes != null || cpuFreqTimes != null) { if (cpuClusterTimes != null || cpuFreqTimes != null) { result.perProcStatePowerMah[procState] += calculateUidModeledPowerMah(u, result.perProcStatePowerMah[procState] += calculateUidModeledPowerMah(u, cpuActiveTime, cpuClusterTimes, cpuFreqTimes); 0, cpuClusterTimes, cpuFreqTimes); } } } } Loading @@ -202,8 +200,12 @@ public class CpuPowerCalculator extends PowerCalculator { continue; continue; } } app.setConsumedPower(key, result.perProcStatePowerMah[key.processState], final long cpuActiveTime = u.getCpuActiveTime(key.processState); BatteryConsumer.POWER_MODEL_POWER_PROFILE); double powerMah = result.perProcStatePowerMah[key.processState]; powerMah += mCpuActivePowerEstimator.calculatePower(cpuActiveTime); app.setConsumedPower(key, powerMah, BatteryConsumer.POWER_MODEL_POWER_PROFILE) .setUsageDurationMillis(key, cpuActiveTime); } } } } Loading core/tests/coretests/src/com/android/internal/os/BatteryStatsCpuTimesTest.java +70 −17 Original line number Original line Diff line number Diff line Loading @@ -156,7 +156,7 @@ public class BatteryStatsCpuTimesTest { verify(mCpuUidFreqTimeReader, times(2)).perClusterTimesAvailable(); verify(mCpuUidFreqTimeReader, times(2)).perClusterTimesAvailable(); verify(mCpuUidFreqTimeReader).readDelta(anyBoolean(), verify(mCpuUidFreqTimeReader).readDelta(anyBoolean(), any(KernelCpuUidFreqTimeReader.Callback.class)); any(KernelCpuUidFreqTimeReader.Callback.class)); verify(mCpuUidActiveTimeReader).readDelta(anyBoolean(), verify(mCpuUidActiveTimeReader).readAbsolute( any(KernelCpuUidActiveTimeReader.Callback.class)); any(KernelCpuUidActiveTimeReader.Callback.class)); verify(mCpuUidClusterTimeReader).readDelta(anyBoolean(), verify(mCpuUidClusterTimeReader).readDelta(anyBoolean(), any(KernelCpuUidClusterTimeReader.Callback.class)); any(KernelCpuUidClusterTimeReader.Callback.class)); Loading Loading @@ -1039,6 +1039,8 @@ public class BatteryStatsCpuTimesTest { @Test @Test public void testReadKernelUidCpuActiveTimesLocked() { public void testReadKernelUidCpuActiveTimesLocked() { mClocks.realtime = 1000; // PRECONDITIONS // PRECONDITIONS updateTimeBasesLocked(true, Display.STATE_ON, 0, 0); updateTimeBasesLocked(true, Display.STATE_ON, 0, 0); Loading @@ -1049,15 +1051,15 @@ public class BatteryStatsCpuTimesTest { FIRST_APPLICATION_UID + 27, FIRST_APPLICATION_UID + 27, FIRST_APPLICATION_UID + 33 FIRST_APPLICATION_UID + 33 }); }); final long[] uidTimesMs = {8000, 25000, 3000, 0, 42000}; final long[] initialTimesMs = {8000, 25000, 3000, 0, 42000}; doAnswer(invocation -> { doAnswer(invocation -> { final KernelCpuUidActiveTimeReader.Callback<Long> callback = final KernelCpuUidActiveTimeReader.Callback<Long> callback = invocation.getArgument(1); invocation.getArgument(0); for (int i = 0; i < testUids.length; ++i) { for (int i = 0; i < testUids.length; ++i) { callback.onUidCpuTime(testUids[i], uidTimesMs[i]); callback.onUidCpuTime(testUids[i], initialTimesMs[i]); } } return null; return null; }).when(mCpuUidActiveTimeReader).readDelta(anyBoolean(), }).when(mCpuUidActiveTimeReader).readAbsolute( any(KernelCpuUidActiveTimeReader.Callback.class)); any(KernelCpuUidActiveTimeReader.Callback.class)); // RUN // RUN Loading @@ -1067,23 +1069,52 @@ public class BatteryStatsCpuTimesTest { for (int i = 0; i < testUids.length; ++i) { for (int i = 0; i < testUids.length; ++i) { final BatteryStats.Uid u = mBatteryStatsImpl.getUidStats().get(testUids[i]); final BatteryStats.Uid u = mBatteryStatsImpl.getUidStats().get(testUids[i]); assertNotNull("No entry for uid=" + testUids[i], u); assertNotNull("No entry for uid=" + testUids[i], u); assertEquals("Unexpected cpu active time for uid=" + testUids[i], uidTimesMs[i], assertEquals("Unexpected cpu active time for uid=" + testUids[i], 0, u.getCpuActiveTime()); u.getCpuActiveTime()); } } // Some time passes mClocks.realtime = 2000; // PRECONDITIONS final long[] cpuTimesAt2000 = {43000, 3345000, 2143000, 123000, 4554000}; doAnswer(invocation -> { final KernelCpuUidActiveTimeReader.Callback<Long> callback = invocation.getArgument(0); for (int i = 0; i < testUids.length; ++i) { callback.onUidCpuTime(testUids[i], cpuTimesAt2000[i]); } return null; }).when(mCpuUidActiveTimeReader).readAbsolute( any(KernelCpuUidActiveTimeReader.Callback.class)); // RUN mBatteryStatsImpl.readKernelUidCpuActiveTimesLocked(true); // VERIFY for (int i = 0; i < testUids.length; ++i) { final BatteryStats.Uid u = mBatteryStatsImpl.getUidStats().get(testUids[i]); assertNotNull("No entry for uid=" + testUids[i], u); assertEquals("Unexpected cpu active time for uid=" + testUids[i], cpuTimesAt2000[i] - initialTimesMs[i], u.getCpuActiveTime()); } // Give it another second mClocks.realtime = 3000; // Repeat the test when the screen is off. // Repeat the test when the screen is off. // PRECONDITIONS // PRECONDITIONS updateTimeBasesLocked(true, Display.STATE_OFF, 0, 0); updateTimeBasesLocked(true, Display.STATE_OFF, 0, 0); final long[] deltasMs = {43000, 3345000, 2143000, 123000, 4554000}; final long[] cpuTimesAt3000 = {63000, 7345000, 8143000, 923000, 5554000}; doAnswer(invocation -> { doAnswer(invocation -> { final KernelCpuUidActiveTimeReader.Callback<Long> callback = final KernelCpuUidActiveTimeReader.Callback<Long> callback = invocation.getArgument(1); invocation.getArgument(0); for (int i = 0; i < testUids.length; ++i) { for (int i = 0; i < testUids.length; ++i) { callback.onUidCpuTime(testUids[i], deltasMs[i]); callback.onUidCpuTime(testUids[i], cpuTimesAt3000[i]); } } return null; return null; }).when(mCpuUidActiveTimeReader).readDelta(anyBoolean(), }).when(mCpuUidActiveTimeReader).readAbsolute( any(KernelCpuUidActiveTimeReader.Callback.class)); any(KernelCpuUidActiveTimeReader.Callback.class)); // RUN // RUN Loading @@ -1094,12 +1125,14 @@ public class BatteryStatsCpuTimesTest { final BatteryStats.Uid u = mBatteryStatsImpl.getUidStats().get(testUids[i]); final BatteryStats.Uid u = mBatteryStatsImpl.getUidStats().get(testUids[i]); assertNotNull("No entry for uid=" + testUids[i], u); assertNotNull("No entry for uid=" + testUids[i], u); assertEquals("Unexpected cpu active time for uid=" + testUids[i], assertEquals("Unexpected cpu active time for uid=" + testUids[i], uidTimesMs[i] + deltasMs[i], u.getCpuActiveTime()); cpuTimesAt3000[i] - initialTimesMs[i], u.getCpuActiveTime()); } } } } @Test @Test public void testReadKernelUidCpuActiveTimesLocked_invalidUid() { public void testReadKernelUidCpuActiveTimesLocked_invalidUid() { mClocks.realtime = 1000; // PRECONDITIONS // PRECONDITIONS updateTimeBasesLocked(true, Display.STATE_ON, 0, 0); updateTimeBasesLocked(true, Display.STATE_ON, 0, 0); Loading @@ -1113,17 +1146,37 @@ public class BatteryStatsCpuTimesTest { FIRST_APPLICATION_UID + 27, FIRST_APPLICATION_UID + 27, FIRST_APPLICATION_UID + 33 FIRST_APPLICATION_UID + 33 }); }); final long[] uidTimesMs = {8000, 25000, 3000, 0, 42000}; final long[] cpuTimesAt1000 = {8000, 25000, 3000, 0, 42000}; doAnswer(invocation -> { doAnswer(invocation -> { final KernelCpuUidActiveTimeReader.Callback<Long> callback = final KernelCpuUidActiveTimeReader.Callback<Long> callback = invocation.getArgument(1); invocation.getArgument(0); for (int i = 0; i < testUids.length; ++i) { for (int i = 0; i < testUids.length; ++i) { callback.onUidCpuTime(testUids[i], uidTimesMs[i]); callback.onUidCpuTime(testUids[i], cpuTimesAt1000[i]); } } // And one for the invalid uid // And one for the invalid uid callback.onUidCpuTime(invalidUid, 1200L); callback.onUidCpuTime(invalidUid, 1200L); return null; return null; }).when(mCpuUidActiveTimeReader).readDelta(anyBoolean(), }).when(mCpuUidActiveTimeReader).readAbsolute( any(KernelCpuUidActiveTimeReader.Callback.class)); // RUN mBatteryStatsImpl.readKernelUidCpuActiveTimesLocked(true); // Some time passes mClocks.realtime = 2000; // Run again to compute the delta final long[] cpuTimesAt2000 = {18000, 225000, 33000, 40, 542000}; doAnswer(invocation -> { final KernelCpuUidActiveTimeReader.Callback<Long> callback = invocation.getArgument(0); for (int i = 0; i < testUids.length; ++i) { callback.onUidCpuTime(testUids[i], cpuTimesAt2000[i]); } // And one for the invalid uid callback.onUidCpuTime(invalidUid, 1200L); return null; }).when(mCpuUidActiveTimeReader).readAbsolute( any(KernelCpuUidActiveTimeReader.Callback.class)); any(KernelCpuUidActiveTimeReader.Callback.class)); // RUN // RUN Loading @@ -1133,8 +1186,8 @@ public class BatteryStatsCpuTimesTest { for (int i = 0; i < testUids.length; ++i) { for (int i = 0; i < testUids.length; ++i) { final BatteryStats.Uid u = mBatteryStatsImpl.getUidStats().get(testUids[i]); final BatteryStats.Uid u = mBatteryStatsImpl.getUidStats().get(testUids[i]); assertNotNull("No entry for uid=" + testUids[i], u); assertNotNull("No entry for uid=" + testUids[i], u); assertEquals("Unexpected cpu active time for uid=" + testUids[i], uidTimesMs[i], assertEquals("Unexpected cpu active time for uid=" + testUids[i], u.getCpuActiveTime()); cpuTimesAt2000[i] - cpuTimesAt1000[i], u.getCpuActiveTime()); } } assertNull("There shouldn't be an entry for invalid uid=" + invalidUid, assertNull("There shouldn't be an entry for invalid uid=" + invalidUid, mBatteryStatsImpl.getUidStats().get(invalidUid)); mBatteryStatsImpl.getUidStats().get(invalidUid)); Loading core/tests/coretests/src/com/android/internal/os/CpuPowerCalculatorTest.java +47 −16 File changed.Preview size limit exceeded, changes collapsed. Show changes Loading
core/java/android/os/BatteryStats.java +6 −0 Original line number Original line Diff line number Diff line Loading @@ -845,6 +845,12 @@ public abstract class BatteryStats implements Parcelable { * Returns cpu active time of an uid. * Returns cpu active time of an uid. */ */ public abstract long getCpuActiveTime(); public abstract long getCpuActiveTime(); /** * Returns cpu active time of a UID while in the specified process state. */ public abstract long getCpuActiveTime(int procState); /** /** * Returns cpu times of an uid on each cluster * Returns cpu times of an uid on each cluster */ */ Loading
core/java/com/android/internal/os/BatteryStatsImpl.java +160 −18 Original line number Original line Diff line number Diff line Loading @@ -160,7 +160,7 @@ public 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 static final int VERSION = 203; static final int VERSION = 204; // The maximum number of names wakelocks we will keep track of // The maximum number of names wakelocks we will keep track of // per uid; once the limit is reached, we batch the remaining wakelocks // per uid; once the limit is reached, we batch the remaining wakelocks Loading Loading @@ -1786,6 +1786,89 @@ public class BatteryStatsImpl extends BatteryStats { } } } } private static class TimeMultiStateCounter implements TimeBaseObs { private final TimeBase mTimeBase; private final LongMultiStateCounter mCounter; private TimeMultiStateCounter(TimeBase timeBase, Parcel in, long timestampMs) { mTimeBase = timeBase; mCounter = LongMultiStateCounter.CREATOR.createFromParcel(in); mCounter.setEnabled(mTimeBase.isRunning(), timestampMs); timeBase.add(this); } private TimeMultiStateCounter(TimeBase timeBase, int stateCount, long timestampMs) { mTimeBase = timeBase; mCounter = new LongMultiStateCounter(stateCount); mCounter.setEnabled(mTimeBase.isRunning(), timestampMs); timeBase.add(this); } private void writeToParcel(Parcel out) { mCounter.writeToParcel(out, 0); } @Override public void onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs) { mCounter.setEnabled(true, elapsedRealtimeUs / 1000); } @Override public void onTimeStopped(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs) { mCounter.setEnabled(false, elapsedRealtimeUs / 1000); } public LongMultiStateCounter getCounter() { return mCounter; } public int getStateCount() { return mCounter.getStateCount(); } public void setTrackingEnabled(boolean enabled, long timestampMs) { mCounter.setEnabled(enabled && mTimeBase.isRunning(), timestampMs); } private void setState(@BatteryConsumer.ProcessState int processState, long elapsedRealtimeMs) { mCounter.setState(processState, elapsedRealtimeMs); } private void update(long value, long timestampMs) { mCounter.updateValue(value, timestampMs); } /** * Returns accumulated count for the specified state. */ public long getCountLocked(int procState) { return mCounter.getCount(procState); } public void logState(Printer pw, String prefix) { pw.println(prefix + "mCounter=" + mCounter); } /** * Clears state of this counter. */ @Override public boolean reset(boolean detachIfReset, long elapsedRealtimeUs /* unused */) { mCounter.reset(); if (detachIfReset) { detach(); } return true; } @Override public void detach() { mTimeBase.remove(this); } } private static class TimeInFreqMultiStateCounter implements TimeBaseObs { private static class TimeInFreqMultiStateCounter implements TimeBaseObs { private final TimeBase mTimeBase; private final TimeBase mTimeBase; private final LongArrayMultiStateCounter mCounter; private final LongArrayMultiStateCounter mCounter; Loading Loading @@ -8024,7 +8107,7 @@ public class BatteryStatsImpl extends BatteryStats { LongSamplingCounter mUserCpuTime; LongSamplingCounter mUserCpuTime; LongSamplingCounter mSystemCpuTime; LongSamplingCounter mSystemCpuTime; LongSamplingCounter[][] mCpuClusterSpeedTimesUs; LongSamplingCounter[][] mCpuClusterSpeedTimesUs; LongSamplingCounter mCpuActiveTimeMs; TimeMultiStateCounter mCpuActiveTimeMs; LongSamplingCounterArray mCpuFreqTimeMs; LongSamplingCounterArray mCpuFreqTimeMs; LongSamplingCounterArray mScreenOffCpuFreqTimeMs; LongSamplingCounterArray mScreenOffCpuFreqTimeMs; Loading Loading @@ -8147,7 +8230,6 @@ public class BatteryStatsImpl extends BatteryStats { mUserCpuTime = new LongSamplingCounter(mBsi.mOnBatteryTimeBase); mUserCpuTime = new LongSamplingCounter(mBsi.mOnBatteryTimeBase); mSystemCpuTime = new LongSamplingCounter(mBsi.mOnBatteryTimeBase); mSystemCpuTime = new LongSamplingCounter(mBsi.mOnBatteryTimeBase); mCpuActiveTimeMs = new LongSamplingCounter(mBsi.mOnBatteryTimeBase); mCpuClusterTimesMs = new LongSamplingCounterArray(mBsi.mOnBatteryTimeBase); mCpuClusterTimesMs = new LongSamplingCounterArray(mBsi.mOnBatteryTimeBase); mWakelockStats = mBsi.new OverflowArrayMap<Wakelock>(uid) { mWakelockStats = mBsi.new OverflowArrayMap<Wakelock>(uid) { Loading Loading @@ -8190,11 +8272,13 @@ public class BatteryStatsImpl extends BatteryStats { mProcessState = procState; mProcessState = procState; getProcStateTimeCounter().setState(procState, elapsedTimeMs); getProcStateTimeCounter().setState(procState, elapsedTimeMs); getProcStateScreenOffTimeCounter().setState(procState, elapsedTimeMs); getProcStateScreenOffTimeCounter().setState(procState, elapsedTimeMs); final int batteryConsumerProcessState = mapUidProcessStateToBatteryConsumerProcessState(procState); getCpuActiveTimeCounter().setState(batteryConsumerProcessState, elapsedTimeMs); final MeasuredEnergyStats energyStats = final MeasuredEnergyStats energyStats = getOrCreateMeasuredEnergyStatsIfSupportedLocked(); getOrCreateMeasuredEnergyStatsIfSupportedLocked(); if (energyStats != null) { if (energyStats != null) { energyStats.setState(mapUidProcessStateToBatteryConsumerProcessState(procState), energyStats.setState(batteryConsumerProcessState, elapsedTimeMs); elapsedTimeMs); } } } } Loading @@ -8208,9 +8292,39 @@ public class BatteryStatsImpl extends BatteryStats { return nullIfAllZeros(mScreenOffCpuFreqTimeMs, which); return nullIfAllZeros(mScreenOffCpuFreqTimeMs, which); } } private TimeMultiStateCounter getCpuActiveTimeCounter() { if (mCpuActiveTimeMs == null) { final long timestampMs = mBsi.mClock.elapsedRealtime(); mCpuActiveTimeMs = new TimeMultiStateCounter(mBsi.mOnBatteryTimeBase, BatteryConsumer.PROCESS_STATE_COUNT, timestampMs); mCpuActiveTimeMs.setState( mapUidProcessStateToBatteryConsumerProcessState(mProcessState), timestampMs); } return mCpuActiveTimeMs; } @Override @Override public long getCpuActiveTime() { public long getCpuActiveTime() { return mCpuActiveTimeMs.getCountLocked(STATS_SINCE_CHARGED); if (mCpuActiveTimeMs == null) { return 0; } long activeTime = 0; for (int procState = 0; procState < BatteryConsumer.PROCESS_STATE_COUNT; procState++) { activeTime += mCpuActiveTimeMs.getCountLocked(procState); } return activeTime; } @Override public long getCpuActiveTime(int procState) { if (mCpuActiveTimeMs == null || procState < 0 || procState >= BatteryConsumer.PROCESS_STATE_COUNT) { return 0; } return mCpuActiveTimeMs.getCountLocked(procState); } } @Override @Override Loading Loading @@ -9914,7 +10028,13 @@ public class BatteryStatsImpl extends BatteryStats { LongSamplingCounterArray.writeToParcel(out, mCpuFreqTimeMs); LongSamplingCounterArray.writeToParcel(out, mCpuFreqTimeMs); LongSamplingCounterArray.writeToParcel(out, mScreenOffCpuFreqTimeMs); LongSamplingCounterArray.writeToParcel(out, mScreenOffCpuFreqTimeMs); if (mCpuActiveTimeMs != null) { out.writeInt(mCpuActiveTimeMs.getStateCount()); mCpuActiveTimeMs.writeToParcel(out); mCpuActiveTimeMs.writeToParcel(out); } else { out.writeInt(0); } mCpuClusterTimesMs.writeToParcel(out); mCpuClusterTimesMs.writeToParcel(out); if (mProcStateTimeMs != null) { if (mProcStateTimeMs != null) { Loading Loading @@ -10217,11 +10337,18 @@ public class BatteryStatsImpl extends BatteryStats { mScreenOffCpuFreqTimeMs = LongSamplingCounterArray.readFromParcel( mScreenOffCpuFreqTimeMs = LongSamplingCounterArray.readFromParcel( in, mBsi.mOnBatteryScreenOffTimeBase); in, mBsi.mOnBatteryScreenOffTimeBase); mCpuActiveTimeMs = new LongSamplingCounter(mBsi.mOnBatteryTimeBase, in); mCpuClusterTimesMs = new LongSamplingCounterArray(mBsi.mOnBatteryTimeBase, in); final long timestampMs = mBsi.mClock.elapsedRealtime(); final long timestampMs = mBsi.mClock.elapsedRealtime(); int stateCount = in.readInt(); int stateCount = in.readInt(); if (stateCount != 0) { final TimeMultiStateCounter counter = new TimeMultiStateCounter( mBsi.mOnBatteryTimeBase, in, timestampMs); if (stateCount == BatteryConsumer.PROCESS_STATE_COUNT) { mCpuActiveTimeMs = counter; } } mCpuClusterTimesMs = new LongSamplingCounterArray(mBsi.mOnBatteryTimeBase, in); stateCount = in.readInt(); if (stateCount != 0) { if (stateCount != 0) { // Read the object from the Parcel, whether it's usable or not // Read the object from the Parcel, whether it's usable or not TimeInFreqMultiStateCounter counter = new TimeInFreqMultiStateCounter( TimeInFreqMultiStateCounter counter = new TimeInFreqMultiStateCounter( Loading Loading @@ -11135,12 +11262,14 @@ public class BatteryStatsImpl extends BatteryStats { updateOnBatteryBgTimeBase(uptimeMs * 1000, elapsedRealtimeMs * 1000); updateOnBatteryBgTimeBase(uptimeMs * 1000, elapsedRealtimeMs * 1000); updateOnBatteryScreenOffBgTimeBase(uptimeMs * 1000, elapsedRealtimeMs * 1000); updateOnBatteryScreenOffBgTimeBase(uptimeMs * 1000, elapsedRealtimeMs * 1000); final int batteryConsumerProcessState = mapUidProcessStateToBatteryConsumerProcessState(mProcessState); getCpuActiveTimeCounter().setState(batteryConsumerProcessState, elapsedRealtimeMs); final MeasuredEnergyStats energyStats = final MeasuredEnergyStats energyStats = getOrCreateMeasuredEnergyStatsIfSupportedLocked(); getOrCreateMeasuredEnergyStatsIfSupportedLocked(); if (energyStats != null) { if (energyStats != null) { energyStats.setState( energyStats.setState(batteryConsumerProcessState, elapsedRealtimeMs); mapUidProcessStateToBatteryConsumerProcessState(mProcessState), elapsedRealtimeMs); } } } } Loading Loading @@ -14344,7 +14473,7 @@ public class BatteryStatsImpl extends BatteryStats { public void readKernelUidCpuActiveTimesLocked(boolean onBattery) { public void readKernelUidCpuActiveTimesLocked(boolean onBattery) { final long startTimeMs = mClock.uptimeMillis(); final long startTimeMs = mClock.uptimeMillis(); final long elapsedRealtimeMs = mClock.elapsedRealtime(); final long elapsedRealtimeMs = mClock.elapsedRealtime(); mCpuUidActiveTimeReader.readDelta(false, (uid, cpuActiveTimesMs) -> { mCpuUidActiveTimeReader.readAbsolute((uid, cpuActiveTimesMs) -> { uid = mapUid(uid); uid = mapUid(uid); if (Process.isIsolated(uid)) { if (Process.isIsolated(uid)) { if (DEBUG) Slog.w(TAG, "Got active times for an isolated uid: " + uid); if (DEBUG) Slog.w(TAG, "Got active times for an isolated uid: " + uid); Loading @@ -14355,7 +14484,7 @@ public class BatteryStatsImpl extends BatteryStats { return; return; } } final Uid u = getUidStatsLocked(uid, elapsedRealtimeMs, startTimeMs); final Uid u = getUidStatsLocked(uid, elapsedRealtimeMs, startTimeMs); u.mCpuActiveTimeMs.addCountLocked(cpuActiveTimesMs, onBattery); u.getCpuActiveTimeCounter().update(cpuActiveTimesMs, mClock.elapsedRealtime()); }); }); final long elapsedTimeMs = mClock.uptimeMillis() - startTimeMs; final long elapsedTimeMs = mClock.uptimeMillis() - startTimeMs; Loading Loading @@ -16496,13 +16625,20 @@ public class BatteryStatsImpl extends BatteryStats { u.mScreenOffCpuFreqTimeMs = LongSamplingCounterArray.readSummaryFromParcelLocked( u.mScreenOffCpuFreqTimeMs = LongSamplingCounterArray.readSummaryFromParcelLocked( in, mOnBatteryScreenOffTimeBase); in, mOnBatteryScreenOffTimeBase); u.mCpuActiveTimeMs.readSummaryFromParcelLocked(in); int stateCount = in.readInt(); if (stateCount != 0) { final TimeMultiStateCounter counter = new TimeMultiStateCounter( mOnBatteryTimeBase, in, mClock.elapsedRealtime()); if (stateCount == BatteryConsumer.PROCESS_STATE_COUNT) { u.mCpuActiveTimeMs = counter; } } u.mCpuClusterTimesMs.readSummaryFromParcelLocked(in); u.mCpuClusterTimesMs.readSummaryFromParcelLocked(in); detachIfNotNull(u.mProcStateTimeMs); detachIfNotNull(u.mProcStateTimeMs); u.mProcStateTimeMs = null; u.mProcStateTimeMs = null; int stateCount = in.readInt(); stateCount = in.readInt(); if (stateCount != 0) { if (stateCount != 0) { // Read the object from the Parcel, whether it's usable or not // Read the object from the Parcel, whether it's usable or not TimeInFreqMultiStateCounter counter = new TimeInFreqMultiStateCounter( TimeInFreqMultiStateCounter counter = new TimeInFreqMultiStateCounter( Loading Loading @@ -17025,7 +17161,13 @@ public class BatteryStatsImpl extends BatteryStats { LongSamplingCounterArray.writeSummaryToParcelLocked(out, u.mCpuFreqTimeMs); LongSamplingCounterArray.writeSummaryToParcelLocked(out, u.mCpuFreqTimeMs); LongSamplingCounterArray.writeSummaryToParcelLocked(out, u.mScreenOffCpuFreqTimeMs); LongSamplingCounterArray.writeSummaryToParcelLocked(out, u.mScreenOffCpuFreqTimeMs); u.mCpuActiveTimeMs.writeSummaryFromParcelLocked(out); if (u.mCpuActiveTimeMs != null) { out.writeInt(u.mCpuActiveTimeMs.getStateCount()); u.mCpuActiveTimeMs.writeToParcel(out); } else { out.writeInt(0); } u.mCpuClusterTimesMs.writeSummaryToParcelLocked(out); u.mCpuClusterTimesMs.writeSummaryToParcelLocked(out); if (u.mProcStateTimeMs != null) { if (u.mProcStateTimeMs != null) {
core/java/com/android/internal/os/CpuPowerCalculator.java +8 −6 Original line number Original line Diff line number Diff line Loading @@ -184,16 +184,14 @@ public class CpuPowerCalculator extends PowerCalculator { continue; continue; } } // TODO(b/191921016): use per-state CPU active time final long cpuActiveTime = 0; // TODO(b/191921016): use per-state CPU cluster times // TODO(b/191921016): use per-state CPU cluster times final long[] cpuClusterTimes = null; final long[] cpuClusterTimes = null; final long[] cpuFreqTimes = u.getCpuFreqTimes(BatteryStats.STATS_SINCE_CHARGED, final long[] cpuFreqTimes = u.getCpuFreqTimes(BatteryStats.STATS_SINCE_CHARGED, uidProcState); uidProcState); if (cpuActiveTime != 0 || cpuClusterTimes != null || cpuFreqTimes != null) { if (cpuClusterTimes != null || cpuFreqTimes != null) { result.perProcStatePowerMah[procState] += calculateUidModeledPowerMah(u, result.perProcStatePowerMah[procState] += calculateUidModeledPowerMah(u, cpuActiveTime, cpuClusterTimes, cpuFreqTimes); 0, cpuClusterTimes, cpuFreqTimes); } } } } Loading @@ -202,8 +200,12 @@ public class CpuPowerCalculator extends PowerCalculator { continue; continue; } } app.setConsumedPower(key, result.perProcStatePowerMah[key.processState], final long cpuActiveTime = u.getCpuActiveTime(key.processState); BatteryConsumer.POWER_MODEL_POWER_PROFILE); double powerMah = result.perProcStatePowerMah[key.processState]; powerMah += mCpuActivePowerEstimator.calculatePower(cpuActiveTime); app.setConsumedPower(key, powerMah, BatteryConsumer.POWER_MODEL_POWER_PROFILE) .setUsageDurationMillis(key, cpuActiveTime); } } } } Loading
core/tests/coretests/src/com/android/internal/os/BatteryStatsCpuTimesTest.java +70 −17 Original line number Original line Diff line number Diff line Loading @@ -156,7 +156,7 @@ public class BatteryStatsCpuTimesTest { verify(mCpuUidFreqTimeReader, times(2)).perClusterTimesAvailable(); verify(mCpuUidFreqTimeReader, times(2)).perClusterTimesAvailable(); verify(mCpuUidFreqTimeReader).readDelta(anyBoolean(), verify(mCpuUidFreqTimeReader).readDelta(anyBoolean(), any(KernelCpuUidFreqTimeReader.Callback.class)); any(KernelCpuUidFreqTimeReader.Callback.class)); verify(mCpuUidActiveTimeReader).readDelta(anyBoolean(), verify(mCpuUidActiveTimeReader).readAbsolute( any(KernelCpuUidActiveTimeReader.Callback.class)); any(KernelCpuUidActiveTimeReader.Callback.class)); verify(mCpuUidClusterTimeReader).readDelta(anyBoolean(), verify(mCpuUidClusterTimeReader).readDelta(anyBoolean(), any(KernelCpuUidClusterTimeReader.Callback.class)); any(KernelCpuUidClusterTimeReader.Callback.class)); Loading Loading @@ -1039,6 +1039,8 @@ public class BatteryStatsCpuTimesTest { @Test @Test public void testReadKernelUidCpuActiveTimesLocked() { public void testReadKernelUidCpuActiveTimesLocked() { mClocks.realtime = 1000; // PRECONDITIONS // PRECONDITIONS updateTimeBasesLocked(true, Display.STATE_ON, 0, 0); updateTimeBasesLocked(true, Display.STATE_ON, 0, 0); Loading @@ -1049,15 +1051,15 @@ public class BatteryStatsCpuTimesTest { FIRST_APPLICATION_UID + 27, FIRST_APPLICATION_UID + 27, FIRST_APPLICATION_UID + 33 FIRST_APPLICATION_UID + 33 }); }); final long[] uidTimesMs = {8000, 25000, 3000, 0, 42000}; final long[] initialTimesMs = {8000, 25000, 3000, 0, 42000}; doAnswer(invocation -> { doAnswer(invocation -> { final KernelCpuUidActiveTimeReader.Callback<Long> callback = final KernelCpuUidActiveTimeReader.Callback<Long> callback = invocation.getArgument(1); invocation.getArgument(0); for (int i = 0; i < testUids.length; ++i) { for (int i = 0; i < testUids.length; ++i) { callback.onUidCpuTime(testUids[i], uidTimesMs[i]); callback.onUidCpuTime(testUids[i], initialTimesMs[i]); } } return null; return null; }).when(mCpuUidActiveTimeReader).readDelta(anyBoolean(), }).when(mCpuUidActiveTimeReader).readAbsolute( any(KernelCpuUidActiveTimeReader.Callback.class)); any(KernelCpuUidActiveTimeReader.Callback.class)); // RUN // RUN Loading @@ -1067,23 +1069,52 @@ public class BatteryStatsCpuTimesTest { for (int i = 0; i < testUids.length; ++i) { for (int i = 0; i < testUids.length; ++i) { final BatteryStats.Uid u = mBatteryStatsImpl.getUidStats().get(testUids[i]); final BatteryStats.Uid u = mBatteryStatsImpl.getUidStats().get(testUids[i]); assertNotNull("No entry for uid=" + testUids[i], u); assertNotNull("No entry for uid=" + testUids[i], u); assertEquals("Unexpected cpu active time for uid=" + testUids[i], uidTimesMs[i], assertEquals("Unexpected cpu active time for uid=" + testUids[i], 0, u.getCpuActiveTime()); u.getCpuActiveTime()); } } // Some time passes mClocks.realtime = 2000; // PRECONDITIONS final long[] cpuTimesAt2000 = {43000, 3345000, 2143000, 123000, 4554000}; doAnswer(invocation -> { final KernelCpuUidActiveTimeReader.Callback<Long> callback = invocation.getArgument(0); for (int i = 0; i < testUids.length; ++i) { callback.onUidCpuTime(testUids[i], cpuTimesAt2000[i]); } return null; }).when(mCpuUidActiveTimeReader).readAbsolute( any(KernelCpuUidActiveTimeReader.Callback.class)); // RUN mBatteryStatsImpl.readKernelUidCpuActiveTimesLocked(true); // VERIFY for (int i = 0; i < testUids.length; ++i) { final BatteryStats.Uid u = mBatteryStatsImpl.getUidStats().get(testUids[i]); assertNotNull("No entry for uid=" + testUids[i], u); assertEquals("Unexpected cpu active time for uid=" + testUids[i], cpuTimesAt2000[i] - initialTimesMs[i], u.getCpuActiveTime()); } // Give it another second mClocks.realtime = 3000; // Repeat the test when the screen is off. // Repeat the test when the screen is off. // PRECONDITIONS // PRECONDITIONS updateTimeBasesLocked(true, Display.STATE_OFF, 0, 0); updateTimeBasesLocked(true, Display.STATE_OFF, 0, 0); final long[] deltasMs = {43000, 3345000, 2143000, 123000, 4554000}; final long[] cpuTimesAt3000 = {63000, 7345000, 8143000, 923000, 5554000}; doAnswer(invocation -> { doAnswer(invocation -> { final KernelCpuUidActiveTimeReader.Callback<Long> callback = final KernelCpuUidActiveTimeReader.Callback<Long> callback = invocation.getArgument(1); invocation.getArgument(0); for (int i = 0; i < testUids.length; ++i) { for (int i = 0; i < testUids.length; ++i) { callback.onUidCpuTime(testUids[i], deltasMs[i]); callback.onUidCpuTime(testUids[i], cpuTimesAt3000[i]); } } return null; return null; }).when(mCpuUidActiveTimeReader).readDelta(anyBoolean(), }).when(mCpuUidActiveTimeReader).readAbsolute( any(KernelCpuUidActiveTimeReader.Callback.class)); any(KernelCpuUidActiveTimeReader.Callback.class)); // RUN // RUN Loading @@ -1094,12 +1125,14 @@ public class BatteryStatsCpuTimesTest { final BatteryStats.Uid u = mBatteryStatsImpl.getUidStats().get(testUids[i]); final BatteryStats.Uid u = mBatteryStatsImpl.getUidStats().get(testUids[i]); assertNotNull("No entry for uid=" + testUids[i], u); assertNotNull("No entry for uid=" + testUids[i], u); assertEquals("Unexpected cpu active time for uid=" + testUids[i], assertEquals("Unexpected cpu active time for uid=" + testUids[i], uidTimesMs[i] + deltasMs[i], u.getCpuActiveTime()); cpuTimesAt3000[i] - initialTimesMs[i], u.getCpuActiveTime()); } } } } @Test @Test public void testReadKernelUidCpuActiveTimesLocked_invalidUid() { public void testReadKernelUidCpuActiveTimesLocked_invalidUid() { mClocks.realtime = 1000; // PRECONDITIONS // PRECONDITIONS updateTimeBasesLocked(true, Display.STATE_ON, 0, 0); updateTimeBasesLocked(true, Display.STATE_ON, 0, 0); Loading @@ -1113,17 +1146,37 @@ public class BatteryStatsCpuTimesTest { FIRST_APPLICATION_UID + 27, FIRST_APPLICATION_UID + 27, FIRST_APPLICATION_UID + 33 FIRST_APPLICATION_UID + 33 }); }); final long[] uidTimesMs = {8000, 25000, 3000, 0, 42000}; final long[] cpuTimesAt1000 = {8000, 25000, 3000, 0, 42000}; doAnswer(invocation -> { doAnswer(invocation -> { final KernelCpuUidActiveTimeReader.Callback<Long> callback = final KernelCpuUidActiveTimeReader.Callback<Long> callback = invocation.getArgument(1); invocation.getArgument(0); for (int i = 0; i < testUids.length; ++i) { for (int i = 0; i < testUids.length; ++i) { callback.onUidCpuTime(testUids[i], uidTimesMs[i]); callback.onUidCpuTime(testUids[i], cpuTimesAt1000[i]); } } // And one for the invalid uid // And one for the invalid uid callback.onUidCpuTime(invalidUid, 1200L); callback.onUidCpuTime(invalidUid, 1200L); return null; return null; }).when(mCpuUidActiveTimeReader).readDelta(anyBoolean(), }).when(mCpuUidActiveTimeReader).readAbsolute( any(KernelCpuUidActiveTimeReader.Callback.class)); // RUN mBatteryStatsImpl.readKernelUidCpuActiveTimesLocked(true); // Some time passes mClocks.realtime = 2000; // Run again to compute the delta final long[] cpuTimesAt2000 = {18000, 225000, 33000, 40, 542000}; doAnswer(invocation -> { final KernelCpuUidActiveTimeReader.Callback<Long> callback = invocation.getArgument(0); for (int i = 0; i < testUids.length; ++i) { callback.onUidCpuTime(testUids[i], cpuTimesAt2000[i]); } // And one for the invalid uid callback.onUidCpuTime(invalidUid, 1200L); return null; }).when(mCpuUidActiveTimeReader).readAbsolute( any(KernelCpuUidActiveTimeReader.Callback.class)); any(KernelCpuUidActiveTimeReader.Callback.class)); // RUN // RUN Loading @@ -1133,8 +1186,8 @@ public class BatteryStatsCpuTimesTest { for (int i = 0; i < testUids.length; ++i) { for (int i = 0; i < testUids.length; ++i) { final BatteryStats.Uid u = mBatteryStatsImpl.getUidStats().get(testUids[i]); final BatteryStats.Uid u = mBatteryStatsImpl.getUidStats().get(testUids[i]); assertNotNull("No entry for uid=" + testUids[i], u); assertNotNull("No entry for uid=" + testUids[i], u); assertEquals("Unexpected cpu active time for uid=" + testUids[i], uidTimesMs[i], assertEquals("Unexpected cpu active time for uid=" + testUids[i], u.getCpuActiveTime()); cpuTimesAt2000[i] - cpuTimesAt1000[i], u.getCpuActiveTime()); } } assertNull("There shouldn't be an entry for invalid uid=" + invalidUid, assertNull("There shouldn't be an entry for invalid uid=" + invalidUid, mBatteryStatsImpl.getUidStats().get(invalidUid)); mBatteryStatsImpl.getUidStats().get(invalidUid)); Loading
core/tests/coretests/src/com/android/internal/os/CpuPowerCalculatorTest.java +47 −16 File changed.Preview size limit exceeded, changes collapsed. Show changes