Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 72e63c66 authored by Dmitri Plotnikov's avatar Dmitri Plotnikov
Browse files

Reduce object allocation in procstate CPU attribution

Bug: 197162116
Test: atest FrameworksCoreTests:BatteryStatsTests
Change-Id: Iee0ed61305248f69943a8e4a6c9baacdd523df0c
parent 02240482
Loading
Loading
Loading
Loading
+35 −29
Original line number Diff line number Diff line
@@ -58,6 +58,7 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.Formatter;
@@ -859,11 +860,13 @@ public abstract class BatteryStats implements Parcelable {
        /**
         * Returns cpu times of an uid at a particular process state.
         */
        public abstract long[] getCpuFreqTimes(int which, int procState);
        public abstract boolean getCpuFreqTimes(@NonNull long[] timesInFreqMs, int procState);

        /**
         * Returns cpu times of an uid while the screen if off at a particular process state.
         */
        public abstract long[] getScreenOffCpuFreqTimes(int which, int procState);
        public abstract boolean getScreenOffCpuFreqTimes(@NonNull long[] timesInFreqMs,
                int procState);

        // Note: the following times are disjoint.  They can be added together to find the
        // total time a uid has had any processes running at all.
@@ -1575,6 +1578,11 @@ public abstract class BatteryStats implements Parcelable {

    public abstract long getNextMaxDailyDeadline();

    /**
     * Returns the total number of frequencies across all CPU clusters.
     */
    public abstract int getCpuFreqCount();

    public abstract long[] getCpuFreqs();

    public final static class HistoryTag {
@@ -4626,27 +4634,26 @@ public abstract class BatteryStats implements Parcelable {
                            cpuFreqTimeMs.length, sb.toString());
                }

                final long[] timesInFreqMs = new long[getCpuFreqCount()];
                for (int procState = 0; procState < Uid.NUM_PROCESS_STATE; ++procState) {
                    final long[] timesMs = u.getCpuFreqTimes(which, procState);
                    if (timesMs != null && timesMs.length == cpuFreqs.length) {
                    if (u.getCpuFreqTimes(timesInFreqMs, procState)) {
                        sb.setLength(0);
                        for (int i = 0; i < timesMs.length; ++i) {
                        for (int i = 0; i < timesInFreqMs.length; ++i) {
                            if (i != 0) sb.append(',');
                            sb.append(timesMs[i]);
                            sb.append(timesInFreqMs[i]);
                        }
                        final long[] screenOffTimesMs = u.getScreenOffCpuFreqTimes(
                                which, procState);
                        if (screenOffTimesMs != null) {
                            for (int i = 0; i < screenOffTimesMs.length; ++i) {
                                sb.append(',').append(screenOffTimesMs[i]);
                        if (u.getScreenOffCpuFreqTimes(timesInFreqMs, procState)) {
                            for (int i = 0; i < timesInFreqMs.length; ++i) {
                                sb.append(',').append(timesInFreqMs[i]);
                            }
                        } else {
                            for (int i = 0; i < timesMs.length; ++i) {
                            for (int i = 0; i < timesInFreqMs.length; ++i) {
                                sb.append(",0");
                            }
                        }
                        dumpLine(pw, uid, category, CPU_TIMES_AT_FREQ_DATA,
                                Uid.UID_PROCESS_TYPES[procState], timesMs.length, sb.toString());
                                Uid.UID_PROCESS_TYPES[procState], timesInFreqMs.length,
                                sb.toString());
                    }
                }
            }
@@ -6243,25 +6250,24 @@ public abstract class BatteryStats implements Parcelable {
                pw.println(sb.toString());
            }

            final long[] timesInFreqMs = new long[getCpuFreqCount()];
            for (int procState = 0; procState < Uid.NUM_PROCESS_STATE; ++procState) {
                final long[] cpuTimes = u.getCpuFreqTimes(which, procState);
                if (cpuTimes != null) {
                if (u.getCpuFreqTimes(timesInFreqMs, procState)) {
                    sb.setLength(0);
                    sb.append("    Cpu times per freq at state ")
                            .append(Uid.PROCESS_STATE_NAMES[procState]).append(':');
                    for (int i = 0; i < cpuTimes.length; ++i) {
                        sb.append(" " + cpuTimes[i]);
                    for (int i = 0; i < timesInFreqMs.length; ++i) {
                        sb.append(" ").append(timesInFreqMs[i]);
                    }
                    pw.println(sb.toString());
                }

                final long[] screenOffCpuTimes = u.getScreenOffCpuFreqTimes(which, procState);
                if (screenOffCpuTimes != null) {
                if (u.getScreenOffCpuFreqTimes(timesInFreqMs, procState)) {
                    sb.setLength(0);
                    sb.append("   Screen-off cpu times per freq at state ")
                            .append(Uid.PROCESS_STATE_NAMES[procState]).append(':');
                    for (int i = 0; i < screenOffCpuTimes.length; ++i) {
                        sb.append(" " + screenOffCpuTimes[i]);
                    for (int i = 0; i < timesInFreqMs.length; ++i) {
                        sb.append(" ").append(timesInFreqMs[i]);
                    }
                    pw.println(sb.toString());
                }
@@ -7627,22 +7633,22 @@ public abstract class BatteryStats implements Parcelable {
                }
            }

            final long[] timesInFreqMs = new long[getCpuFreqCount()];
            final long[] timesInFreqScreenOffMs = new long[getCpuFreqCount()];
            for (int procState = 0; procState < Uid.NUM_PROCESS_STATE; ++procState) {
                final long[] timesMs = u.getCpuFreqTimes(which, procState);
                if (timesMs != null && timesMs.length == cpuFreqs.length) {
                    long[] screenOffTimesMs = u.getScreenOffCpuFreqTimes(which, procState);
                    if (screenOffTimesMs == null) {
                        screenOffTimesMs = new long[timesMs.length];
                if (u.getCpuFreqTimes(timesInFreqMs, procState)) {
                    if (!u.getScreenOffCpuFreqTimes(timesInFreqScreenOffMs, procState)) {
                        Arrays.fill(timesInFreqScreenOffMs, 0);
                    }
                    final long procToken = proto.start(UidProto.Cpu.BY_PROCESS_STATE);
                    proto.write(UidProto.Cpu.ByProcessState.PROCESS_STATE, procState);
                    for (int ic = 0; ic < timesMs.length; ++ic) {
                    for (int ic = 0; ic < timesInFreqMs.length; ++ic) {
                        long cToken = proto.start(UidProto.Cpu.ByProcessState.BY_FREQUENCY);
                        proto.write(UidProto.Cpu.ByFrequency.FREQUENCY_INDEX, ic + 1);
                        proto.write(UidProto.Cpu.ByFrequency.TOTAL_DURATION_MS,
                                timesMs[ic]);
                                timesInFreqMs[ic]);
                        proto.write(UidProto.Cpu.ByFrequency.SCREEN_OFF_DURATION_MS,
                                screenOffTimesMs[ic]);
                                timesInFreqScreenOffMs[ic]);
                        proto.end(cToken);
                    }
                    proto.end(procToken);
+46 −32
Original line number Diff line number Diff line
@@ -468,6 +468,7 @@ public class BatteryStatsImpl extends BatteryStats {
            mPendingUids.clear();
        }
        final long timestampMs = mClock.elapsedRealtime();
        LongArrayMultiStateCounter.LongArrayContainer deltaContainer = null;
        for (int i = uidStates.size() - 1; i >= 0; --i) {
            final int uid = uidStates.keyAt(i);
            final int procState = uidStates.valueAt(i);
@@ -493,6 +494,9 @@ public class BatteryStatsImpl extends BatteryStats {
                        isolatedUids[j] = u.mChildUids.keyAt(j);
                        isolatedUidTimeInFreqCounters[j] =
                                u.mChildUids.valueAt(j).cpuTimeInFreqCounter;
                        if (deltaContainer == null && isolatedUidTimeInFreqCounters[j] != null) {
                            deltaContainer = getCpuTimeInFreqContainer();
                        }
                    }
                }
            }
@@ -509,8 +513,6 @@ public class BatteryStatsImpl extends BatteryStats {
            mKernelSingleUidTimeReader.addDelta(uid, onBatteryScreenOffCounter, timestampMs);
            if (isolatedUids != null) {
                LongArrayMultiStateCounter.LongArrayContainer deltaContainer =
                        new LongArrayMultiStateCounter.LongArrayContainer(getCpuFreqCount());
                for (int j = isolatedUids.length - 1; j >= 0; --j) {
                    if (isolatedUidTimeInFreqCounters[j] != null) {
                        mKernelSingleUidTimeReader.addDelta(isolatedUids[j],
@@ -612,13 +614,13 @@ public class BatteryStatsImpl extends BatteryStats {
                }
                if (u.mChildUids != null) {
                    final LongArrayMultiStateCounter.LongArrayContainer deltaContainer =
                            new LongArrayMultiStateCounter.LongArrayContainer(getCpuFreqCount());
                    for (int j = u.mChildUids.size() - 1; j >= 0; --j) {
                        final LongArrayMultiStateCounter counter =
                                u.mChildUids.valueAt(j).cpuTimeInFreqCounter;
                        if (counter != null) {
                            final int isolatedUid = u.mChildUids.keyAt(j);
                            final LongArrayMultiStateCounter.LongArrayContainer deltaContainer =
                                    getCpuTimeInFreqContainer();
                            mKernelSingleUidTimeReader.addDelta(isolatedUid,
                                    counter, timestampMs, deltaContainer);
                            onBatteryCounter.addCounts(deltaContainer);
@@ -1186,7 +1188,9 @@ public class BatteryStatsImpl extends BatteryStats {
    private long mBatteryTimeToFullSeconds = -1;
    private boolean mCpuFreqsInitialized;
    private long[] mCpuFreqs;
    private LongArrayMultiStateCounter.LongArrayContainer mTmpCpuTimeInFreq;
    /**
     * Times spent by the system server threads handling incoming binder requests.
@@ -1931,23 +1935,22 @@ public class BatteryStatsImpl extends BatteryStats {
        }
        /**
         * Returns accumulated counts for the specified state, or null if all counts are zero.
         * Returns accumulated counts for the specified state, or false if all counts are zero.
         */
        @Nullable
        public long[] getCountsLocked(int which, int procState) {
            LongArrayMultiStateCounter.LongArrayContainer longArrayContainer =
                    new LongArrayMultiStateCounter.LongArrayContainer(mCounter.getArrayLength());
            mCounter.getCounts(longArrayContainer, procState);
            final long[] counts = new long[mCounter.getArrayLength()];
            longArrayContainer.getValues(counts);
        public boolean getCountsLocked(long[] counts, int procState) {
            if (counts.length != mCounter.getArrayLength()) {
                return false;
            }
            mCounter.getCounts(counts, procState);
            // Return counts only if at least one of the elements is non-zero.
            for (int i = counts.length - 1; i >= 0; --i) {
                if (counts[i] != 0) {
                    return counts;
                    return true;
                }
            }
            return null;
            return false;
        }
        public void logState(Printer pw, String prefix) {
@@ -8346,35 +8349,34 @@ public class BatteryStatsImpl extends BatteryStats {
        @GuardedBy("mBsi")
        @Override
        public long[] getCpuFreqTimes(int which, int procState) {
        public boolean getCpuFreqTimes(long[] timesInFreqMs, int procState) {
            if (procState < 0 || procState >= NUM_PROCESS_STATE) {
                return null;
                return false;
            }
            if (mProcStateTimeMs == null) {
                return null;
                return false;
            }
            if (!mBsi.mPerProcStateCpuTimesAvailable) {
                mProcStateTimeMs = null;
                return null;
                return false;
            }
            return mProcStateTimeMs.getCountsLocked(which, procState);
            return mProcStateTimeMs.getCountsLocked(timesInFreqMs, procState);
        }
        @GuardedBy("mBsi")
        @Override
        public long[] getScreenOffCpuFreqTimes(int which, int procState) {
        public boolean getScreenOffCpuFreqTimes(long[] timesInFreqMs, int procState) {
            if (procState < 0 || procState >= NUM_PROCESS_STATE) {
                return null;
                return false;
            }
            if (mProcStateScreenOffTimeMs == null) {
                return null;
                return false;
            }
            if (!mBsi.mPerProcStateCpuTimesAvailable) {
                mProcStateScreenOffTimeMs = null;
                return null;
                return false;
            }
            return mProcStateScreenOffTimeMs.getCountsLocked(which, procState);
            return mProcStateScreenOffTimeMs.getCountsLocked(timesInFreqMs, procState);
        }
        public long getBinderCallCount() {
@@ -11577,18 +11579,30 @@ public class BatteryStatsImpl extends BatteryStats {
        }
    }
    @GuardedBy("this")
    @Override
    public long[] getCpuFreqs() {
        if (!mCpuFreqsInitialized) {
            mCpuFreqs = mCpuUidFreqTimeReader.readFreqs(mPowerProfile);
            mCpuFreqsInitialized = true;
        }
        return mCpuFreqs;
    }
    /**
     * Returns the total number of frequencies across all CPU clusters.
     */
    private int getCpuFreqCount() {
        if (mCpuFreqs == null) {
            mCpuFreqs = mCpuUidFreqTimeReader.readFreqs(mPowerProfile);
    @GuardedBy("this")
    @Override
    public int getCpuFreqCount() {
        final long[] cpuFreqs = getCpuFreqs();
        return cpuFreqs != null ? cpuFreqs.length : 0;
    }
    @GuardedBy("this")
    private LongArrayMultiStateCounter.LongArrayContainer getCpuTimeInFreqContainer() {
        if (mTmpCpuTimeInFreq == null) {
            mTmpCpuTimeInFreq =
                    new LongArrayMultiStateCounter.LongArrayContainer(getCpuFreqCount());
        }
        return mCpuFreqs != null ? mCpuFreqs.length : 0;
        return mTmpCpuTimeInFreq;
    }
    public BatteryStatsImpl(File systemDir, Handler handler, PlatformIdleStateCallback cb,
+7 −4
Original line number Diff line number Diff line
@@ -56,6 +56,7 @@ public class CpuPowerCalculator extends PowerCalculator {
        public long durationFgMs;
        public String packageWithHighestDrain;
        public double[] perProcStatePowerMah;
        public long[] cpuFreqTimes;
    }

    public CpuPowerCalculator(PowerProfile profile) {
@@ -98,6 +99,9 @@ public class CpuPowerCalculator extends PowerCalculator {

        BatteryConsumer.Key[] keys = UNINITIALIZED_KEYS;
        Result result = new Result();
        if (query.isProcessStateDataNeeded()) {
            result.cpuFreqTimes = new long[batteryStats.getCpuFreqCount()];
        }
        final SparseArray<UidBatteryConsumer.Builder> uidBatteryConsumerBuilders =
                builder.getUidBatteryConsumerBuilders();
        for (int i = uidBatteryConsumerBuilders.size() - 1; i >= 0; i--) {
@@ -187,11 +191,10 @@ public class CpuPowerCalculator extends PowerCalculator {
            // TODO(b/191921016): use per-state CPU cluster times
            final long[] cpuClusterTimes = null;

            final long[] cpuFreqTimes = u.getCpuFreqTimes(BatteryStats.STATS_SINCE_CHARGED,
                    uidProcState);
            if (cpuClusterTimes != null || cpuFreqTimes != null) {
            boolean hasCpuFreqTimes = u.getCpuFreqTimes(result.cpuFreqTimes, uidProcState);
            if (cpuClusterTimes != null || hasCpuFreqTimes) {
                result.perProcStatePowerMah[procState] += calculateUidModeledPowerMah(u,
                        0, cpuClusterTimes, cpuFreqTimes);
                        0, cpuClusterTimes, result.cpuFreqTimes);
            }
        }

+16 −0
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@ import dalvik.annotation.optimization.FastNative;
import libcore.util.NativeAllocationRegistry;

import java.util.Arrays;
import java.util.concurrent.atomic.AtomicReference;

/**
 * Performs per-state counting of multi-element values over time. The class' behavior is illustrated
@@ -120,6 +121,8 @@ public final class LongArrayMultiStateCounter implements Parcelable {
    private static final NativeAllocationRegistry sRegistry =
            NativeAllocationRegistry.createMalloced(
                    LongArrayMultiStateCounter.class.getClassLoader(), native_getReleaseFunc());
    private static final AtomicReference<LongArrayContainer> sTmpArrayContainer =
            new AtomicReference<>();

    private final int mStateCount;
    private final int mLength;
@@ -203,6 +206,19 @@ public final class LongArrayMultiStateCounter implements Parcelable {
        native_reset(mNativeObject);
    }

    /**
     * Populates the array with the accumulated counts for the specified state.
     */
    public void getCounts(long[] counts, int state) {
        LongArrayContainer container = sTmpArrayContainer.getAndSet(null);
        if (container == null || container.mLength != counts.length) {
            container = new LongArrayContainer(counts.length);
        }
        getCounts(container, state);
        container.getValues(counts);
        sTmpArrayContainer.set(container);
    }

    /**
     * Populates longArrayContainer with the accumulated counts for the specified state.
     */
+34 −27
Original line number Diff line number Diff line
@@ -16,7 +16,6 @@

package com.android.internal.os;

import static android.os.BatteryStats.STATS_SINCE_CHARGED;
import static android.os.BatteryStats.Uid.NUM_PROCESS_STATE;
import static android.os.BatteryStats.Uid.PROCESS_STATE_BACKGROUND;
import static android.os.BatteryStats.Uid.PROCESS_STATE_CACHED;
@@ -25,8 +24,10 @@ import static android.os.BatteryStats.Uid.PROCESS_STATE_TOP;

import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.eq;
@@ -115,14 +116,17 @@ public class BatteryStatsImplTest {
                {989834, 384098, 98483, 23809, 4984},
                {4859048, 348903, 4578967, 5973894, 298549}
        };

        final long[] timeInFreqs = new long[NUM_CPU_FREQS];

        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) {
                assertNull(u.getCpuFreqTimes(STATS_SINCE_CHARGED, procState));
                assertNull(u.getScreenOffCpuFreqTimes(STATS_SINCE_CHARGED, procState));
                assertFalse(u.getCpuFreqTimes(timeInFreqs, procState));
                assertFalse(u.getScreenOffCpuFreqTimes(timeInFreqs, procState));
            }
        }
        addPendingUids(testUids, testProcStates);
@@ -134,13 +138,13 @@ public class BatteryStatsImplTest {
        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) {
                final boolean hasTimeInFreq = u.getCpuFreqTimes(timeInFreqs, procState);
                if (procState == testProcStates[i]) {
                    assertArrayEquals("Uid=" + testUids[i], cpuTimes[i],
                            u.getCpuFreqTimes(STATS_SINCE_CHARGED, procState));
                    assertArrayEquals("Uid=" + testUids[i], cpuTimes[i], timeInFreqs);
                } else {
                    assertNull(u.getCpuFreqTimes(STATS_SINCE_CHARGED, procState));
                    assertFalse(hasTimeInFreq);
                }
                assertNull(u.getScreenOffCpuFreqTimes(STATS_SINCE_CHARGED, procState));
                assertFalse(u.getScreenOffCpuFreqTimes(timeInFreqs, procState));
            }
        }

@@ -172,12 +176,12 @@ public class BatteryStatsImplTest {
                    for (int j = 0; j < expectedCpuTimes.length; ++j) {
                        expectedCpuTimes[j] += delta1[i][j];
                    }
                    assertArrayEquals("Uid=" + testUids[i], expectedCpuTimes,
                            u.getCpuFreqTimes(STATS_SINCE_CHARGED, procState));
                    assertTrue(u.getCpuFreqTimes(timeInFreqs, procState));
                    assertArrayEquals("Uid=" + testUids[i], expectedCpuTimes, timeInFreqs);
                } else {
                    assertNull(u.getCpuFreqTimes(STATS_SINCE_CHARGED, procState));
                    assertFalse(u.getCpuFreqTimes(timeInFreqs, procState));
                }
                assertNull(u.getScreenOffCpuFreqTimes(STATS_SINCE_CHARGED, procState));
                assertFalse(u.getScreenOffCpuFreqTimes(timeInFreqs, procState));
            }
        }

@@ -214,13 +218,13 @@ public class BatteryStatsImplTest {
                    for (int j = 0; j < expectedCpuTimes.length; ++j) {
                        expectedCpuTimes[j] += delta1[i][j] + delta2[i][j];
                    }
                    assertArrayEquals("Uid=" + testUids[i], expectedCpuTimes,
                            u.getCpuFreqTimes(STATS_SINCE_CHARGED, procState));
                    assertArrayEquals("Uid=" + testUids[i], delta2[i],
                            u.getScreenOffCpuFreqTimes(STATS_SINCE_CHARGED, procState));
                    assertTrue(u.getCpuFreqTimes(timeInFreqs, procState));
                    assertArrayEquals("Uid=" + testUids[i], expectedCpuTimes, timeInFreqs);
                    assertTrue(u.getScreenOffCpuFreqTimes(timeInFreqs, procState));
                    assertArrayEquals("Uid=" + testUids[i], delta2[i], timeInFreqs);
                } else {
                    assertNull(u.getCpuFreqTimes(STATS_SINCE_CHARGED, procState));
                    assertNull(u.getScreenOffCpuFreqTimes(STATS_SINCE_CHARGED, procState));
                    assertFalse(u.getCpuFreqTimes(timeInFreqs, procState));
                    assertFalse(u.getScreenOffCpuFreqTimes(timeInFreqs, procState));
                }
            }
        }
@@ -262,18 +266,18 @@ public class BatteryStatsImplTest {
                        expectedCpuTimes[j] += delta1[i][j] + delta2[i][j] + delta3[i][j]
                                + (testUids[i] == parentUid ? isolatedUidCpuTimes[j] : 0);
                    }
                    assertArrayEquals("Uid=" + testUids[i], expectedCpuTimes,
                            u.getCpuFreqTimes(STATS_SINCE_CHARGED, procState));
                    assertTrue(u.getCpuFreqTimes(timeInFreqs, procState));
                    assertArrayEquals("Uid=" + testUids[i], expectedCpuTimes, timeInFreqs);
                    long[] expectedScreenOffTimes = delta2[i].clone();
                    for (int j = 0; j < expectedScreenOffTimes.length; ++j) {
                        expectedScreenOffTimes[j] += delta3[i][j]
                                + (testUids[i] == parentUid ? isolatedUidCpuTimes[j] : 0);
                    }
                    assertArrayEquals("Uid=" + testUids[i], expectedScreenOffTimes,
                            u.getScreenOffCpuFreqTimes(STATS_SINCE_CHARGED, procState));
                    assertTrue(u.getScreenOffCpuFreqTimes(timeInFreqs, procState));
                    assertArrayEquals("Uid=" + testUids[i], expectedScreenOffTimes, timeInFreqs);
                } else {
                    assertNull(u.getCpuFreqTimes(STATS_SINCE_CHARGED, procState));
                    assertNull(u.getScreenOffCpuFreqTimes(STATS_SINCE_CHARGED, procState));
                    assertFalse(u.getCpuFreqTimes(timeInFreqs, procState));
                    assertFalse(u.getScreenOffCpuFreqTimes(timeInFreqs, procState));
                }
            }
        }
@@ -329,16 +333,19 @@ public class BatteryStatsImplTest {
        mBatteryStatsImpl.copyFromAllUidsCpuTimes(true, false);

        verifyNoPendingUids();

        final long[] timeInFreqs = new long[NUM_CPU_FREQS];

        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) {
                if (procState == testProcStates[i]) {
                    assertArrayEquals("Uid=" + testUids[i], expectedCpuTimes[i],
                            u.getCpuFreqTimes(STATS_SINCE_CHARGED, procState));
                    assertTrue(u.getCpuFreqTimes(timeInFreqs, procState));
                    assertArrayEquals("Uid=" + testUids[i], expectedCpuTimes[i], timeInFreqs);
                } else {
                    assertNull(u.getCpuFreqTimes(STATS_SINCE_CHARGED, procState));
                    assertFalse(u.getCpuFreqTimes(timeInFreqs, procState));
                }
                assertNull(u.getScreenOffCpuFreqTimes(STATS_SINCE_CHARGED, procState));
                assertFalse(u.getScreenOffCpuFreqTimes(timeInFreqs, procState));
            }
        }
    }