Loading core/java/android/os/BatteryStats.java +6 −11 Original line number Diff line number Diff line Loading @@ -634,7 +634,7 @@ public abstract class BatteryStats implements Parcelable { */ public static int mapToInternalProcessState(int procState) { if (procState == ActivityManager.PROCESS_STATE_NONEXISTENT) { return ActivityManager.PROCESS_STATE_NONEXISTENT; return Uid.PROCESS_STATE_NONEXISTENT; } else if (procState == ActivityManager.PROCESS_STATE_TOP) { return Uid.PROCESS_STATE_TOP; } else if (ActivityManager.isForegroundService(procState)) { Loading Loading @@ -911,6 +911,11 @@ public abstract class BatteryStats implements Parcelable { * Total number of process states we track. */ public static final int NUM_PROCESS_STATE = 7; /** * State of the UID when it has no running processes. It is intentionally out of * bounds 0..NUM_PROCESS_STATE. */ public static final int PROCESS_STATE_NONEXISTENT = NUM_PROCESS_STATE; // Used in dump static final String[] PROCESS_STATE_NAMES = { Loading @@ -930,16 +935,6 @@ public abstract class BatteryStats implements Parcelable { "C" // CACHED }; /** * When the process exits one of these states, we need to make sure cpu time in this state * is not attributed to any non-critical process states. */ public static final int[] CRITICAL_PROC_STATES = { Uid.PROCESS_STATE_TOP, Uid.PROCESS_STATE_FOREGROUND_SERVICE, Uid.PROCESS_STATE_FOREGROUND }; public abstract long getProcessStateTime(int state, long elapsedRealtimeUs, int which); public abstract Timer getProcessStateTimer(int state); Loading core/java/com/android/internal/os/BatteryStatsImpl.java +90 −241 File changed.Preview size limit exceeded, changes collapsed. Show changes core/java/com/android/internal/os/KernelCpuUidTimeReader.java +4 −0 Original line number Diff line number Diff line Loading @@ -620,6 +620,10 @@ public abstract class KernelCpuUidTimeReader<T> { } return numClusterFreqs; } public boolean isFastCpuTimesReader() { return mBpfTimesAvailable; } } /** Loading core/tests/coretests/src/com/android/internal/os/BatteryStatsImplTest.java +52 −81 Original line number Diff line number Diff line Loading @@ -37,7 +37,6 @@ import static org.mockito.Mockito.when; import android.app.ActivityManager; import android.os.BatteryStats; import android.util.SparseArray; import android.util.SparseIntArray; import android.view.Display; import androidx.test.filters.LargeTest; Loading @@ -53,6 +52,7 @@ import org.mockito.MockitoAnnotations; @LargeTest @RunWith(AndroidJUnit4.class) @SuppressWarnings("GuardedBy") public class BatteryStatsImplTest { private static final long[] CPU_FREQS = {1, 2, 3, 4, 5}; private static final int NUM_CPU_FREQS = CPU_FREQS.length; Loading @@ -62,29 +62,26 @@ public class BatteryStatsImplTest { @Mock private KernelSingleUidTimeReader mKernelSingleUidTimeReader; private final MockClock mMockClock = new MockClock(); private MockBatteryStatsImpl mBatteryStatsImpl; private MockClock mMockClock = new MockClock(); @Before public void setUp() { MockitoAnnotations.initMocks(this); when(mKernelUidCpuFreqTimeReader.isFastCpuTimesReader()).thenReturn(true); when(mKernelUidCpuFreqTimeReader.readFreqs(any())).thenReturn(CPU_FREQS); when(mKernelUidCpuFreqTimeReader.allUidTimesAvailable()).thenReturn(true); when(mKernelSingleUidTimeReader.singleUidCpuTimesAvailable()).thenReturn(true); mBatteryStatsImpl = new MockBatteryStatsImpl(mMockClock) .setKernelCpuUidFreqTimeReader(mKernelUidCpuFreqTimeReader) .setKernelSingleUidTimeReader(mKernelSingleUidTimeReader) .setTrackingCpuByProcStateEnabled(true); .setKernelSingleUidTimeReader(mKernelSingleUidTimeReader); } @Test public void testUpdateProcStateCpuTimes() { mBatteryStatsImpl.setOnBatteryInternal(true); synchronized (mBatteryStatsImpl) { mBatteryStatsImpl.updateTimeBasesLocked(true, Display.STATE_ON, 0, 0); } final int[] testUids = {10032, 10048, 10145, 10139}; final int[] activityManagerProcStates = { Loading @@ -99,15 +96,24 @@ public class BatteryStatsImplTest { PROCESS_STATE_TOP, PROCESS_STATE_CACHED }; addPendingUids(testUids, testProcStates); // Initialize time-in-freq counters mMockClock.realtime = 1000; for (int i = 0; i < testUids.length; ++i) { mBatteryStatsImpl.noteUidProcessStateLocked(testUids[i], activityManagerProcStates[i]); mockKernelSingleUidTimeReader(testUids[i], new long[5]); mBatteryStatsImpl.noteUidProcessStateLocked(testUids[i], activityManagerProcStates[i]); } final long[] timeInFreqs = new long[NUM_CPU_FREQS]; // Verify there are no cpu times initially. for (int i = 0; i < testUids.length; ++i) { final BatteryStats.Uid u = mBatteryStatsImpl.getUidStatsLocked(testUids[i]); for (int procState = 0; procState < NUM_PROCESS_STATE; ++procState) { assertFalse(u.getCpuFreqTimes(timeInFreqs, procState)); assertFalse(u.getScreenOffCpuFreqTimes(timeInFreqs, procState)); } } mBatteryStatsImpl.updateProcStateCpuTimes(true, false); // Obtain initial CPU time-in-freq counts final long[][] cpuTimes = { Loading @@ -117,24 +123,14 @@ public class BatteryStatsImplTest { {4859048, 348903, 4578967, 5973894, 298549} }; final long[] timeInFreqs = new long[NUM_CPU_FREQS]; mMockClock.realtime += 1000; for (int i = 0; i < testUids.length; ++i) { mockKernelSingleUidTimeReader(testUids[i], cpuTimes[i]); // Verify there are no cpu times initially. final BatteryStats.Uid u = mBatteryStatsImpl.getUidStatsLocked(testUids[i]); for (int procState = 0; procState < NUM_PROCESS_STATE; ++procState) { assertFalse(u.getCpuFreqTimes(timeInFreqs, procState)); assertFalse(u.getScreenOffCpuFreqTimes(timeInFreqs, procState)); } mBatteryStatsImpl.updateProcStateCpuTimesLocked(testUids[i], mMockClock.realtime); } addPendingUids(testUids, testProcStates); mMockClock.realtime += 1000; mBatteryStatsImpl.updateProcStateCpuTimes(true, false); verifyNoPendingUids(); for (int i = 0; i < testUids.length; ++i) { final BatteryStats.Uid u = mBatteryStatsImpl.getUidStats().get(testUids[i]); for (int procState = 0; procState < NUM_PROCESS_STATE; ++procState) { Loading @@ -155,19 +151,19 @@ public class BatteryStatsImplTest { {945894, 9089432, 19478, 3834, 7845}, {843895, 43948, 949582, 99, 384} }; mMockClock.realtime += 1000; for (int i = 0; i < testUids.length; ++i) { long[] newCpuTimes = new long[cpuTimes[i].length]; for (int j = 0; j < cpuTimes[i].length; j++) { newCpuTimes[j] = cpuTimes[i][j] + delta1[i][j]; } mockKernelSingleUidTimeReader(testUids[i], newCpuTimes); mBatteryStatsImpl.updateProcStateCpuTimesLocked(testUids[i], mMockClock.realtime); } addPendingUids(testUids, testProcStates); mMockClock.realtime += 1000; mBatteryStatsImpl.updateProcStateCpuTimes(true, false); verifyNoPendingUids(); for (int i = 0; i < testUids.length; ++i) { final BatteryStats.Uid u = mBatteryStatsImpl.getUidStats().get(testUids[i]); for (int procState = 0; procState < NUM_PROCESS_STATE; ++procState) { Loading @@ -186,10 +182,8 @@ public class BatteryStatsImplTest { } // Validate the on-battery-screen-off counter synchronized (mBatteryStatsImpl) { mBatteryStatsImpl.updateTimeBasesLocked(true, Display.STATE_OFF, 0, mMockClock.realtime * 1000); } final long[][] delta2 = { {95932, 2943, 49834, 89034, 139}, Loading @@ -197,19 +191,19 @@ public class BatteryStatsImplTest { {678, 7498, 9843, 889, 4894}, {488, 998, 8498, 394, 574} }; mMockClock.realtime += 1000; for (int i = 0; i < testUids.length; ++i) { long[] newCpuTimes = new long[cpuTimes[i].length]; for (int j = 0; j < cpuTimes[i].length; j++) { newCpuTimes[j] = cpuTimes[i][j] + delta1[i][j] + delta2[i][j]; } mockKernelSingleUidTimeReader(testUids[i], newCpuTimes); mBatteryStatsImpl.updateProcStateCpuTimesLocked(testUids[i], mMockClock.realtime); } addPendingUids(testUids, testProcStates); mMockClock.realtime += 1000; mBatteryStatsImpl.updateProcStateCpuTimes(true, true); verifyNoPendingUids(); for (int i = 0; i < testUids.length; ++i) { final BatteryStats.Uid u = mBatteryStatsImpl.getUidStats().get(testUids[i]); for (int procState = 0; procState < NUM_PROCESS_STATE; ++procState) { Loading Loading @@ -239,24 +233,25 @@ public class BatteryStatsImplTest { {3049509483598l, 4597834, 377654, 94589035, 7854}, {9493, 784, 99895, 8974893, 9879843} }; mMockClock.realtime += 1000; final int parentUid = testUids[1]; final int childUid = 99099; addIsolatedUid(parentUid, childUid); final long[] isolatedUidCpuTimes = {495784, 398473, 4895, 4905, 30984093}; mockKernelSingleUidTimeReader(childUid, isolatedUidCpuTimes, isolatedUidCpuTimes); for (int i = 0; i < testUids.length; ++i) { long[] newCpuTimes = new long[cpuTimes[i].length]; for (int j = 0; j < cpuTimes[i].length; j++) { newCpuTimes[j] = cpuTimes[i][j] + delta1[i][j] + delta2[i][j] + delta3[i][j]; } mockKernelSingleUidTimeReader(testUids[i], newCpuTimes); mBatteryStatsImpl.updateProcStateCpuTimesLocked(testUids[i], mMockClock.realtime); } addPendingUids(testUids, testProcStates); final int parentUid = testUids[1]; final int childUid = 99099; addIsolatedUid(parentUid, childUid); final long[] isolatedUidCpuTimes = {495784, 398473, 4895, 4905, 30984093}; mockKernelSingleUidTimeReader(childUid, isolatedUidCpuTimes, isolatedUidCpuTimes); mMockClock.realtime += 1000; mBatteryStatsImpl.updateProcStateCpuTimes(true, true); verifyNoPendingUids(); for (int i = 0; i < testUids.length; ++i) { final BatteryStats.Uid u = mBatteryStatsImpl.getUidStats().get(testUids[i]); for (int procState = 0; procState < NUM_PROCESS_STATE; ++procState) { Loading Loading @@ -284,11 +279,9 @@ public class BatteryStatsImplTest { } @Test public void testCopyFromAllUidsCpuTimes() { public void testUpdateCpuTimesForAllUids() { mBatteryStatsImpl.setOnBatteryInternal(false); synchronized (mBatteryStatsImpl) { mBatteryStatsImpl.updateTimeBasesLocked(true, Display.STATE_ON, 0, 0); } mMockClock.realtime = 1000; Loading @@ -299,14 +292,14 @@ public class BatteryStatsImplTest { PROCESS_STATE_TOP, PROCESS_STATE_CACHED }; addPendingUids(testUids, testProcStates); for (int i = 0; i < testUids.length; ++i) { BatteryStatsImpl.Uid uid = mBatteryStatsImpl.getUidStatsLocked(testUids[i]); uid.setProcessStateForTest(testProcStates[i], mMockClock.elapsedRealtime()); mockKernelSingleUidTimeReader(testUids[i], new long[NUM_CPU_FREQS]); mBatteryStatsImpl.updateProcStateCpuTimesLocked(testUids[i], mMockClock.elapsedRealtime()); } mBatteryStatsImpl.updateProcStateCpuTimes(true, false); final SparseArray<long[]> allUidCpuTimes = new SparseArray<>(); long[][] allCpuTimes = { Loading @@ -330,9 +323,8 @@ public class BatteryStatsImplTest { } mMockClock.realtime += 1000; mBatteryStatsImpl.copyFromAllUidsCpuTimes(true, false); verifyNoPendingUids(); mBatteryStatsImpl.updateCpuTimesForAllUids(); final long[] timeInFreqs = new long[NUM_CPU_FREQS]; Loading Loading @@ -411,9 +403,7 @@ public class BatteryStatsImplTest { final int releaseTimeMs = 1005; final int currentTimeMs = 1011; synchronized (mBatteryStatsImpl) { mBatteryStatsImpl.updateTimeBasesLocked(true, Display.STATE_OFF, 0, 0); } // Create a Uid Object final BatteryStats.Uid u = mBatteryStatsImpl.getUidStatsLocked(testUid); Loading @@ -436,9 +426,7 @@ public class BatteryStatsImplTest { final int acquireTimeMs = 1000; final int currentTimeMs = 1011; synchronized (mBatteryStatsImpl) { mBatteryStatsImpl.updateTimeBasesLocked(true, Display.STATE_OFF, 0, 0); } // Create a Uid Object final BatteryStats.Uid u = mBatteryStatsImpl.getUidStatsLocked(testUid); Loading @@ -464,9 +452,7 @@ public class BatteryStatsImplTest { final int releaseTimeMs_2 = 1009; final int currentTimeMs = 1011; synchronized (mBatteryStatsImpl) { mBatteryStatsImpl.updateTimeBasesLocked(true, Display.STATE_OFF, 0, 0); } // Create a Uid Object final BatteryStats.Uid u = mBatteryStatsImpl.getUidStatsLocked(testUid); Loading Loading @@ -496,9 +482,7 @@ public class BatteryStatsImplTest { final int releaseTimeMs_2 = 1009; final int currentTimeMs = 1011; synchronized (mBatteryStatsImpl) { mBatteryStatsImpl.updateTimeBasesLocked(true, Display.STATE_OFF, 0, 0); } // Create a Uid Object final BatteryStats.Uid u = mBatteryStatsImpl.getUidStatsLocked(testUid); Loading @@ -523,17 +507,4 @@ public class BatteryStatsImplTest { final BatteryStatsImpl.Uid u = mBatteryStatsImpl.getUidStatsLocked(parentUid); u.addIsolatedUid(childUid); } private void addPendingUids(int[] uids, int[] procStates) { final SparseIntArray pendingUids = mBatteryStatsImpl.getPendingUids(); for (int i = 0; i < uids.length; ++i) { pendingUids.put(uids[i], procStates[i]); } } private void verifyNoPendingUids() { final SparseIntArray pendingUids = mBatteryStatsImpl.getPendingUids(); assertEquals("There shouldn't be any pending uids left: " + pendingUids, 0, pendingUids.size()); } } core/tests/coretests/src/com/android/internal/os/BstatsCpuTimesValidationTest.java +0 −128 Original line number Diff line number Diff line Loading @@ -26,9 +26,6 @@ import static android.os.BatteryStats.Uid.PROCESS_STATE_TOP; import static android.os.BatteryStats.Uid.PROCESS_STATE_TOP_SLEEPING; import static android.os.BatteryStats.Uid.UID_PROCESS_TYPES; import static com.android.internal.os.BatteryStatsImpl.Constants.KEY_PROC_STATE_CPU_TIMES_READ_DELAY_MS; import static com.android.internal.os.BatteryStatsImpl.Constants.KEY_TRACK_CPU_TIMES_BY_PROC_STATE; import static junit.framework.Assert.assertNotNull; import static junit.framework.Assert.assertNull; import static junit.framework.Assert.assertTrue; Loading @@ -51,7 +48,6 @@ import android.os.Process; import android.os.SystemClock; import android.provider.Settings; import android.support.test.uiautomator.UiDevice; import android.text.TextUtils; import android.util.ArrayMap; import android.util.DebugUtils; import android.util.KeyValueListParser; Loading Loading @@ -125,11 +121,6 @@ public class BstatsCpuTimesValidationTest { PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0); sTestPkgUid = sContext.getPackageManager().getPackageUid(TEST_PKG, 0); executeCmd("cmd deviceidle whitelist +" + TEST_PKG); final ArrayMap<String, String> desiredConstants = new ArrayMap<>(); desiredConstants.put(KEY_TRACK_CPU_TIMES_BY_PROC_STATE, Boolean.toString(true)); desiredConstants.put(KEY_PROC_STATE_CPU_TIMES_READ_DELAY_MS, Integer.toString(0)); updateBatteryStatsConstants(desiredConstants); checkCpuTimesAvailability(); } Loading Loading @@ -517,125 +508,6 @@ public class BstatsCpuTimesValidationTest { batteryOffScreenOn(); } @Test public void testCpuFreqTimes_trackingDisabled() throws Exception { if (!sCpuFreqTimesAvailable || !sPerProcStateTimesAvailable) { Log.w(TAG, "Skipping " + testName.getMethodName() + "; freqTimesAvailable=" + sCpuFreqTimesAvailable + ", procStateTimesAvailable=" + sPerProcStateTimesAvailable); return; } final String bstatsConstants = Settings.Global.getString(sContext.getContentResolver(), Settings.Global.BATTERY_STATS_CONSTANTS); try { batteryOnScreenOn(); forceStop(); resetBatteryStats(); final long[] initialSnapshot = getAllCpuFreqTimes(sTestPkgUid); assertNull("Initial snapshot should be null, initial=" + Arrays.toString(initialSnapshot), initialSnapshot); assertNull("Initial top state snapshot should be null", getAllCpuFreqTimes(sTestPkgUid, PROCESS_STATE_TOP)); doSomeWork(PROCESS_STATE_TOP); forceStop(); final long[] cpuTimesMs = getAllCpuFreqTimes(sTestPkgUid, PROCESS_STATE_TOP); final String msgCpuTimes = getAllCpuTimesMsg(); assertCpuTimesValid(cpuTimesMs); long actualCpuTimeMs = 0; for (int i = 0; i < cpuTimesMs.length / 2; ++i) { actualCpuTimeMs += cpuTimesMs[i]; } assertApproximateValue("Incorrect total cpu time, " + msgCpuTimes, WORK_DURATION_MS, actualCpuTimeMs); updateTrackPerProcStateCpuTimesSetting(bstatsConstants, false); doSomeWork(PROCESS_STATE_TOP); forceStop(); final long[] cpuTimesMs2 = getAllCpuFreqTimes(sTestPkgUid, PROCESS_STATE_TOP); assertCpuTimesValid(cpuTimesMs2); assertCpuTimesEqual(cpuTimesMs2, cpuTimesMs, 20, "Unexpected cpu times with tracking off"); updateTrackPerProcStateCpuTimesSetting(bstatsConstants, true); final long[] cpuTimesMs3 = getAllCpuFreqTimes(sTestPkgUid, PROCESS_STATE_TOP); assertCpuTimesValid(cpuTimesMs3); assertCpuTimesEqual(cpuTimesMs3, cpuTimesMs, 500, "Unexpected cpu times after turning on tracking"); doSomeWork(PROCESS_STATE_TOP); forceStop(); final long[] cpuTimesMs4 = getAllCpuFreqTimes(sTestPkgUid, PROCESS_STATE_TOP); assertCpuTimesValid(cpuTimesMs4); actualCpuTimeMs = 0; for (int i = 0; i < cpuTimesMs4.length / 2; ++i) { actualCpuTimeMs += cpuTimesMs4[i]; } assertApproximateValue("Incorrect total cpu time, " + msgCpuTimes, 2 * WORK_DURATION_MS, actualCpuTimeMs); batteryOffScreenOn(); } finally { Settings.Global.putString(sContext.getContentResolver(), Settings.Global.BATTERY_STATS_CONSTANTS, bstatsConstants); } } private void assertCpuTimesEqual(long[] actual, long[] expected, long delta, String errMsg) { for (int i = actual.length - 1; i >= 0; --i) { if (actual[i] > expected[i] + delta || actual[i] < expected[i]) { fail(errMsg + ", actual=" + Arrays.toString(actual) + ", expected=" + Arrays.toString(expected) + ", delta=" + delta); } } } private void updateTrackPerProcStateCpuTimesSetting(String originalConstants, boolean enabled) throws Exception { final String newConstants; final String setting = KEY_TRACK_CPU_TIMES_BY_PROC_STATE + "=" + enabled; if (originalConstants == null || "null".equals(originalConstants)) { newConstants = setting; } else if (originalConstants.contains(KEY_TRACK_CPU_TIMES_BY_PROC_STATE)) { newConstants = originalConstants.replaceAll( KEY_TRACK_CPU_TIMES_BY_PROC_STATE + "=(true|false)", setting); } else { newConstants = originalConstants + "," + setting; } Settings.Global.putString(sContext.getContentResolver(), Settings.Global.BATTERY_STATS_CONSTANTS, newConstants); assertTrackPerProcStateCpuTimesSetting(enabled); } private void assertTrackPerProcStateCpuTimesSetting(boolean enabled) throws Exception { final String expectedValue = Boolean.toString(enabled); assertDelayedCondition("Unexpected value for " + KEY_TRACK_CPU_TIMES_BY_PROC_STATE, () -> { final String actualValue = getSettingValueFromDump(KEY_TRACK_CPU_TIMES_BY_PROC_STATE); return expectedValue.equals(actualValue) ? null : "expected=" + expectedValue + ", actual=" + actualValue; }, SETTING_UPDATE_TIMEOUT_MS, SETTING_UPDATE_CHECK_INTERVAL_MS); } private String getSettingValueFromDump(String key) throws Exception { final String settingsDump = executeCmdSilent("dumpsys batterystats --settings"); final TextUtils.SimpleStringSplitter splitter = new TextUtils.SimpleStringSplitter('\n'); splitter.setString(settingsDump); String next; while (splitter.hasNext()) { next = splitter.next().trim(); if (next.startsWith(key)) { return next.split("=")[1]; } } return null; } private void assertCpuTimesValid(long[] cpuTimes) { assertNotNull(cpuTimes); for (int i = 0; i < cpuTimes.length; ++i) { Loading Loading
core/java/android/os/BatteryStats.java +6 −11 Original line number Diff line number Diff line Loading @@ -634,7 +634,7 @@ public abstract class BatteryStats implements Parcelable { */ public static int mapToInternalProcessState(int procState) { if (procState == ActivityManager.PROCESS_STATE_NONEXISTENT) { return ActivityManager.PROCESS_STATE_NONEXISTENT; return Uid.PROCESS_STATE_NONEXISTENT; } else if (procState == ActivityManager.PROCESS_STATE_TOP) { return Uid.PROCESS_STATE_TOP; } else if (ActivityManager.isForegroundService(procState)) { Loading Loading @@ -911,6 +911,11 @@ public abstract class BatteryStats implements Parcelable { * Total number of process states we track. */ public static final int NUM_PROCESS_STATE = 7; /** * State of the UID when it has no running processes. It is intentionally out of * bounds 0..NUM_PROCESS_STATE. */ public static final int PROCESS_STATE_NONEXISTENT = NUM_PROCESS_STATE; // Used in dump static final String[] PROCESS_STATE_NAMES = { Loading @@ -930,16 +935,6 @@ public abstract class BatteryStats implements Parcelable { "C" // CACHED }; /** * When the process exits one of these states, we need to make sure cpu time in this state * is not attributed to any non-critical process states. */ public static final int[] CRITICAL_PROC_STATES = { Uid.PROCESS_STATE_TOP, Uid.PROCESS_STATE_FOREGROUND_SERVICE, Uid.PROCESS_STATE_FOREGROUND }; public abstract long getProcessStateTime(int state, long elapsedRealtimeUs, int which); public abstract Timer getProcessStateTimer(int state); Loading
core/java/com/android/internal/os/BatteryStatsImpl.java +90 −241 File changed.Preview size limit exceeded, changes collapsed. Show changes
core/java/com/android/internal/os/KernelCpuUidTimeReader.java +4 −0 Original line number Diff line number Diff line Loading @@ -620,6 +620,10 @@ public abstract class KernelCpuUidTimeReader<T> { } return numClusterFreqs; } public boolean isFastCpuTimesReader() { return mBpfTimesAvailable; } } /** Loading
core/tests/coretests/src/com/android/internal/os/BatteryStatsImplTest.java +52 −81 Original line number Diff line number Diff line Loading @@ -37,7 +37,6 @@ import static org.mockito.Mockito.when; import android.app.ActivityManager; import android.os.BatteryStats; import android.util.SparseArray; import android.util.SparseIntArray; import android.view.Display; import androidx.test.filters.LargeTest; Loading @@ -53,6 +52,7 @@ import org.mockito.MockitoAnnotations; @LargeTest @RunWith(AndroidJUnit4.class) @SuppressWarnings("GuardedBy") public class BatteryStatsImplTest { private static final long[] CPU_FREQS = {1, 2, 3, 4, 5}; private static final int NUM_CPU_FREQS = CPU_FREQS.length; Loading @@ -62,29 +62,26 @@ public class BatteryStatsImplTest { @Mock private KernelSingleUidTimeReader mKernelSingleUidTimeReader; private final MockClock mMockClock = new MockClock(); private MockBatteryStatsImpl mBatteryStatsImpl; private MockClock mMockClock = new MockClock(); @Before public void setUp() { MockitoAnnotations.initMocks(this); when(mKernelUidCpuFreqTimeReader.isFastCpuTimesReader()).thenReturn(true); when(mKernelUidCpuFreqTimeReader.readFreqs(any())).thenReturn(CPU_FREQS); when(mKernelUidCpuFreqTimeReader.allUidTimesAvailable()).thenReturn(true); when(mKernelSingleUidTimeReader.singleUidCpuTimesAvailable()).thenReturn(true); mBatteryStatsImpl = new MockBatteryStatsImpl(mMockClock) .setKernelCpuUidFreqTimeReader(mKernelUidCpuFreqTimeReader) .setKernelSingleUidTimeReader(mKernelSingleUidTimeReader) .setTrackingCpuByProcStateEnabled(true); .setKernelSingleUidTimeReader(mKernelSingleUidTimeReader); } @Test public void testUpdateProcStateCpuTimes() { mBatteryStatsImpl.setOnBatteryInternal(true); synchronized (mBatteryStatsImpl) { mBatteryStatsImpl.updateTimeBasesLocked(true, Display.STATE_ON, 0, 0); } final int[] testUids = {10032, 10048, 10145, 10139}; final int[] activityManagerProcStates = { Loading @@ -99,15 +96,24 @@ public class BatteryStatsImplTest { PROCESS_STATE_TOP, PROCESS_STATE_CACHED }; addPendingUids(testUids, testProcStates); // Initialize time-in-freq counters mMockClock.realtime = 1000; for (int i = 0; i < testUids.length; ++i) { mBatteryStatsImpl.noteUidProcessStateLocked(testUids[i], activityManagerProcStates[i]); mockKernelSingleUidTimeReader(testUids[i], new long[5]); mBatteryStatsImpl.noteUidProcessStateLocked(testUids[i], activityManagerProcStates[i]); } final long[] timeInFreqs = new long[NUM_CPU_FREQS]; // Verify there are no cpu times initially. for (int i = 0; i < testUids.length; ++i) { final BatteryStats.Uid u = mBatteryStatsImpl.getUidStatsLocked(testUids[i]); for (int procState = 0; procState < NUM_PROCESS_STATE; ++procState) { assertFalse(u.getCpuFreqTimes(timeInFreqs, procState)); assertFalse(u.getScreenOffCpuFreqTimes(timeInFreqs, procState)); } } mBatteryStatsImpl.updateProcStateCpuTimes(true, false); // Obtain initial CPU time-in-freq counts final long[][] cpuTimes = { Loading @@ -117,24 +123,14 @@ public class BatteryStatsImplTest { {4859048, 348903, 4578967, 5973894, 298549} }; final long[] timeInFreqs = new long[NUM_CPU_FREQS]; mMockClock.realtime += 1000; for (int i = 0; i < testUids.length; ++i) { mockKernelSingleUidTimeReader(testUids[i], cpuTimes[i]); // Verify there are no cpu times initially. final BatteryStats.Uid u = mBatteryStatsImpl.getUidStatsLocked(testUids[i]); for (int procState = 0; procState < NUM_PROCESS_STATE; ++procState) { assertFalse(u.getCpuFreqTimes(timeInFreqs, procState)); assertFalse(u.getScreenOffCpuFreqTimes(timeInFreqs, procState)); } mBatteryStatsImpl.updateProcStateCpuTimesLocked(testUids[i], mMockClock.realtime); } addPendingUids(testUids, testProcStates); mMockClock.realtime += 1000; mBatteryStatsImpl.updateProcStateCpuTimes(true, false); verifyNoPendingUids(); for (int i = 0; i < testUids.length; ++i) { final BatteryStats.Uid u = mBatteryStatsImpl.getUidStats().get(testUids[i]); for (int procState = 0; procState < NUM_PROCESS_STATE; ++procState) { Loading @@ -155,19 +151,19 @@ public class BatteryStatsImplTest { {945894, 9089432, 19478, 3834, 7845}, {843895, 43948, 949582, 99, 384} }; mMockClock.realtime += 1000; for (int i = 0; i < testUids.length; ++i) { long[] newCpuTimes = new long[cpuTimes[i].length]; for (int j = 0; j < cpuTimes[i].length; j++) { newCpuTimes[j] = cpuTimes[i][j] + delta1[i][j]; } mockKernelSingleUidTimeReader(testUids[i], newCpuTimes); mBatteryStatsImpl.updateProcStateCpuTimesLocked(testUids[i], mMockClock.realtime); } addPendingUids(testUids, testProcStates); mMockClock.realtime += 1000; mBatteryStatsImpl.updateProcStateCpuTimes(true, false); verifyNoPendingUids(); for (int i = 0; i < testUids.length; ++i) { final BatteryStats.Uid u = mBatteryStatsImpl.getUidStats().get(testUids[i]); for (int procState = 0; procState < NUM_PROCESS_STATE; ++procState) { Loading @@ -186,10 +182,8 @@ public class BatteryStatsImplTest { } // Validate the on-battery-screen-off counter synchronized (mBatteryStatsImpl) { mBatteryStatsImpl.updateTimeBasesLocked(true, Display.STATE_OFF, 0, mMockClock.realtime * 1000); } final long[][] delta2 = { {95932, 2943, 49834, 89034, 139}, Loading @@ -197,19 +191,19 @@ public class BatteryStatsImplTest { {678, 7498, 9843, 889, 4894}, {488, 998, 8498, 394, 574} }; mMockClock.realtime += 1000; for (int i = 0; i < testUids.length; ++i) { long[] newCpuTimes = new long[cpuTimes[i].length]; for (int j = 0; j < cpuTimes[i].length; j++) { newCpuTimes[j] = cpuTimes[i][j] + delta1[i][j] + delta2[i][j]; } mockKernelSingleUidTimeReader(testUids[i], newCpuTimes); mBatteryStatsImpl.updateProcStateCpuTimesLocked(testUids[i], mMockClock.realtime); } addPendingUids(testUids, testProcStates); mMockClock.realtime += 1000; mBatteryStatsImpl.updateProcStateCpuTimes(true, true); verifyNoPendingUids(); for (int i = 0; i < testUids.length; ++i) { final BatteryStats.Uid u = mBatteryStatsImpl.getUidStats().get(testUids[i]); for (int procState = 0; procState < NUM_PROCESS_STATE; ++procState) { Loading Loading @@ -239,24 +233,25 @@ public class BatteryStatsImplTest { {3049509483598l, 4597834, 377654, 94589035, 7854}, {9493, 784, 99895, 8974893, 9879843} }; mMockClock.realtime += 1000; final int parentUid = testUids[1]; final int childUid = 99099; addIsolatedUid(parentUid, childUid); final long[] isolatedUidCpuTimes = {495784, 398473, 4895, 4905, 30984093}; mockKernelSingleUidTimeReader(childUid, isolatedUidCpuTimes, isolatedUidCpuTimes); for (int i = 0; i < testUids.length; ++i) { long[] newCpuTimes = new long[cpuTimes[i].length]; for (int j = 0; j < cpuTimes[i].length; j++) { newCpuTimes[j] = cpuTimes[i][j] + delta1[i][j] + delta2[i][j] + delta3[i][j]; } mockKernelSingleUidTimeReader(testUids[i], newCpuTimes); mBatteryStatsImpl.updateProcStateCpuTimesLocked(testUids[i], mMockClock.realtime); } addPendingUids(testUids, testProcStates); final int parentUid = testUids[1]; final int childUid = 99099; addIsolatedUid(parentUid, childUid); final long[] isolatedUidCpuTimes = {495784, 398473, 4895, 4905, 30984093}; mockKernelSingleUidTimeReader(childUid, isolatedUidCpuTimes, isolatedUidCpuTimes); mMockClock.realtime += 1000; mBatteryStatsImpl.updateProcStateCpuTimes(true, true); verifyNoPendingUids(); for (int i = 0; i < testUids.length; ++i) { final BatteryStats.Uid u = mBatteryStatsImpl.getUidStats().get(testUids[i]); for (int procState = 0; procState < NUM_PROCESS_STATE; ++procState) { Loading Loading @@ -284,11 +279,9 @@ public class BatteryStatsImplTest { } @Test public void testCopyFromAllUidsCpuTimes() { public void testUpdateCpuTimesForAllUids() { mBatteryStatsImpl.setOnBatteryInternal(false); synchronized (mBatteryStatsImpl) { mBatteryStatsImpl.updateTimeBasesLocked(true, Display.STATE_ON, 0, 0); } mMockClock.realtime = 1000; Loading @@ -299,14 +292,14 @@ public class BatteryStatsImplTest { PROCESS_STATE_TOP, PROCESS_STATE_CACHED }; addPendingUids(testUids, testProcStates); for (int i = 0; i < testUids.length; ++i) { BatteryStatsImpl.Uid uid = mBatteryStatsImpl.getUidStatsLocked(testUids[i]); uid.setProcessStateForTest(testProcStates[i], mMockClock.elapsedRealtime()); mockKernelSingleUidTimeReader(testUids[i], new long[NUM_CPU_FREQS]); mBatteryStatsImpl.updateProcStateCpuTimesLocked(testUids[i], mMockClock.elapsedRealtime()); } mBatteryStatsImpl.updateProcStateCpuTimes(true, false); final SparseArray<long[]> allUidCpuTimes = new SparseArray<>(); long[][] allCpuTimes = { Loading @@ -330,9 +323,8 @@ public class BatteryStatsImplTest { } mMockClock.realtime += 1000; mBatteryStatsImpl.copyFromAllUidsCpuTimes(true, false); verifyNoPendingUids(); mBatteryStatsImpl.updateCpuTimesForAllUids(); final long[] timeInFreqs = new long[NUM_CPU_FREQS]; Loading Loading @@ -411,9 +403,7 @@ public class BatteryStatsImplTest { final int releaseTimeMs = 1005; final int currentTimeMs = 1011; synchronized (mBatteryStatsImpl) { mBatteryStatsImpl.updateTimeBasesLocked(true, Display.STATE_OFF, 0, 0); } // Create a Uid Object final BatteryStats.Uid u = mBatteryStatsImpl.getUidStatsLocked(testUid); Loading @@ -436,9 +426,7 @@ public class BatteryStatsImplTest { final int acquireTimeMs = 1000; final int currentTimeMs = 1011; synchronized (mBatteryStatsImpl) { mBatteryStatsImpl.updateTimeBasesLocked(true, Display.STATE_OFF, 0, 0); } // Create a Uid Object final BatteryStats.Uid u = mBatteryStatsImpl.getUidStatsLocked(testUid); Loading @@ -464,9 +452,7 @@ public class BatteryStatsImplTest { final int releaseTimeMs_2 = 1009; final int currentTimeMs = 1011; synchronized (mBatteryStatsImpl) { mBatteryStatsImpl.updateTimeBasesLocked(true, Display.STATE_OFF, 0, 0); } // Create a Uid Object final BatteryStats.Uid u = mBatteryStatsImpl.getUidStatsLocked(testUid); Loading Loading @@ -496,9 +482,7 @@ public class BatteryStatsImplTest { final int releaseTimeMs_2 = 1009; final int currentTimeMs = 1011; synchronized (mBatteryStatsImpl) { mBatteryStatsImpl.updateTimeBasesLocked(true, Display.STATE_OFF, 0, 0); } // Create a Uid Object final BatteryStats.Uid u = mBatteryStatsImpl.getUidStatsLocked(testUid); Loading @@ -523,17 +507,4 @@ public class BatteryStatsImplTest { final BatteryStatsImpl.Uid u = mBatteryStatsImpl.getUidStatsLocked(parentUid); u.addIsolatedUid(childUid); } private void addPendingUids(int[] uids, int[] procStates) { final SparseIntArray pendingUids = mBatteryStatsImpl.getPendingUids(); for (int i = 0; i < uids.length; ++i) { pendingUids.put(uids[i], procStates[i]); } } private void verifyNoPendingUids() { final SparseIntArray pendingUids = mBatteryStatsImpl.getPendingUids(); assertEquals("There shouldn't be any pending uids left: " + pendingUids, 0, pendingUids.size()); } }
core/tests/coretests/src/com/android/internal/os/BstatsCpuTimesValidationTest.java +0 −128 Original line number Diff line number Diff line Loading @@ -26,9 +26,6 @@ import static android.os.BatteryStats.Uid.PROCESS_STATE_TOP; import static android.os.BatteryStats.Uid.PROCESS_STATE_TOP_SLEEPING; import static android.os.BatteryStats.Uid.UID_PROCESS_TYPES; import static com.android.internal.os.BatteryStatsImpl.Constants.KEY_PROC_STATE_CPU_TIMES_READ_DELAY_MS; import static com.android.internal.os.BatteryStatsImpl.Constants.KEY_TRACK_CPU_TIMES_BY_PROC_STATE; import static junit.framework.Assert.assertNotNull; import static junit.framework.Assert.assertNull; import static junit.framework.Assert.assertTrue; Loading @@ -51,7 +48,6 @@ import android.os.Process; import android.os.SystemClock; import android.provider.Settings; import android.support.test.uiautomator.UiDevice; import android.text.TextUtils; import android.util.ArrayMap; import android.util.DebugUtils; import android.util.KeyValueListParser; Loading Loading @@ -125,11 +121,6 @@ public class BstatsCpuTimesValidationTest { PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0); sTestPkgUid = sContext.getPackageManager().getPackageUid(TEST_PKG, 0); executeCmd("cmd deviceidle whitelist +" + TEST_PKG); final ArrayMap<String, String> desiredConstants = new ArrayMap<>(); desiredConstants.put(KEY_TRACK_CPU_TIMES_BY_PROC_STATE, Boolean.toString(true)); desiredConstants.put(KEY_PROC_STATE_CPU_TIMES_READ_DELAY_MS, Integer.toString(0)); updateBatteryStatsConstants(desiredConstants); checkCpuTimesAvailability(); } Loading Loading @@ -517,125 +508,6 @@ public class BstatsCpuTimesValidationTest { batteryOffScreenOn(); } @Test public void testCpuFreqTimes_trackingDisabled() throws Exception { if (!sCpuFreqTimesAvailable || !sPerProcStateTimesAvailable) { Log.w(TAG, "Skipping " + testName.getMethodName() + "; freqTimesAvailable=" + sCpuFreqTimesAvailable + ", procStateTimesAvailable=" + sPerProcStateTimesAvailable); return; } final String bstatsConstants = Settings.Global.getString(sContext.getContentResolver(), Settings.Global.BATTERY_STATS_CONSTANTS); try { batteryOnScreenOn(); forceStop(); resetBatteryStats(); final long[] initialSnapshot = getAllCpuFreqTimes(sTestPkgUid); assertNull("Initial snapshot should be null, initial=" + Arrays.toString(initialSnapshot), initialSnapshot); assertNull("Initial top state snapshot should be null", getAllCpuFreqTimes(sTestPkgUid, PROCESS_STATE_TOP)); doSomeWork(PROCESS_STATE_TOP); forceStop(); final long[] cpuTimesMs = getAllCpuFreqTimes(sTestPkgUid, PROCESS_STATE_TOP); final String msgCpuTimes = getAllCpuTimesMsg(); assertCpuTimesValid(cpuTimesMs); long actualCpuTimeMs = 0; for (int i = 0; i < cpuTimesMs.length / 2; ++i) { actualCpuTimeMs += cpuTimesMs[i]; } assertApproximateValue("Incorrect total cpu time, " + msgCpuTimes, WORK_DURATION_MS, actualCpuTimeMs); updateTrackPerProcStateCpuTimesSetting(bstatsConstants, false); doSomeWork(PROCESS_STATE_TOP); forceStop(); final long[] cpuTimesMs2 = getAllCpuFreqTimes(sTestPkgUid, PROCESS_STATE_TOP); assertCpuTimesValid(cpuTimesMs2); assertCpuTimesEqual(cpuTimesMs2, cpuTimesMs, 20, "Unexpected cpu times with tracking off"); updateTrackPerProcStateCpuTimesSetting(bstatsConstants, true); final long[] cpuTimesMs3 = getAllCpuFreqTimes(sTestPkgUid, PROCESS_STATE_TOP); assertCpuTimesValid(cpuTimesMs3); assertCpuTimesEqual(cpuTimesMs3, cpuTimesMs, 500, "Unexpected cpu times after turning on tracking"); doSomeWork(PROCESS_STATE_TOP); forceStop(); final long[] cpuTimesMs4 = getAllCpuFreqTimes(sTestPkgUid, PROCESS_STATE_TOP); assertCpuTimesValid(cpuTimesMs4); actualCpuTimeMs = 0; for (int i = 0; i < cpuTimesMs4.length / 2; ++i) { actualCpuTimeMs += cpuTimesMs4[i]; } assertApproximateValue("Incorrect total cpu time, " + msgCpuTimes, 2 * WORK_DURATION_MS, actualCpuTimeMs); batteryOffScreenOn(); } finally { Settings.Global.putString(sContext.getContentResolver(), Settings.Global.BATTERY_STATS_CONSTANTS, bstatsConstants); } } private void assertCpuTimesEqual(long[] actual, long[] expected, long delta, String errMsg) { for (int i = actual.length - 1; i >= 0; --i) { if (actual[i] > expected[i] + delta || actual[i] < expected[i]) { fail(errMsg + ", actual=" + Arrays.toString(actual) + ", expected=" + Arrays.toString(expected) + ", delta=" + delta); } } } private void updateTrackPerProcStateCpuTimesSetting(String originalConstants, boolean enabled) throws Exception { final String newConstants; final String setting = KEY_TRACK_CPU_TIMES_BY_PROC_STATE + "=" + enabled; if (originalConstants == null || "null".equals(originalConstants)) { newConstants = setting; } else if (originalConstants.contains(KEY_TRACK_CPU_TIMES_BY_PROC_STATE)) { newConstants = originalConstants.replaceAll( KEY_TRACK_CPU_TIMES_BY_PROC_STATE + "=(true|false)", setting); } else { newConstants = originalConstants + "," + setting; } Settings.Global.putString(sContext.getContentResolver(), Settings.Global.BATTERY_STATS_CONSTANTS, newConstants); assertTrackPerProcStateCpuTimesSetting(enabled); } private void assertTrackPerProcStateCpuTimesSetting(boolean enabled) throws Exception { final String expectedValue = Boolean.toString(enabled); assertDelayedCondition("Unexpected value for " + KEY_TRACK_CPU_TIMES_BY_PROC_STATE, () -> { final String actualValue = getSettingValueFromDump(KEY_TRACK_CPU_TIMES_BY_PROC_STATE); return expectedValue.equals(actualValue) ? null : "expected=" + expectedValue + ", actual=" + actualValue; }, SETTING_UPDATE_TIMEOUT_MS, SETTING_UPDATE_CHECK_INTERVAL_MS); } private String getSettingValueFromDump(String key) throws Exception { final String settingsDump = executeCmdSilent("dumpsys batterystats --settings"); final TextUtils.SimpleStringSplitter splitter = new TextUtils.SimpleStringSplitter('\n'); splitter.setString(settingsDump); String next; while (splitter.hasNext()) { next = splitter.next().trim(); if (next.startsWith(key)) { return next.split("=")[1]; } } return null; } private void assertCpuTimesValid(long[] cpuTimes) { assertNotNull(cpuTimes); for (int i = 0; i < cpuTimes.length; ++i) { Loading