Loading core/java/com/android/internal/os/BatteryStatsImpl.java +63 −60 Original line number Diff line number Diff line Loading @@ -967,14 +967,15 @@ public class BatteryStatsImpl extends BatteryStats { } } @VisibleForTesting public static class LongSamplingCounterArray extends LongCounterArray implements TimeBaseObs { final TimeBase mTimeBase; long[] mCounts; long[] mLoadedCounts; long[] mUnpluggedCounts; long[] mPluggedCounts; public long[] mCounts; public long[] mLoadedCounts; public long[] mUnpluggedCounts; public long[] mPluggedCounts; LongSamplingCounterArray(TimeBase timeBase, Parcel in) { private LongSamplingCounterArray(TimeBase timeBase, Parcel in) { mTimeBase = timeBase; mPluggedCounts = in.createLongArray(); mCounts = copyArray(mPluggedCounts, mCounts); Loading @@ -983,12 +984,12 @@ public class BatteryStatsImpl extends BatteryStats { timeBase.add(this); } LongSamplingCounterArray(TimeBase timeBase) { public LongSamplingCounterArray(TimeBase timeBase) { mTimeBase = timeBase; timeBase.add(this); } public void writeToParcel(Parcel out) { private void writeToParcel(Parcel out) { out.writeLongArray(mCounts); out.writeLongArray(mLoadedCounts); out.writeLongArray(mUnpluggedCounts); Loading Loading @@ -1024,7 +1025,7 @@ public class BatteryStatsImpl extends BatteryStats { + " mPluggedCounts=" + Arrays.toString(mPluggedCounts)); } void addCountLocked(long[] counts) { public void addCountLocked(long[] counts) { if (counts == null) { return; } Loading @@ -1039,7 +1040,7 @@ public class BatteryStatsImpl extends BatteryStats { /** * Clear state of this counter. */ void reset(boolean detachIfReset) { public void reset(boolean detachIfReset) { fillArray(mCounts, 0); fillArray(mLoadedCounts, 0); fillArray(mPluggedCounts, 0); Loading @@ -1049,21 +1050,60 @@ public class BatteryStatsImpl extends BatteryStats { } } void detach() { public void detach() { mTimeBase.remove(this); } void writeSummaryFromParcelLocked(Parcel out) { private void writeSummaryToParcelLocked(Parcel out) { out.writeLongArray(mCounts); } void readSummaryFromParcelLocked(Parcel in) { private void readSummaryFromParcelLocked(Parcel in) { mCounts = in.createLongArray(); mLoadedCounts = copyArray(mCounts, mLoadedCounts); mUnpluggedCounts = copyArray(mCounts, mUnpluggedCounts); mPluggedCounts = copyArray(mCounts, mPluggedCounts); } public static void writeToParcel(Parcel out, LongSamplingCounterArray counterArray) { if (counterArray != null) { out.writeInt(1); counterArray.writeToParcel(out); } else { out.writeInt(0); } } public static LongSamplingCounterArray readFromParcel(Parcel in, TimeBase timeBase) { if (in.readInt() != 0) { return new LongSamplingCounterArray(timeBase, in); } else { return null; } } public static void writeSummaryToParcelLocked(Parcel out, LongSamplingCounterArray counterArray) { if (counterArray != null) { out.writeInt(1); counterArray.writeSummaryToParcelLocked(out); } else { out.writeInt(0); } } public static LongSamplingCounterArray readSummaryFromParcelLocked(Parcel in, TimeBase timeBase) { if (in.readInt() != 0) { final LongSamplingCounterArray counterArray = new LongSamplingCounterArray(timeBase); counterArray.readSummaryFromParcelLocked(in); return counterArray; } else { return null; } } private void fillArray(long[] a, long val) { if (a != null) { Arrays.fill(a, val); Loading Loading @@ -6927,18 +6967,8 @@ public class BatteryStatsImpl extends BatteryStats { out.writeInt(0); } if (mCpuFreqTimeMs != null) { out.writeInt(1); mCpuFreqTimeMs.writeToParcel(out); } else { out.writeInt(0); } if (mScreenOffCpuFreqTimeMs != null) { out.writeInt(1); mScreenOffCpuFreqTimeMs.writeToParcel(out); } else { out.writeInt(0); } LongSamplingCounterArray.writeToParcel(out, mCpuFreqTimeMs); LongSamplingCounterArray.writeToParcel(out, mScreenOffCpuFreqTimeMs); if (mMobileRadioApWakeupCount != null) { out.writeInt(1); Loading Loading @@ -7187,17 +7217,9 @@ public class BatteryStatsImpl extends BatteryStats { mCpuClusterSpeed = null; } if (in.readInt() != 0) { mCpuFreqTimeMs = new LongSamplingCounterArray(mBsi.mOnBatteryTimeBase, in); } else { mCpuFreqTimeMs = null; } if (in.readInt() != 0) { mScreenOffCpuFreqTimeMs = new LongSamplingCounterArray( mBsi.mOnBatteryScreenOffTimeBase, in); } else { mScreenOffCpuFreqTimeMs = null; } mCpuFreqTimeMs = LongSamplingCounterArray.readFromParcel(in, mBsi.mOnBatteryTimeBase); mScreenOffCpuFreqTimeMs = LongSamplingCounterArray.readFromParcel( in, mBsi.mOnBatteryScreenOffTimeBase); if (in.readInt() != 0) { mMobileRadioApWakeupCount = new LongSamplingCounter(mBsi.mOnBatteryTimeBase, in); Loading Loading @@ -11355,19 +11377,10 @@ public class BatteryStatsImpl extends BatteryStats { u.mCpuClusterSpeed = null; } if (in.readInt() != 0) { u.mCpuFreqTimeMs = new LongSamplingCounterArray(mOnBatteryTimeBase); u.mCpuFreqTimeMs.readSummaryFromParcelLocked(in); } else { u.mCpuFreqTimeMs = null; } if (in.readInt() != 0) { u.mScreenOffCpuFreqTimeMs = new LongSamplingCounterArray( mOnBatteryScreenOffTimeBase); u.mScreenOffCpuFreqTimeMs.readSummaryFromParcelLocked(in); } else { u.mScreenOffCpuFreqTimeMs = null; } u.mCpuFreqTimeMs = LongSamplingCounterArray.readSummaryFromParcelLocked( in, mOnBatteryTimeBase); u.mScreenOffCpuFreqTimeMs = LongSamplingCounterArray.readSummaryFromParcelLocked( in, mOnBatteryScreenOffTimeBase); if (in.readInt() != 0) { u.mMobileRadioApWakeupCount = new LongSamplingCounter(mOnBatteryTimeBase); Loading Loading @@ -11765,18 +11778,8 @@ public class BatteryStatsImpl extends BatteryStats { out.writeInt(0); } if (u.mCpuFreqTimeMs != null) { out.writeInt(1); u.mCpuFreqTimeMs.writeSummaryFromParcelLocked(out); } else { out.writeInt(0); } if (u.mScreenOffCpuFreqTimeMs != null) { out.writeInt(1); u.mScreenOffCpuFreqTimeMs.writeSummaryFromParcelLocked(out); } else { out.writeInt(0); } LongSamplingCounterArray.writeSummaryToParcelLocked(out, u.mCpuFreqTimeMs); LongSamplingCounterArray.writeSummaryToParcelLocked(out, u.mScreenOffCpuFreqTimeMs); if (u.mMobileRadioApWakeupCount != null) { out.writeInt(1); Loading core/tests/coretests/src/com/android/internal/os/KernelUidCpuFreqTimeReaderTest.java +61 −6 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ package com.android.internal.os; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyNoMoreInteractions; import static org.mockito.Mockito.verifyZeroInteractions; import static org.mockito.Mockito.when; import android.support.test.filters.SmallTest; Loading @@ -27,6 +28,7 @@ import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.MockitoAnnotations; import java.io.BufferedReader; Loading Loading @@ -70,18 +72,70 @@ public class KernelUidCpuFreqTimeReaderTest { times[i][j] = uids[i] * freqs[j] * 10; } } final String[] uidsTimesLines = getUidTimesLines(uids, times); final String[] lines = new String[uidsTimesLines.length + 1]; System.arraycopy(uidsTimesLines, 0, lines, 0, uidsTimesLines.length); lines[uidsTimesLines.length] = null; when(mBufferedReader.readLine()) .thenReturn(getFreqsLine(freqs), lines); .thenReturn(getFreqsLine(freqs), getUidTimesLines(uids, times)); mKernelUidCpuFreqTimeReader.readDelta(mBufferedReader, mCallback); verify(mCallback).onCpuFreqs(freqs); for (int i = 0; i < uids.length; ++i) { verify(mCallback).onUidCpuFreqTime(uids[i], times[i]); } verifyNoMoreInteractions(mCallback); // Verify that a second call will only return deltas. Mockito.reset(mCallback, mBufferedReader); final long[][] newTimes1 = new long[uids.length][freqs.length]; for (int i = 0; i < uids.length; ++i) { for (int j = 0; j < freqs.length; ++j) { newTimes1[i][j] = (times[i][j] + uids[i] + freqs[j]) * 10; } } when(mBufferedReader.readLine()) .thenReturn(getFreqsLine(freqs), getUidTimesLines(uids, newTimes1)); mKernelUidCpuFreqTimeReader.readDelta(mBufferedReader, mCallback); verify(mCallback).onCpuFreqs(freqs); for (int i = 0; i < uids.length; ++i) { verify(mCallback).onUidCpuFreqTime(uids[i], subtract(newTimes1[i], times[i])); } verifyNoMoreInteractions(mCallback); // Verify that calling with a null callback doesn't result in any crashes Mockito.reset(mCallback, mBufferedReader); final long[][] newTimes2 = new long[uids.length][freqs.length]; for (int i = 0; i < uids.length; ++i) { for (int j = 0; j < freqs.length; ++j) { newTimes2[i][j] = (newTimes1[i][j] + uids[i] * freqs[j]) * 10; } } when(mBufferedReader.readLine()) .thenReturn(getFreqsLine(freqs), getUidTimesLines(uids, newTimes2)); mKernelUidCpuFreqTimeReader.readDelta(mBufferedReader, null); verifyZeroInteractions(mCallback); // Verify that the readDelta call will only return deltas when // the previous call had null callback. Mockito.reset(mCallback, mBufferedReader); final long[][] newTimes3 = new long[uids.length][freqs.length]; for (int i = 0; i < uids.length; ++i) { for (int j = 0; j < freqs.length; ++j) { newTimes3[i][j] = (newTimes2[i][j] * (uids[i] + freqs[j])) * 10; } } when(mBufferedReader.readLine()) .thenReturn(getFreqsLine(freqs), getUidTimesLines(uids, newTimes3)); mKernelUidCpuFreqTimeReader.readDelta(mBufferedReader, mCallback); verify(mCallback).onCpuFreqs(freqs); for (int i = 0; i < uids.length; ++i) { verify(mCallback).onUidCpuFreqTime(uids[i], subtract(newTimes3[i], newTimes2[i])); } verifyNoMoreInteractions(mCallback); } private long[] subtract(long[] a1, long[] a2) { long[] val = new long[a1.length]; for (int i = 0; i < val.length; ++i) { val[i] = a1[i] - a2[i]; } return val; } private String getFreqsLine(long[] freqs) { Loading @@ -94,7 +148,7 @@ public class KernelUidCpuFreqTimeReaderTest { } private String[] getUidTimesLines(int[] uids, long[][] times) { final String[] lines = new String[uids.length]; final String[] lines = new String[uids.length + 1]; final StringBuilder sb = new StringBuilder(); for (int i = 0; i < uids.length; ++i) { sb.setLength(0); Loading @@ -104,6 +158,7 @@ public class KernelUidCpuFreqTimeReaderTest { } lines[i] = sb.toString(); } lines[uids.length] = null; return lines; } } core/tests/coretests/src/com/android/internal/os/LongSamplingCounterArrayTest.java 0 → 100644 +217 −0 Original line number Diff line number Diff line /* * Copyright (C) 2017 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.internal.os; import static android.os.BatteryStats.STATS_SINCE_CHARGED; import static com.android.internal.os.BatteryStatsImpl.LongSamplingCounterArray; import static com.android.internal.os.BatteryStatsImpl.TimeBase; import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyNoMoreInteractions; import static org.mockito.Mockito.verifyZeroInteractions; import static org.mockito.Mockito.when; import android.os.Parcel; import android.support.test.filters.SmallTest; import android.support.test.runner.AndroidJUnit4; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.MockitoAnnotations; import java.util.Arrays; /** * Test class for {@link BatteryStatsImpl.LongSamplingCounterArray}. * * To run the tests, use * * runtest -c com.android.internal.os.LongSamplingCounterArrayTest frameworks-core * * or the following steps: * * Build: m FrameworksCoreTests * Install: adb install -r \ * ${ANDROID_PRODUCT_OUT}/data/app/FrameworksCoreTests/FrameworksCoreTests.apk * Run: adb shell am instrument -e class com.android.internal.os.LongSamplingCounterArrayTest -w \ * com.android.frameworks.coretests/android.support.test.runner.AndroidJUnitRunner */ @SmallTest @RunWith(AndroidJUnit4.class) public class LongSamplingCounterArrayTest { private static final long[] COUNTS = {1111, 2222, 3333, 4444}; private static final long[] LOADED_COUNTS = {5555, 6666, 7777, 8888}; private static final long[] PLUGGED_COUNTS = {9999, 11111, 22222, 33333}; private static final long[] UNPLUGGED_COUNTS = {44444, 55555, 66666, 77777}; private static final long[] ZEROES = {0, 0, 0, 0}; @Mock private TimeBase mTimeBase; private LongSamplingCounterArray mCounterArray; @Before public void setUp() { MockitoAnnotations.initMocks(this); mCounterArray = new LongSamplingCounterArray(mTimeBase); Mockito.reset(mTimeBase); } @Test public void testReadWriteParcel() { final Parcel parcel = Parcel.obtain(); initializeCounterArrayWithDefaultValues(); LongSamplingCounterArray.writeToParcel(parcel, mCounterArray); parcel.setDataPosition(0); // Now clear counterArray and verify values are read from parcel correctly. updateCounts(null, null, null, null); mCounterArray = LongSamplingCounterArray.readFromParcel(parcel, mTimeBase); assertArrayEquals(COUNTS, mCounterArray.mCounts, "Unexpected counts"); assertArrayEquals(LOADED_COUNTS, mCounterArray.mLoadedCounts, "Unexpected loadedCounts"); assertArrayEquals(COUNTS, mCounterArray.mPluggedCounts, "Unexpected pluggedCounts"); assertArrayEquals(UNPLUGGED_COUNTS, mCounterArray.mUnpluggedCounts, "Unexpected unpluggedCounts"); parcel.recycle(); } @Test public void testReadWriteSummaryParcel() { final Parcel parcel = Parcel.obtain(); initializeCounterArrayWithDefaultValues(); LongSamplingCounterArray.writeSummaryToParcelLocked(parcel, mCounterArray); parcel.setDataPosition(0); // Now clear counterArray and verify values are read from parcel correctly. updateCounts(null, null, null, null); mCounterArray = LongSamplingCounterArray.readSummaryFromParcelLocked(parcel, mTimeBase); assertArrayEquals(COUNTS, mCounterArray.mCounts, "Unexpected counts"); assertArrayEquals(COUNTS, mCounterArray.mLoadedCounts, "Unexpected loadedCounts"); assertArrayEquals(COUNTS, mCounterArray.mPluggedCounts, "Unexpected pluggedCounts"); assertArrayEquals(COUNTS, mCounterArray.mUnpluggedCounts, "Unexpected unpluggedCounts"); parcel.recycle(); } @Test public void testOnTimeStarted() { initializeCounterArrayWithDefaultValues(); mCounterArray.onTimeStarted(0, 0, 0); assertArrayEquals(PLUGGED_COUNTS, mCounterArray.mCounts, "Unexpected counts"); assertArrayEquals(LOADED_COUNTS, mCounterArray.mLoadedCounts, "Unexpected loadedCounts"); assertArrayEquals(PLUGGED_COUNTS, mCounterArray.mPluggedCounts, "Unexpected pluggedCounts"); assertArrayEquals(PLUGGED_COUNTS, mCounterArray.mUnpluggedCounts, "Unexpected unpluggedCounts"); } @Test public void testOnTimeStopped() { initializeCounterArrayWithDefaultValues(); mCounterArray.onTimeStopped(0, 0, 0); assertArrayEquals(COUNTS, mCounterArray.mCounts, "Unexpected counts"); assertArrayEquals(LOADED_COUNTS, mCounterArray.mLoadedCounts, "Unexpected loadedCounts"); assertArrayEquals(COUNTS, mCounterArray.mPluggedCounts, "Unexpected pluggedCounts"); assertArrayEquals(UNPLUGGED_COUNTS, mCounterArray.mUnpluggedCounts, "Unexpected unpluggedCounts"); } @Test public void testGetCountsLocked() { initializeCounterArrayWithDefaultValues(); when(mTimeBase.isRunning()).thenReturn(false); long[] actualVal = mCounterArray.getCountsLocked(STATS_SINCE_CHARGED); long[] expectedVal = PLUGGED_COUNTS; assertArrayEquals(expectedVal, actualVal, "Unexpected values"); when(mTimeBase.isRunning()).thenReturn(true); actualVal = mCounterArray.getCountsLocked(STATS_SINCE_CHARGED); expectedVal = COUNTS; assertArrayEquals(expectedVal, actualVal, "Unexpected values"); } @Test public void testAddCountLocked() { final long[] deltas = {123, 234, 345, 456}; mCounterArray.addCountLocked(deltas); assertArrayEquals(deltas, mCounterArray.mCounts, "Unexpected counts"); assertArrayEquals(null, mCounterArray.mLoadedCounts, "Unexpected loadedCounts"); assertArrayEquals(null, mCounterArray.mPluggedCounts, "Unexpected pluggedCounts"); assertArrayEquals(null, mCounterArray.mUnpluggedCounts, "Unexpected unpluggedCounts"); initializeCounterArrayWithDefaultValues(); final long[] newCounts = new long[deltas.length]; for (int i = 0; i < deltas.length; ++i) { newCounts[i] = COUNTS[i] + deltas[i]; } mCounterArray.addCountLocked(deltas); assertArrayEquals(newCounts, mCounterArray.mCounts, "Unexpected counts"); assertArrayEquals(LOADED_COUNTS, mCounterArray.mLoadedCounts, "Unexpected loadedCounts"); assertArrayEquals(PLUGGED_COUNTS, mCounterArray.mPluggedCounts, "Unexpected pluggedCounts"); assertArrayEquals(UNPLUGGED_COUNTS, mCounterArray.mUnpluggedCounts, "Unexpected unpluggedCounts"); } @Test public void testReset() { initializeCounterArrayWithDefaultValues(); // Test with detachIfReset=false mCounterArray.reset(false /* detachIfReset */); assertArrayEquals(ZEROES, mCounterArray.mCounts, "Unexpected counts"); assertArrayEquals(ZEROES, mCounterArray.mLoadedCounts, "Unexpected loadedCounts"); assertArrayEquals(ZEROES, mCounterArray.mPluggedCounts, "Unexpected pluggedCounts"); assertArrayEquals(ZEROES, mCounterArray.mUnpluggedCounts, "Unexpected unpluggedCounts"); verifyZeroInteractions(mTimeBase); initializeCounterArrayWithDefaultValues(); // Test with detachIfReset=true mCounterArray.reset(true /* detachIfReset */); assertArrayEquals(ZEROES, mCounterArray.mCounts, "Unexpected counts"); assertArrayEquals(ZEROES, mCounterArray.mLoadedCounts, "Unexpected loadedCounts"); assertArrayEquals(ZEROES, mCounterArray.mPluggedCounts, "Unexpected pluggedCounts"); assertArrayEquals(ZEROES, mCounterArray.mUnpluggedCounts, "Unexpected unpluggedCounts"); verify(mTimeBase).remove(mCounterArray); verifyNoMoreInteractions(mTimeBase); } @Test public void testDetach() { mCounterArray.detach(); verify(mTimeBase).remove(mCounterArray); verifyNoMoreInteractions(mTimeBase); } private void initializeCounterArrayWithDefaultValues() { updateCounts(COUNTS, LOADED_COUNTS, PLUGGED_COUNTS, UNPLUGGED_COUNTS); } private void assertArrayEquals(long[] expected, long[] actual, String msg) { assertTrue(msg + ", expected: " + Arrays.toString(expected) + ", actual: " + Arrays.toString(actual), Arrays.equals(expected, actual)); } private void updateCounts(long[] counts, long[] loadedCounts, long[] pluggedCounts, long[] unpluggedCounts) { mCounterArray.mCounts = counts; mCounterArray.mLoadedCounts = loadedCounts; mCounterArray.mPluggedCounts = pluggedCounts; mCounterArray.mUnpluggedCounts = unpluggedCounts; } } Loading
core/java/com/android/internal/os/BatteryStatsImpl.java +63 −60 Original line number Diff line number Diff line Loading @@ -967,14 +967,15 @@ public class BatteryStatsImpl extends BatteryStats { } } @VisibleForTesting public static class LongSamplingCounterArray extends LongCounterArray implements TimeBaseObs { final TimeBase mTimeBase; long[] mCounts; long[] mLoadedCounts; long[] mUnpluggedCounts; long[] mPluggedCounts; public long[] mCounts; public long[] mLoadedCounts; public long[] mUnpluggedCounts; public long[] mPluggedCounts; LongSamplingCounterArray(TimeBase timeBase, Parcel in) { private LongSamplingCounterArray(TimeBase timeBase, Parcel in) { mTimeBase = timeBase; mPluggedCounts = in.createLongArray(); mCounts = copyArray(mPluggedCounts, mCounts); Loading @@ -983,12 +984,12 @@ public class BatteryStatsImpl extends BatteryStats { timeBase.add(this); } LongSamplingCounterArray(TimeBase timeBase) { public LongSamplingCounterArray(TimeBase timeBase) { mTimeBase = timeBase; timeBase.add(this); } public void writeToParcel(Parcel out) { private void writeToParcel(Parcel out) { out.writeLongArray(mCounts); out.writeLongArray(mLoadedCounts); out.writeLongArray(mUnpluggedCounts); Loading Loading @@ -1024,7 +1025,7 @@ public class BatteryStatsImpl extends BatteryStats { + " mPluggedCounts=" + Arrays.toString(mPluggedCounts)); } void addCountLocked(long[] counts) { public void addCountLocked(long[] counts) { if (counts == null) { return; } Loading @@ -1039,7 +1040,7 @@ public class BatteryStatsImpl extends BatteryStats { /** * Clear state of this counter. */ void reset(boolean detachIfReset) { public void reset(boolean detachIfReset) { fillArray(mCounts, 0); fillArray(mLoadedCounts, 0); fillArray(mPluggedCounts, 0); Loading @@ -1049,21 +1050,60 @@ public class BatteryStatsImpl extends BatteryStats { } } void detach() { public void detach() { mTimeBase.remove(this); } void writeSummaryFromParcelLocked(Parcel out) { private void writeSummaryToParcelLocked(Parcel out) { out.writeLongArray(mCounts); } void readSummaryFromParcelLocked(Parcel in) { private void readSummaryFromParcelLocked(Parcel in) { mCounts = in.createLongArray(); mLoadedCounts = copyArray(mCounts, mLoadedCounts); mUnpluggedCounts = copyArray(mCounts, mUnpluggedCounts); mPluggedCounts = copyArray(mCounts, mPluggedCounts); } public static void writeToParcel(Parcel out, LongSamplingCounterArray counterArray) { if (counterArray != null) { out.writeInt(1); counterArray.writeToParcel(out); } else { out.writeInt(0); } } public static LongSamplingCounterArray readFromParcel(Parcel in, TimeBase timeBase) { if (in.readInt() != 0) { return new LongSamplingCounterArray(timeBase, in); } else { return null; } } public static void writeSummaryToParcelLocked(Parcel out, LongSamplingCounterArray counterArray) { if (counterArray != null) { out.writeInt(1); counterArray.writeSummaryToParcelLocked(out); } else { out.writeInt(0); } } public static LongSamplingCounterArray readSummaryFromParcelLocked(Parcel in, TimeBase timeBase) { if (in.readInt() != 0) { final LongSamplingCounterArray counterArray = new LongSamplingCounterArray(timeBase); counterArray.readSummaryFromParcelLocked(in); return counterArray; } else { return null; } } private void fillArray(long[] a, long val) { if (a != null) { Arrays.fill(a, val); Loading Loading @@ -6927,18 +6967,8 @@ public class BatteryStatsImpl extends BatteryStats { out.writeInt(0); } if (mCpuFreqTimeMs != null) { out.writeInt(1); mCpuFreqTimeMs.writeToParcel(out); } else { out.writeInt(0); } if (mScreenOffCpuFreqTimeMs != null) { out.writeInt(1); mScreenOffCpuFreqTimeMs.writeToParcel(out); } else { out.writeInt(0); } LongSamplingCounterArray.writeToParcel(out, mCpuFreqTimeMs); LongSamplingCounterArray.writeToParcel(out, mScreenOffCpuFreqTimeMs); if (mMobileRadioApWakeupCount != null) { out.writeInt(1); Loading Loading @@ -7187,17 +7217,9 @@ public class BatteryStatsImpl extends BatteryStats { mCpuClusterSpeed = null; } if (in.readInt() != 0) { mCpuFreqTimeMs = new LongSamplingCounterArray(mBsi.mOnBatteryTimeBase, in); } else { mCpuFreqTimeMs = null; } if (in.readInt() != 0) { mScreenOffCpuFreqTimeMs = new LongSamplingCounterArray( mBsi.mOnBatteryScreenOffTimeBase, in); } else { mScreenOffCpuFreqTimeMs = null; } mCpuFreqTimeMs = LongSamplingCounterArray.readFromParcel(in, mBsi.mOnBatteryTimeBase); mScreenOffCpuFreqTimeMs = LongSamplingCounterArray.readFromParcel( in, mBsi.mOnBatteryScreenOffTimeBase); if (in.readInt() != 0) { mMobileRadioApWakeupCount = new LongSamplingCounter(mBsi.mOnBatteryTimeBase, in); Loading Loading @@ -11355,19 +11377,10 @@ public class BatteryStatsImpl extends BatteryStats { u.mCpuClusterSpeed = null; } if (in.readInt() != 0) { u.mCpuFreqTimeMs = new LongSamplingCounterArray(mOnBatteryTimeBase); u.mCpuFreqTimeMs.readSummaryFromParcelLocked(in); } else { u.mCpuFreqTimeMs = null; } if (in.readInt() != 0) { u.mScreenOffCpuFreqTimeMs = new LongSamplingCounterArray( mOnBatteryScreenOffTimeBase); u.mScreenOffCpuFreqTimeMs.readSummaryFromParcelLocked(in); } else { u.mScreenOffCpuFreqTimeMs = null; } u.mCpuFreqTimeMs = LongSamplingCounterArray.readSummaryFromParcelLocked( in, mOnBatteryTimeBase); u.mScreenOffCpuFreqTimeMs = LongSamplingCounterArray.readSummaryFromParcelLocked( in, mOnBatteryScreenOffTimeBase); if (in.readInt() != 0) { u.mMobileRadioApWakeupCount = new LongSamplingCounter(mOnBatteryTimeBase); Loading Loading @@ -11765,18 +11778,8 @@ public class BatteryStatsImpl extends BatteryStats { out.writeInt(0); } if (u.mCpuFreqTimeMs != null) { out.writeInt(1); u.mCpuFreqTimeMs.writeSummaryFromParcelLocked(out); } else { out.writeInt(0); } if (u.mScreenOffCpuFreqTimeMs != null) { out.writeInt(1); u.mScreenOffCpuFreqTimeMs.writeSummaryFromParcelLocked(out); } else { out.writeInt(0); } LongSamplingCounterArray.writeSummaryToParcelLocked(out, u.mCpuFreqTimeMs); LongSamplingCounterArray.writeSummaryToParcelLocked(out, u.mScreenOffCpuFreqTimeMs); if (u.mMobileRadioApWakeupCount != null) { out.writeInt(1); Loading
core/tests/coretests/src/com/android/internal/os/KernelUidCpuFreqTimeReaderTest.java +61 −6 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ package com.android.internal.os; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyNoMoreInteractions; import static org.mockito.Mockito.verifyZeroInteractions; import static org.mockito.Mockito.when; import android.support.test.filters.SmallTest; Loading @@ -27,6 +28,7 @@ import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.MockitoAnnotations; import java.io.BufferedReader; Loading Loading @@ -70,18 +72,70 @@ public class KernelUidCpuFreqTimeReaderTest { times[i][j] = uids[i] * freqs[j] * 10; } } final String[] uidsTimesLines = getUidTimesLines(uids, times); final String[] lines = new String[uidsTimesLines.length + 1]; System.arraycopy(uidsTimesLines, 0, lines, 0, uidsTimesLines.length); lines[uidsTimesLines.length] = null; when(mBufferedReader.readLine()) .thenReturn(getFreqsLine(freqs), lines); .thenReturn(getFreqsLine(freqs), getUidTimesLines(uids, times)); mKernelUidCpuFreqTimeReader.readDelta(mBufferedReader, mCallback); verify(mCallback).onCpuFreqs(freqs); for (int i = 0; i < uids.length; ++i) { verify(mCallback).onUidCpuFreqTime(uids[i], times[i]); } verifyNoMoreInteractions(mCallback); // Verify that a second call will only return deltas. Mockito.reset(mCallback, mBufferedReader); final long[][] newTimes1 = new long[uids.length][freqs.length]; for (int i = 0; i < uids.length; ++i) { for (int j = 0; j < freqs.length; ++j) { newTimes1[i][j] = (times[i][j] + uids[i] + freqs[j]) * 10; } } when(mBufferedReader.readLine()) .thenReturn(getFreqsLine(freqs), getUidTimesLines(uids, newTimes1)); mKernelUidCpuFreqTimeReader.readDelta(mBufferedReader, mCallback); verify(mCallback).onCpuFreqs(freqs); for (int i = 0; i < uids.length; ++i) { verify(mCallback).onUidCpuFreqTime(uids[i], subtract(newTimes1[i], times[i])); } verifyNoMoreInteractions(mCallback); // Verify that calling with a null callback doesn't result in any crashes Mockito.reset(mCallback, mBufferedReader); final long[][] newTimes2 = new long[uids.length][freqs.length]; for (int i = 0; i < uids.length; ++i) { for (int j = 0; j < freqs.length; ++j) { newTimes2[i][j] = (newTimes1[i][j] + uids[i] * freqs[j]) * 10; } } when(mBufferedReader.readLine()) .thenReturn(getFreqsLine(freqs), getUidTimesLines(uids, newTimes2)); mKernelUidCpuFreqTimeReader.readDelta(mBufferedReader, null); verifyZeroInteractions(mCallback); // Verify that the readDelta call will only return deltas when // the previous call had null callback. Mockito.reset(mCallback, mBufferedReader); final long[][] newTimes3 = new long[uids.length][freqs.length]; for (int i = 0; i < uids.length; ++i) { for (int j = 0; j < freqs.length; ++j) { newTimes3[i][j] = (newTimes2[i][j] * (uids[i] + freqs[j])) * 10; } } when(mBufferedReader.readLine()) .thenReturn(getFreqsLine(freqs), getUidTimesLines(uids, newTimes3)); mKernelUidCpuFreqTimeReader.readDelta(mBufferedReader, mCallback); verify(mCallback).onCpuFreqs(freqs); for (int i = 0; i < uids.length; ++i) { verify(mCallback).onUidCpuFreqTime(uids[i], subtract(newTimes3[i], newTimes2[i])); } verifyNoMoreInteractions(mCallback); } private long[] subtract(long[] a1, long[] a2) { long[] val = new long[a1.length]; for (int i = 0; i < val.length; ++i) { val[i] = a1[i] - a2[i]; } return val; } private String getFreqsLine(long[] freqs) { Loading @@ -94,7 +148,7 @@ public class KernelUidCpuFreqTimeReaderTest { } private String[] getUidTimesLines(int[] uids, long[][] times) { final String[] lines = new String[uids.length]; final String[] lines = new String[uids.length + 1]; final StringBuilder sb = new StringBuilder(); for (int i = 0; i < uids.length; ++i) { sb.setLength(0); Loading @@ -104,6 +158,7 @@ public class KernelUidCpuFreqTimeReaderTest { } lines[i] = sb.toString(); } lines[uids.length] = null; return lines; } }
core/tests/coretests/src/com/android/internal/os/LongSamplingCounterArrayTest.java 0 → 100644 +217 −0 Original line number Diff line number Diff line /* * Copyright (C) 2017 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.internal.os; import static android.os.BatteryStats.STATS_SINCE_CHARGED; import static com.android.internal.os.BatteryStatsImpl.LongSamplingCounterArray; import static com.android.internal.os.BatteryStatsImpl.TimeBase; import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyNoMoreInteractions; import static org.mockito.Mockito.verifyZeroInteractions; import static org.mockito.Mockito.when; import android.os.Parcel; import android.support.test.filters.SmallTest; import android.support.test.runner.AndroidJUnit4; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.MockitoAnnotations; import java.util.Arrays; /** * Test class for {@link BatteryStatsImpl.LongSamplingCounterArray}. * * To run the tests, use * * runtest -c com.android.internal.os.LongSamplingCounterArrayTest frameworks-core * * or the following steps: * * Build: m FrameworksCoreTests * Install: adb install -r \ * ${ANDROID_PRODUCT_OUT}/data/app/FrameworksCoreTests/FrameworksCoreTests.apk * Run: adb shell am instrument -e class com.android.internal.os.LongSamplingCounterArrayTest -w \ * com.android.frameworks.coretests/android.support.test.runner.AndroidJUnitRunner */ @SmallTest @RunWith(AndroidJUnit4.class) public class LongSamplingCounterArrayTest { private static final long[] COUNTS = {1111, 2222, 3333, 4444}; private static final long[] LOADED_COUNTS = {5555, 6666, 7777, 8888}; private static final long[] PLUGGED_COUNTS = {9999, 11111, 22222, 33333}; private static final long[] UNPLUGGED_COUNTS = {44444, 55555, 66666, 77777}; private static final long[] ZEROES = {0, 0, 0, 0}; @Mock private TimeBase mTimeBase; private LongSamplingCounterArray mCounterArray; @Before public void setUp() { MockitoAnnotations.initMocks(this); mCounterArray = new LongSamplingCounterArray(mTimeBase); Mockito.reset(mTimeBase); } @Test public void testReadWriteParcel() { final Parcel parcel = Parcel.obtain(); initializeCounterArrayWithDefaultValues(); LongSamplingCounterArray.writeToParcel(parcel, mCounterArray); parcel.setDataPosition(0); // Now clear counterArray and verify values are read from parcel correctly. updateCounts(null, null, null, null); mCounterArray = LongSamplingCounterArray.readFromParcel(parcel, mTimeBase); assertArrayEquals(COUNTS, mCounterArray.mCounts, "Unexpected counts"); assertArrayEquals(LOADED_COUNTS, mCounterArray.mLoadedCounts, "Unexpected loadedCounts"); assertArrayEquals(COUNTS, mCounterArray.mPluggedCounts, "Unexpected pluggedCounts"); assertArrayEquals(UNPLUGGED_COUNTS, mCounterArray.mUnpluggedCounts, "Unexpected unpluggedCounts"); parcel.recycle(); } @Test public void testReadWriteSummaryParcel() { final Parcel parcel = Parcel.obtain(); initializeCounterArrayWithDefaultValues(); LongSamplingCounterArray.writeSummaryToParcelLocked(parcel, mCounterArray); parcel.setDataPosition(0); // Now clear counterArray and verify values are read from parcel correctly. updateCounts(null, null, null, null); mCounterArray = LongSamplingCounterArray.readSummaryFromParcelLocked(parcel, mTimeBase); assertArrayEquals(COUNTS, mCounterArray.mCounts, "Unexpected counts"); assertArrayEquals(COUNTS, mCounterArray.mLoadedCounts, "Unexpected loadedCounts"); assertArrayEquals(COUNTS, mCounterArray.mPluggedCounts, "Unexpected pluggedCounts"); assertArrayEquals(COUNTS, mCounterArray.mUnpluggedCounts, "Unexpected unpluggedCounts"); parcel.recycle(); } @Test public void testOnTimeStarted() { initializeCounterArrayWithDefaultValues(); mCounterArray.onTimeStarted(0, 0, 0); assertArrayEquals(PLUGGED_COUNTS, mCounterArray.mCounts, "Unexpected counts"); assertArrayEquals(LOADED_COUNTS, mCounterArray.mLoadedCounts, "Unexpected loadedCounts"); assertArrayEquals(PLUGGED_COUNTS, mCounterArray.mPluggedCounts, "Unexpected pluggedCounts"); assertArrayEquals(PLUGGED_COUNTS, mCounterArray.mUnpluggedCounts, "Unexpected unpluggedCounts"); } @Test public void testOnTimeStopped() { initializeCounterArrayWithDefaultValues(); mCounterArray.onTimeStopped(0, 0, 0); assertArrayEquals(COUNTS, mCounterArray.mCounts, "Unexpected counts"); assertArrayEquals(LOADED_COUNTS, mCounterArray.mLoadedCounts, "Unexpected loadedCounts"); assertArrayEquals(COUNTS, mCounterArray.mPluggedCounts, "Unexpected pluggedCounts"); assertArrayEquals(UNPLUGGED_COUNTS, mCounterArray.mUnpluggedCounts, "Unexpected unpluggedCounts"); } @Test public void testGetCountsLocked() { initializeCounterArrayWithDefaultValues(); when(mTimeBase.isRunning()).thenReturn(false); long[] actualVal = mCounterArray.getCountsLocked(STATS_SINCE_CHARGED); long[] expectedVal = PLUGGED_COUNTS; assertArrayEquals(expectedVal, actualVal, "Unexpected values"); when(mTimeBase.isRunning()).thenReturn(true); actualVal = mCounterArray.getCountsLocked(STATS_SINCE_CHARGED); expectedVal = COUNTS; assertArrayEquals(expectedVal, actualVal, "Unexpected values"); } @Test public void testAddCountLocked() { final long[] deltas = {123, 234, 345, 456}; mCounterArray.addCountLocked(deltas); assertArrayEquals(deltas, mCounterArray.mCounts, "Unexpected counts"); assertArrayEquals(null, mCounterArray.mLoadedCounts, "Unexpected loadedCounts"); assertArrayEquals(null, mCounterArray.mPluggedCounts, "Unexpected pluggedCounts"); assertArrayEquals(null, mCounterArray.mUnpluggedCounts, "Unexpected unpluggedCounts"); initializeCounterArrayWithDefaultValues(); final long[] newCounts = new long[deltas.length]; for (int i = 0; i < deltas.length; ++i) { newCounts[i] = COUNTS[i] + deltas[i]; } mCounterArray.addCountLocked(deltas); assertArrayEquals(newCounts, mCounterArray.mCounts, "Unexpected counts"); assertArrayEquals(LOADED_COUNTS, mCounterArray.mLoadedCounts, "Unexpected loadedCounts"); assertArrayEquals(PLUGGED_COUNTS, mCounterArray.mPluggedCounts, "Unexpected pluggedCounts"); assertArrayEquals(UNPLUGGED_COUNTS, mCounterArray.mUnpluggedCounts, "Unexpected unpluggedCounts"); } @Test public void testReset() { initializeCounterArrayWithDefaultValues(); // Test with detachIfReset=false mCounterArray.reset(false /* detachIfReset */); assertArrayEquals(ZEROES, mCounterArray.mCounts, "Unexpected counts"); assertArrayEquals(ZEROES, mCounterArray.mLoadedCounts, "Unexpected loadedCounts"); assertArrayEquals(ZEROES, mCounterArray.mPluggedCounts, "Unexpected pluggedCounts"); assertArrayEquals(ZEROES, mCounterArray.mUnpluggedCounts, "Unexpected unpluggedCounts"); verifyZeroInteractions(mTimeBase); initializeCounterArrayWithDefaultValues(); // Test with detachIfReset=true mCounterArray.reset(true /* detachIfReset */); assertArrayEquals(ZEROES, mCounterArray.mCounts, "Unexpected counts"); assertArrayEquals(ZEROES, mCounterArray.mLoadedCounts, "Unexpected loadedCounts"); assertArrayEquals(ZEROES, mCounterArray.mPluggedCounts, "Unexpected pluggedCounts"); assertArrayEquals(ZEROES, mCounterArray.mUnpluggedCounts, "Unexpected unpluggedCounts"); verify(mTimeBase).remove(mCounterArray); verifyNoMoreInteractions(mTimeBase); } @Test public void testDetach() { mCounterArray.detach(); verify(mTimeBase).remove(mCounterArray); verifyNoMoreInteractions(mTimeBase); } private void initializeCounterArrayWithDefaultValues() { updateCounts(COUNTS, LOADED_COUNTS, PLUGGED_COUNTS, UNPLUGGED_COUNTS); } private void assertArrayEquals(long[] expected, long[] actual, String msg) { assertTrue(msg + ", expected: " + Arrays.toString(expected) + ", actual: " + Arrays.toString(actual), Arrays.equals(expected, actual)); } private void updateCounts(long[] counts, long[] loadedCounts, long[] pluggedCounts, long[] unpluggedCounts) { mCounterArray.mCounts = counts; mCounterArray.mLoadedCounts = loadedCounts; mCounterArray.mPluggedCounts = pluggedCounts; mCounterArray.mUnpluggedCounts = unpluggedCounts; } }