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

Commit 65e919ae authored by Sudheer Shanka's avatar Sudheer Shanka Committed by Android (Google) Code Review
Browse files

Merge "Attribute procstate cpu times to correct battery/screen on/off buckets."

parents 9761f47e e544d162
Loading
Loading
Loading
Loading
+36 −29
Original line number Original line Diff line number Diff line
@@ -124,7 +124,7 @@ public class BatteryStatsImpl extends BatteryStats {
    private static final int MAGIC = 0xBA757475; // 'BATSTATS'
    private static final int MAGIC = 0xBA757475; // 'BATSTATS'
    // Current on-disk Parcel version
    // Current on-disk Parcel version
    private static final int VERSION = 172 + (USE_OLD_HISTORY ? 1000 : 0);
    private static final int VERSION = 173 + (USE_OLD_HISTORY ? 1000 : 0);
    // Maximum number of items we will record in the history.
    // Maximum number of items we will record in the history.
    private static final int MAX_HISTORY_ITEMS;
    private static final int MAX_HISTORY_ITEMS;
@@ -289,7 +289,7 @@ public class BatteryStatsImpl extends BatteryStats {
    /**
    /**
     * Update per-freq cpu times for all the uids in {@link #mPendingUids}.
     * Update per-freq cpu times for all the uids in {@link #mPendingUids}.
     */
     */
    public void updateProcStateCpuTimes() {
    public void updateProcStateCpuTimes(boolean onBattery, boolean onBatteryScreenOff) {
        final SparseIntArray uidStates;
        final SparseIntArray uidStates;
        synchronized (BatteryStatsImpl.this) {
        synchronized (BatteryStatsImpl.this) {
            if(!initKernelSingleUidTimeReaderLocked()) {
            if(!initKernelSingleUidTimeReaderLocked()) {
@@ -307,7 +307,6 @@ public class BatteryStatsImpl extends BatteryStats {
            final int procState = uidStates.valueAt(i);
            final int procState = uidStates.valueAt(i);
            final int[] isolatedUids;
            final int[] isolatedUids;
            final Uid u;
            final Uid u;
            final boolean onBattery;
            synchronized (BatteryStatsImpl.this) {
            synchronized (BatteryStatsImpl.this) {
                // It's possible that uid no longer exists and any internal references have
                // It's possible that uid no longer exists and any internal references have
                // already been deleted, so using {@link #getAvailableUidStatsLocked} to avoid
                // already been deleted, so using {@link #getAvailableUidStatsLocked} to avoid
@@ -324,7 +323,6 @@ public class BatteryStatsImpl extends BatteryStats {
                        isolatedUids[j] = u.mChildUids.get(j);
                        isolatedUids[j] = u.mChildUids.get(j);
                    }
                    }
                }
                }
                onBattery = mOnBatteryInternal;
            }
            }
            long[] cpuTimesMs = mKernelSingleUidTimeReader.readDeltaMs(uid);
            long[] cpuTimesMs = mKernelSingleUidTimeReader.readDeltaMs(uid);
            if (isolatedUids != null) {
            if (isolatedUids != null) {
@@ -335,20 +333,27 @@ public class BatteryStatsImpl extends BatteryStats {
            }
            }
            if (onBattery && cpuTimesMs != null) {
            if (onBattery && cpuTimesMs != null) {
                synchronized (BatteryStatsImpl.this) {
                synchronized (BatteryStatsImpl.this) {
                    u.addProcStateTimesMs(procState, cpuTimesMs);
                    u.addProcStateTimesMs(procState, cpuTimesMs, onBattery);
                    u.addProcStateScreenOffTimesMs(procState, cpuTimesMs);
                    u.addProcStateScreenOffTimesMs(procState, cpuTimesMs, onBatteryScreenOff);
                }
                }
            }
            }
        }
        }
    }
    }
    public void copyFromAllUidsCpuTimes() {
        synchronized (BatteryStatsImpl.this) {
            copyFromAllUidsCpuTimes(
                    mOnBatteryTimeBase.isRunning(), mOnBatteryScreenOffTimeBase.isRunning());
        }
    }
    /**
    /**
     * When the battery/screen state changes, we don't attribute the cpu times to any process
     * When the battery/screen state changes, we don't attribute the cpu times to any process
     * but we still need to snapshots of all uids to get correct deltas later on. Since we
     * but we still need to snapshots of all uids to get correct deltas later on. Since we
     * already read this data for updating per-freq cpu times, we can use the same data for
     * already read this data for updating per-freq cpu times, we can use the same data for
     * per-procstate cpu times.
     * per-procstate cpu times.
     */
     */
    public void copyFromAllUidsCpuTimes() {
    public void copyFromAllUidsCpuTimes(boolean onBattery, boolean onBatteryScreenOff) {
        synchronized (BatteryStatsImpl.this) {
        synchronized (BatteryStatsImpl.this) {
            if(!initKernelSingleUidTimeReaderLocked()) {
            if(!initKernelSingleUidTimeReaderLocked()) {
                return;
                return;
@@ -368,7 +373,7 @@ public class BatteryStatsImpl extends BatteryStats {
                }
                }
                final long[] deltaTimesMs = mKernelSingleUidTimeReader.computeDelta(
                final long[] deltaTimesMs = mKernelSingleUidTimeReader.computeDelta(
                        uid, cpuTimesMs.clone());
                        uid, cpuTimesMs.clone());
                if (mOnBatteryInternal && deltaTimesMs != null) {
                if (onBattery && deltaTimesMs != null) {
                    final int procState;
                    final int procState;
                    final int idx = mPendingUids.indexOfKey(uid);
                    final int idx = mPendingUids.indexOfKey(uid);
                    if (idx >= 0) {
                    if (idx >= 0) {
@@ -378,8 +383,8 @@ public class BatteryStatsImpl extends BatteryStats {
                        procState = u.mProcessState;
                        procState = u.mProcessState;
                    }
                    }
                    if (procState >= 0 && procState < Uid.NUM_PROCESS_STATE) {
                    if (procState >= 0 && procState < Uid.NUM_PROCESS_STATE) {
                        u.addProcStateTimesMs(procState, deltaTimesMs);
                        u.addProcStateTimesMs(procState, deltaTimesMs, onBattery);
                        u.addProcStateScreenOffTimesMs(procState, deltaTimesMs);
                        u.addProcStateScreenOffTimesMs(procState, deltaTimesMs, onBatteryScreenOff);
                    }
                    }
                }
                }
            }
            }
@@ -443,8 +448,8 @@ public class BatteryStatsImpl extends BatteryStats {
        Future<?> scheduleSync(String reason, int flags);
        Future<?> scheduleSync(String reason, int flags);
        Future<?> scheduleCpuSyncDueToRemovedUid(int uid);
        Future<?> scheduleCpuSyncDueToRemovedUid(int uid);
        Future<?> scheduleReadProcStateCpuTimes();
        Future<?> scheduleReadProcStateCpuTimes(boolean onBattery, boolean onBatteryScreenOff);
        Future<?> scheduleCopyFromAllUidsCpuTimes();
        Future<?> scheduleCopyFromAllUidsCpuTimes(boolean onBattery, boolean onBatteryScreenOff);
    }
    }
    public Handler mHandler;
    public Handler mHandler;
@@ -1231,12 +1236,10 @@ public class BatteryStatsImpl extends BatteryStats {
        public long[] mCounts;
        public long[] mCounts;
        public long[] mLoadedCounts;
        public long[] mLoadedCounts;
        public long[] mUnpluggedCounts;
        public long[] mUnpluggedCounts;
        public long[] mPluggedCounts;
        private LongSamplingCounterArray(TimeBase timeBase, Parcel in) {
        private LongSamplingCounterArray(TimeBase timeBase, Parcel in) {
            mTimeBase = timeBase;
            mTimeBase = timeBase;
            mPluggedCounts = in.createLongArray();
            mCounts = in.createLongArray();
            mCounts = copyArray(mPluggedCounts, mCounts);
            mLoadedCounts = in.createLongArray();
            mLoadedCounts = in.createLongArray();
            mUnpluggedCounts = in.createLongArray();
            mUnpluggedCounts = in.createLongArray();
            timeBase.add(this);
            timeBase.add(this);
@@ -1255,17 +1258,16 @@ public class BatteryStatsImpl extends BatteryStats {
        @Override
        @Override
        public void onTimeStarted(long elapsedRealTime, long baseUptime, long baseRealtime) {
        public void onTimeStarted(long elapsedRealTime, long baseUptime, long baseRealtime) {
            mUnpluggedCounts = copyArray(mPluggedCounts, mUnpluggedCounts);
            mUnpluggedCounts = copyArray(mCounts, mUnpluggedCounts);
        }
        }
        @Override
        @Override
        public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) {
        public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) {
            mPluggedCounts = copyArray(mCounts, mPluggedCounts);
        }
        }
        @Override
        @Override
        public long[] getCountsLocked(int which) {
        public long[] getCountsLocked(int which) {
            long[] val = copyArray(mTimeBase.isRunning() ? mCounts : mPluggedCounts, null);
            long[] val = copyArray(mCounts, null);
            if (which == STATS_SINCE_UNPLUGGED) {
            if (which == STATS_SINCE_UNPLUGGED) {
                subtract(val, mUnpluggedCounts);
                subtract(val, mUnpluggedCounts);
            } else if (which != STATS_SINCE_CHARGED) {
            } else if (which != STATS_SINCE_CHARGED) {
@@ -1278,15 +1280,18 @@ public class BatteryStatsImpl extends BatteryStats {
        public void logState(Printer pw, String prefix) {
        public void logState(Printer pw, String prefix) {
            pw.println(prefix + "mCounts=" + Arrays.toString(mCounts)
            pw.println(prefix + "mCounts=" + Arrays.toString(mCounts)
                    + " mLoadedCounts=" + Arrays.toString(mLoadedCounts)
                    + " mLoadedCounts=" + Arrays.toString(mLoadedCounts)
                    + " mUnpluggedCounts=" + Arrays.toString(mUnpluggedCounts)
                    + " mUnpluggedCounts=" + Arrays.toString(mUnpluggedCounts));
                    + " mPluggedCounts=" + Arrays.toString(mPluggedCounts));
        }
        }
        public void addCountLocked(long[] counts) {
        public void addCountLocked(long[] counts) {
            addCountLocked(counts, mTimeBase.isRunning());
        }
        public void addCountLocked(long[] counts, boolean isRunning) {
            if (counts == null) {
            if (counts == null) {
                return;
                return;
            }
            }
            if (mTimeBase.isRunning()) {
            if (isRunning) {
                if (mCounts == null) {
                if (mCounts == null) {
                    mCounts = new long[counts.length];
                    mCounts = new long[counts.length];
                }
                }
@@ -1306,7 +1311,6 @@ public class BatteryStatsImpl extends BatteryStats {
        public void reset(boolean detachIfReset) {
        public void reset(boolean detachIfReset) {
            fillArray(mCounts, 0);
            fillArray(mCounts, 0);
            fillArray(mLoadedCounts, 0);
            fillArray(mLoadedCounts, 0);
            fillArray(mPluggedCounts, 0);
            fillArray(mUnpluggedCounts, 0);
            fillArray(mUnpluggedCounts, 0);
            if (detachIfReset) {
            if (detachIfReset) {
                detach();
                detach();
@@ -1325,7 +1329,6 @@ public class BatteryStatsImpl extends BatteryStats {
            mCounts = in.createLongArray();
            mCounts = in.createLongArray();
            mLoadedCounts = copyArray(mCounts, mLoadedCounts);
            mLoadedCounts = copyArray(mCounts, mLoadedCounts);
            mUnpluggedCounts = copyArray(mCounts, mUnpluggedCounts);
            mUnpluggedCounts = copyArray(mCounts, mUnpluggedCounts);
            mPluggedCounts = copyArray(mCounts, mPluggedCounts);
        }
        }
        public static void writeToParcel(Parcel out, LongSamplingCounterArray counterArray) {
        public static void writeToParcel(Parcel out, LongSamplingCounterArray counterArray) {
@@ -3783,7 +3786,8 @@ public class BatteryStatsImpl extends BatteryStats {
                        + " and battery is " + (unplugged ? "on" : "off"));
                        + " and battery is " + (unplugged ? "on" : "off"));
            }
            }
            updateCpuTimeLocked();
            updateCpuTimeLocked();
            mExternalSync.scheduleCopyFromAllUidsCpuTimes();
            mExternalSync.scheduleCopyFromAllUidsCpuTimes(mOnBatteryTimeBase.isRunning(),
                    mOnBatteryScreenOffTimeBase.isRunning());
            mOnBatteryTimeBase.setRunning(unplugged, uptime, realtime);
            mOnBatteryTimeBase.setRunning(unplugged, uptime, realtime);
            if (updateOnBatteryTimeBase) {
            if (updateOnBatteryTimeBase) {
@@ -6648,7 +6652,7 @@ public class BatteryStatsImpl extends BatteryStats {
            return null;
            return null;
        }
        }
        private void addProcStateTimesMs(int procState, long[] cpuTimesMs) {
        private void addProcStateTimesMs(int procState, long[] cpuTimesMs, boolean onBattery) {
            if (mProcStateTimeMs == null) {
            if (mProcStateTimeMs == null) {
                mProcStateTimeMs = new LongSamplingCounterArray[NUM_PROCESS_STATE];
                mProcStateTimeMs = new LongSamplingCounterArray[NUM_PROCESS_STATE];
            }
            }
@@ -6657,10 +6661,11 @@ public class BatteryStatsImpl extends BatteryStats {
                mProcStateTimeMs[procState] = new LongSamplingCounterArray(
                mProcStateTimeMs[procState] = new LongSamplingCounterArray(
                        mBsi.mOnBatteryTimeBase);
                        mBsi.mOnBatteryTimeBase);
            }
            }
            mProcStateTimeMs[procState].addCountLocked(cpuTimesMs);
            mProcStateTimeMs[procState].addCountLocked(cpuTimesMs, onBattery);
        }
        }
        private void addProcStateScreenOffTimesMs(int procState, long[] cpuTimesMs) {
        private void addProcStateScreenOffTimesMs(int procState, long[] cpuTimesMs,
                boolean onBatteryScreenOff) {
            if (mProcStateScreenOffTimeMs == null) {
            if (mProcStateScreenOffTimeMs == null) {
                mProcStateScreenOffTimeMs = new LongSamplingCounterArray[NUM_PROCESS_STATE];
                mProcStateScreenOffTimeMs = new LongSamplingCounterArray[NUM_PROCESS_STATE];
            }
            }
@@ -6669,7 +6674,7 @@ public class BatteryStatsImpl extends BatteryStats {
                mProcStateScreenOffTimeMs[procState] = new LongSamplingCounterArray(
                mProcStateScreenOffTimeMs[procState] = new LongSamplingCounterArray(
                        mBsi.mOnBatteryScreenOffTimeBase);
                        mBsi.mOnBatteryScreenOffTimeBase);
            }
            }
            mProcStateScreenOffTimeMs[procState].addCountLocked(cpuTimesMs);
            mProcStateScreenOffTimeMs[procState].addCountLocked(cpuTimesMs, onBatteryScreenOff);
        }
        }
        @Override
        @Override
@@ -9408,7 +9413,9 @@ public class BatteryStatsImpl extends BatteryStats {
                    if (mBsi.mPerProcStateCpuTimesAvailable) {
                    if (mBsi.mPerProcStateCpuTimesAvailable) {
                        if (mBsi.mPendingUids.size() == 0) {
                        if (mBsi.mPendingUids.size() == 0) {
                            mBsi.mExternalSync.scheduleReadProcStateCpuTimes();
                            mBsi.mExternalSync.scheduleReadProcStateCpuTimes(
                                    mBsi.mOnBatteryTimeBase.isRunning(),
                                    mBsi.mOnBatteryScreenOffTimeBase.isRunning());
                        }
                        }
                        if (mBsi.mPendingUids.indexOfKey(mUid) < 0
                        if (mBsi.mPendingUids.indexOfKey(mUid) < 0
                                || ArrayUtils.contains(CRITICAL_PROC_STATES, mProcessState)) {
                                || ArrayUtils.contains(CRITICAL_PROC_STATES, mProcessState)) {
+8 −8
Original line number Original line Diff line number Diff line
@@ -71,7 +71,7 @@ public class BatteryStatsImplTest {
    @Test
    @Test
    public void testUpdateProcStateCpuTimes() {
    public void testUpdateProcStateCpuTimes() {
        mBatteryStatsImpl.setOnBatteryInternal(true);
        mBatteryStatsImpl.setOnBatteryInternal(true);
        mBatteryStatsImpl.updateTimeBasesLocked(true, Display.STATE_ON, 0, 0);
        mBatteryStatsImpl.updateTimeBasesLocked(false, Display.STATE_ON, 0, 0);


        final int[] testUids = {10032, 10048, 10145, 10139};
        final int[] testUids = {10032, 10048, 10145, 10139};
        final int[] testProcStates = {
        final int[] testProcStates = {
@@ -98,7 +98,7 @@ public class BatteryStatsImplTest {
            }
            }
        }
        }


        mBatteryStatsImpl.updateProcStateCpuTimes();
        mBatteryStatsImpl.updateProcStateCpuTimes(true, false);


        verifyNoPendingUids();
        verifyNoPendingUids();
        for (int i = 0; i < testUids.length; ++i) {
        for (int i = 0; i < testUids.length; ++i) {
@@ -125,7 +125,7 @@ public class BatteryStatsImplTest {
        }
        }
        addPendingUids(testUids, testProcStates);
        addPendingUids(testUids, testProcStates);


        mBatteryStatsImpl.updateProcStateCpuTimes();
        mBatteryStatsImpl.updateProcStateCpuTimes(true, false);


        verifyNoPendingUids();
        verifyNoPendingUids();
        for (int i = 0; i < testUids.length; ++i) {
        for (int i = 0; i < testUids.length; ++i) {
@@ -157,7 +157,7 @@ public class BatteryStatsImplTest {
        }
        }
        addPendingUids(testUids, testProcStates);
        addPendingUids(testUids, testProcStates);


        mBatteryStatsImpl.updateProcStateCpuTimes();
        mBatteryStatsImpl.updateProcStateCpuTimes(true, true);


        verifyNoPendingUids();
        verifyNoPendingUids();
        for (int i = 0; i < testUids.length; ++i) {
        for (int i = 0; i < testUids.length; ++i) {
@@ -196,7 +196,7 @@ public class BatteryStatsImplTest {
        final long[] isolatedUidCpuTimes = {495784, 398473, 4895, 4905, 30984093};
        final long[] isolatedUidCpuTimes = {495784, 398473, 4895, 4905, 30984093};
        when(mKernelSingleUidTimeReader.readDeltaMs(childUid)).thenReturn(isolatedUidCpuTimes);
        when(mKernelSingleUidTimeReader.readDeltaMs(childUid)).thenReturn(isolatedUidCpuTimes);


        mBatteryStatsImpl.updateProcStateCpuTimes();
        mBatteryStatsImpl.updateProcStateCpuTimes(true, true);


        verifyNoPendingUids();
        verifyNoPendingUids();
        for (int i = 0; i < testUids.length; ++i) {
        for (int i = 0; i < testUids.length; ++i) {
@@ -227,8 +227,8 @@ public class BatteryStatsImplTest {


    @Test
    @Test
    public void testCopyFromAllUidsCpuTimes() {
    public void testCopyFromAllUidsCpuTimes() {
        mBatteryStatsImpl.setOnBatteryInternal(true);
        mBatteryStatsImpl.setOnBatteryInternal(false);
        mBatteryStatsImpl.updateTimeBasesLocked(true, Display.STATE_ON, 0, 0);
        mBatteryStatsImpl.updateTimeBasesLocked(false, Display.STATE_ON, 0, 0);


        final int[] testUids = {10032, 10048, 10145, 10139};
        final int[] testUids = {10032, 10048, 10145, 10139};
        final int[] testProcStates = {
        final int[] testProcStates = {
@@ -264,7 +264,7 @@ public class BatteryStatsImplTest {
                    .thenReturn(expectedCpuTimes[i]);
                    .thenReturn(expectedCpuTimes[i]);
        }
        }


        mBatteryStatsImpl.copyFromAllUidsCpuTimes();
        mBatteryStatsImpl.copyFromAllUidsCpuTimes(true, false);


        verifyNoPendingUids();
        verifyNoPendingUids();
        for (int i = 0; i < testUids.length; ++i) {
        for (int i = 0; i < testUids.length; ++i) {
+55 −25
Original line number Original line Diff line number Diff line
@@ -16,7 +16,9 @@


package com.android.internal.os;
package com.android.internal.os;


import static android.os.BatteryStats.STATS_CURRENT;
import static android.os.BatteryStats.STATS_SINCE_CHARGED;
import static android.os.BatteryStats.STATS_SINCE_CHARGED;
import static android.os.BatteryStats.STATS_SINCE_UNPLUGGED;


import static com.android.internal.os.BatteryStatsImpl.LongSamplingCounterArray;
import static com.android.internal.os.BatteryStatsImpl.LongSamplingCounterArray;
import static com.android.internal.os.BatteryStatsImpl.TimeBase;
import static com.android.internal.os.BatteryStatsImpl.TimeBase;
@@ -61,7 +63,6 @@ public class LongSamplingCounterArrayTest {


    private static final long[] COUNTS = {1111, 2222, 3333, 4444};
    private static final long[] COUNTS = {1111, 2222, 3333, 4444};
    private static final long[] LOADED_COUNTS = {5555, 6666, 7777, 8888};
    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[] UNPLUGGED_COUNTS = {44444, 55555, 66666, 77777};
    private static final long[] ZEROES = {0, 0, 0, 0};
    private static final long[] ZEROES = {0, 0, 0, 0};


@@ -83,11 +84,10 @@ public class LongSamplingCounterArrayTest {
        parcel.setDataPosition(0);
        parcel.setDataPosition(0);


        // Now clear counterArray and verify values are read from parcel correctly.
        // Now clear counterArray and verify values are read from parcel correctly.
        updateCounts(null, null, null, null);
        updateCounts(null, null, null);
        mCounterArray = LongSamplingCounterArray.readFromParcel(parcel, mTimeBase);
        mCounterArray = LongSamplingCounterArray.readFromParcel(parcel, mTimeBase);
        assertArrayEquals(COUNTS, mCounterArray.mCounts, "Unexpected counts");
        assertArrayEquals(COUNTS, mCounterArray.mCounts, "Unexpected counts");
        assertArrayEquals(LOADED_COUNTS, mCounterArray.mLoadedCounts, "Unexpected loadedCounts");
        assertArrayEquals(LOADED_COUNTS, mCounterArray.mLoadedCounts, "Unexpected loadedCounts");
        assertArrayEquals(COUNTS, mCounterArray.mPluggedCounts, "Unexpected pluggedCounts");
        assertArrayEquals(UNPLUGGED_COUNTS, mCounterArray.mUnpluggedCounts,
        assertArrayEquals(UNPLUGGED_COUNTS, mCounterArray.mUnpluggedCounts,
                "Unexpected unpluggedCounts");
                "Unexpected unpluggedCounts");
        parcel.recycle();
        parcel.recycle();
@@ -101,11 +101,10 @@ public class LongSamplingCounterArrayTest {
        parcel.setDataPosition(0);
        parcel.setDataPosition(0);


        // Now clear counterArray and verify values are read from parcel correctly.
        // Now clear counterArray and verify values are read from parcel correctly.
        updateCounts(null, null, null, null);
        updateCounts(null, null, null);
        mCounterArray = LongSamplingCounterArray.readSummaryFromParcelLocked(parcel, mTimeBase);
        mCounterArray = LongSamplingCounterArray.readSummaryFromParcelLocked(parcel, mTimeBase);
        assertArrayEquals(COUNTS, mCounterArray.mCounts, "Unexpected counts");
        assertArrayEquals(COUNTS, mCounterArray.mCounts, "Unexpected counts");
        assertArrayEquals(COUNTS, mCounterArray.mLoadedCounts, "Unexpected loadedCounts");
        assertArrayEquals(COUNTS, mCounterArray.mLoadedCounts, "Unexpected loadedCounts");
        assertArrayEquals(COUNTS, mCounterArray.mPluggedCounts, "Unexpected pluggedCounts");
        assertArrayEquals(COUNTS, mCounterArray.mUnpluggedCounts, "Unexpected unpluggedCounts");
        assertArrayEquals(COUNTS, mCounterArray.mUnpluggedCounts, "Unexpected unpluggedCounts");
        parcel.recycle();
        parcel.recycle();
    }
    }
@@ -116,8 +115,7 @@ public class LongSamplingCounterArrayTest {
        mCounterArray.onTimeStarted(0, 0, 0);
        mCounterArray.onTimeStarted(0, 0, 0);
        assertArrayEquals(COUNTS, mCounterArray.mCounts, "Unexpected counts");
        assertArrayEquals(COUNTS, mCounterArray.mCounts, "Unexpected counts");
        assertArrayEquals(LOADED_COUNTS, mCounterArray.mLoadedCounts, "Unexpected loadedCounts");
        assertArrayEquals(LOADED_COUNTS, mCounterArray.mLoadedCounts, "Unexpected loadedCounts");
        assertArrayEquals(PLUGGED_COUNTS, mCounterArray.mPluggedCounts, "Unexpected pluggedCounts");
        assertArrayEquals(COUNTS, mCounterArray.mUnpluggedCounts,
        assertArrayEquals(PLUGGED_COUNTS, mCounterArray.mUnpluggedCounts,
                "Unexpected unpluggedCounts");
                "Unexpected unpluggedCounts");
    }
    }


@@ -127,7 +125,6 @@ public class LongSamplingCounterArrayTest {
        mCounterArray.onTimeStopped(0, 0, 0);
        mCounterArray.onTimeStopped(0, 0, 0);
        assertArrayEquals(COUNTS, mCounterArray.mCounts, "Unexpected counts");
        assertArrayEquals(COUNTS, mCounterArray.mCounts, "Unexpected counts");
        assertArrayEquals(LOADED_COUNTS, mCounterArray.mLoadedCounts, "Unexpected loadedCounts");
        assertArrayEquals(LOADED_COUNTS, mCounterArray.mLoadedCounts, "Unexpected loadedCounts");
        assertArrayEquals(COUNTS, mCounterArray.mPluggedCounts, "Unexpected pluggedCounts");
        assertArrayEquals(UNPLUGGED_COUNTS, mCounterArray.mUnpluggedCounts,
        assertArrayEquals(UNPLUGGED_COUNTS, mCounterArray.mUnpluggedCounts,
                "Unexpected unpluggedCounts");
                "Unexpected unpluggedCounts");
    }
    }
@@ -137,24 +134,50 @@ public class LongSamplingCounterArrayTest {
        initializeCounterArrayWithDefaultValues();
        initializeCounterArrayWithDefaultValues();


        when(mTimeBase.isRunning()).thenReturn(false);
        when(mTimeBase.isRunning()).thenReturn(false);
        long[] actualVal = mCounterArray.getCountsLocked(STATS_SINCE_CHARGED);
        assertArrayEquals(COUNTS, mCounterArray.getCountsLocked(STATS_SINCE_CHARGED),
        long[] expectedVal = PLUGGED_COUNTS;
                "Unexpected values");
        assertArrayEquals(expectedVal, actualVal, "Unexpected values");
        assertArrayEquals(subtract(COUNTS, LOADED_COUNTS),
                mCounterArray.getCountsLocked(STATS_CURRENT), "Unexpected values");
        assertArrayEquals(subtract(COUNTS, UNPLUGGED_COUNTS),
                mCounterArray.getCountsLocked(STATS_SINCE_UNPLUGGED), "Unexpected values");


        when(mTimeBase.isRunning()).thenReturn(true);
        when(mTimeBase.isRunning()).thenReturn(true);
        actualVal = mCounterArray.getCountsLocked(STATS_SINCE_CHARGED);
        assertArrayEquals(COUNTS, mCounterArray.getCountsLocked(STATS_SINCE_CHARGED),
        expectedVal = COUNTS;
                "Unexpected values");
        assertArrayEquals(expectedVal, actualVal, "Unexpected values");
        assertArrayEquals(subtract(COUNTS, LOADED_COUNTS),
                mCounterArray.getCountsLocked(STATS_CURRENT), "Unexpected values");
        assertArrayEquals(subtract(COUNTS, UNPLUGGED_COUNTS),
                mCounterArray.getCountsLocked(STATS_SINCE_UNPLUGGED), "Unexpected values");
    }

    private long[] subtract(long[] val, long[] toSubtract) {
        final long[] result = val.clone();
        if (toSubtract != null) {
            for (int i = val.length - 1; i >= 0; --i) {
                result[i] -= toSubtract[i];
            }
        }
        return result;
    }
    }


    @Test
    @Test
    public void testAddCountLocked() {
    public void testAddCountLocked() {
        updateCounts(null, null, null);
        final long[] deltas = {123, 234, 345, 456};
        final long[] deltas = {123, 234, 345, 456};
        when(mTimeBase.isRunning()).thenReturn(true);
        when(mTimeBase.isRunning()).thenReturn(true);
        mCounterArray.addCountLocked(deltas);
        mCounterArray.addCountLocked(deltas);
        assertArrayEquals(deltas, mCounterArray.mCounts, "Unexpected counts");
        assertArrayEquals(deltas, mCounterArray.mCounts, "Unexpected counts");
        assertArrayEquals(null, mCounterArray.mLoadedCounts, "Unexpected loadedCounts");
        assertArrayEquals(null, mCounterArray.mLoadedCounts, "Unexpected loadedCounts");
        assertArrayEquals(null, mCounterArray.mPluggedCounts, "Unexpected pluggedCounts");
        assertArrayEquals(null, mCounterArray.mUnpluggedCounts, "Unexpected unpluggedCounts");

        updateCounts(null, null, null);
        mCounterArray.addCountLocked(deltas, false);
        assertArrayEquals(null, mCounterArray.mCounts, "Unexpected counts");
        assertArrayEquals(null, mCounterArray.mLoadedCounts, "Unexpected loadedCounts");
        assertArrayEquals(null, mCounterArray.mUnpluggedCounts, "Unexpected unpluggedCounts");
        mCounterArray.addCountLocked(deltas, true);
        assertArrayEquals(deltas, mCounterArray.mCounts, "Unexpected counts");
        assertArrayEquals(null, mCounterArray.mLoadedCounts, "Unexpected loadedCounts");
        assertArrayEquals(null, mCounterArray.mUnpluggedCounts, "Unexpected unpluggedCounts");
        assertArrayEquals(null, mCounterArray.mUnpluggedCounts, "Unexpected unpluggedCounts");


        initializeCounterArrayWithDefaultValues();
        initializeCounterArrayWithDefaultValues();
@@ -165,7 +188,18 @@ public class LongSamplingCounterArrayTest {
        mCounterArray.addCountLocked(deltas);
        mCounterArray.addCountLocked(deltas);
        assertArrayEquals(newCounts, mCounterArray.mCounts, "Unexpected counts");
        assertArrayEquals(newCounts, mCounterArray.mCounts, "Unexpected counts");
        assertArrayEquals(LOADED_COUNTS, mCounterArray.mLoadedCounts, "Unexpected loadedCounts");
        assertArrayEquals(LOADED_COUNTS, mCounterArray.mLoadedCounts, "Unexpected loadedCounts");
        assertArrayEquals(PLUGGED_COUNTS, mCounterArray.mPluggedCounts, "Unexpected pluggedCounts");
        assertArrayEquals(UNPLUGGED_COUNTS, mCounterArray.mUnpluggedCounts,
                "Unexpected unpluggedCounts");

        initializeCounterArrayWithDefaultValues();
        mCounterArray.addCountLocked(deltas, false);
        assertArrayEquals(COUNTS, mCounterArray.mCounts, "Unexpected counts");
        assertArrayEquals(LOADED_COUNTS, mCounterArray.mLoadedCounts, "Unexpected loadedCounts");
        assertArrayEquals(UNPLUGGED_COUNTS, mCounterArray.mUnpluggedCounts,
                "Unexpected unpluggedCounts");
        mCounterArray.addCountLocked(deltas, true);
        assertArrayEquals(newCounts, mCounterArray.mCounts, "Unexpected counts");
        assertArrayEquals(LOADED_COUNTS, mCounterArray.mLoadedCounts, "Unexpected loadedCounts");
        assertArrayEquals(UNPLUGGED_COUNTS, mCounterArray.mUnpluggedCounts,
        assertArrayEquals(UNPLUGGED_COUNTS, mCounterArray.mUnpluggedCounts,
                "Unexpected unpluggedCounts");
                "Unexpected unpluggedCounts");
    }
    }
@@ -177,7 +211,6 @@ public class LongSamplingCounterArrayTest {
        mCounterArray.reset(false /* detachIfReset */);
        mCounterArray.reset(false /* detachIfReset */);
        assertArrayEquals(ZEROES, mCounterArray.mCounts, "Unexpected counts");
        assertArrayEquals(ZEROES, mCounterArray.mCounts, "Unexpected counts");
        assertArrayEquals(ZEROES, mCounterArray.mLoadedCounts, "Unexpected loadedCounts");
        assertArrayEquals(ZEROES, mCounterArray.mLoadedCounts, "Unexpected loadedCounts");
        assertArrayEquals(ZEROES, mCounterArray.mPluggedCounts, "Unexpected pluggedCounts");
        assertArrayEquals(ZEROES, mCounterArray.mUnpluggedCounts, "Unexpected unpluggedCounts");
        assertArrayEquals(ZEROES, mCounterArray.mUnpluggedCounts, "Unexpected unpluggedCounts");
        verifyZeroInteractions(mTimeBase);
        verifyZeroInteractions(mTimeBase);


@@ -186,7 +219,6 @@ public class LongSamplingCounterArrayTest {
        mCounterArray.reset(true /* detachIfReset */);
        mCounterArray.reset(true /* detachIfReset */);
        assertArrayEquals(ZEROES, mCounterArray.mCounts, "Unexpected counts");
        assertArrayEquals(ZEROES, mCounterArray.mCounts, "Unexpected counts");
        assertArrayEquals(ZEROES, mCounterArray.mLoadedCounts, "Unexpected loadedCounts");
        assertArrayEquals(ZEROES, mCounterArray.mLoadedCounts, "Unexpected loadedCounts");
        assertArrayEquals(ZEROES, mCounterArray.mPluggedCounts, "Unexpected pluggedCounts");
        assertArrayEquals(ZEROES, mCounterArray.mUnpluggedCounts, "Unexpected unpluggedCounts");
        assertArrayEquals(ZEROES, mCounterArray.mUnpluggedCounts, "Unexpected unpluggedCounts");
        verify(mTimeBase).remove(mCounterArray);
        verify(mTimeBase).remove(mCounterArray);
        verifyNoMoreInteractions(mTimeBase);
        verifyNoMoreInteractions(mTimeBase);
@@ -200,7 +232,7 @@ public class LongSamplingCounterArrayTest {
    }
    }


    private void initializeCounterArrayWithDefaultValues() {
    private void initializeCounterArrayWithDefaultValues() {
        updateCounts(COUNTS, LOADED_COUNTS, PLUGGED_COUNTS, UNPLUGGED_COUNTS);
        updateCounts(COUNTS, LOADED_COUNTS, UNPLUGGED_COUNTS);
    }
    }


    private void assertArrayEquals(long[] expected, long[] actual, String msg) {
    private void assertArrayEquals(long[] expected, long[] actual, String msg) {
@@ -208,11 +240,9 @@ public class LongSamplingCounterArrayTest {
                + ", actual: " + Arrays.toString(actual), Arrays.equals(expected, actual));
                + ", actual: " + Arrays.toString(actual), Arrays.equals(expected, actual));
    }
    }


    private void updateCounts(long[] counts, long[] loadedCounts,
    private void updateCounts(long[] counts, long[] loadedCounts, long[] unpluggedCounts) {
            long[] pluggedCounts, long[] unpluggedCounts) {
        mCounterArray.mCounts = counts == null ? null : counts.clone();
        mCounterArray.mCounts = counts;
        mCounterArray.mLoadedCounts = loadedCounts == null ? null : loadedCounts.clone();
        mCounterArray.mLoadedCounts = loadedCounts;
        mCounterArray.mUnpluggedCounts = unpluggedCounts == null ? null : unpluggedCounts.clone();
        mCounterArray.mPluggedCounts = pluggedCounts;
        mCounterArray.mUnpluggedCounts = unpluggedCounts;
    }
    }
}
}
+4 −2
Original line number Original line Diff line number Diff line
@@ -139,12 +139,14 @@ public class MockBatteryStatsImpl extends BatteryStatsImpl {
        }
        }


        @Override
        @Override
        public Future<?> scheduleReadProcStateCpuTimes() {
        public Future<?> scheduleReadProcStateCpuTimes(
                boolean onBattery, boolean onBatteryScreenOff) {
            return null;
            return null;
        }
        }


        @Override
        @Override
        public Future<?> scheduleCopyFromAllUidsCpuTimes() {
        public Future<?> scheduleCopyFromAllUidsCpuTimes(
                boolean onBattery, boolean onBatteryScreenOff) {
            return null;
            return null;
        }
        }


+10 −18
Original line number Original line Diff line number Diff line
@@ -35,6 +35,7 @@ import android.util.TimeUtils;


import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.os.BatteryStatsImpl;
import com.android.internal.os.BatteryStatsImpl;
import com.android.internal.util.function.pooled.PooledLambda;


import libcore.util.EmptyArray;
import libcore.util.EmptyArray;


@@ -117,7 +118,7 @@ class BatteryExternalStatsWorker implements BatteryStatsImpl.ExternalStatsSync {
    }
    }


    @Override
    @Override
    public Future<?> scheduleReadProcStateCpuTimes() {
    public Future<?> scheduleReadProcStateCpuTimes(boolean onBattery, boolean onBatteryScreenOff) {
        synchronized (mStats) {
        synchronized (mStats) {
            if (!mStats.mPerProcStateCpuTimesAvailable) {
            if (!mStats.mPerProcStateCpuTimesAvailable) {
                return null;
                return null;
@@ -125,14 +126,17 @@ class BatteryExternalStatsWorker implements BatteryStatsImpl.ExternalStatsSync {
        }
        }
        synchronized (BatteryExternalStatsWorker.this) {
        synchronized (BatteryExternalStatsWorker.this) {
            if (!mExecutorService.isShutdown()) {
            if (!mExecutorService.isShutdown()) {
                return mExecutorService.submit(mReadProcStateCpuTimesTask);
                return mExecutorService.submit(PooledLambda.obtainRunnable(
                        BatteryStatsImpl::updateProcStateCpuTimes,
                        mStats, onBattery, onBatteryScreenOff).recycleOnUse());
            }
            }
        }
        }
        return null;
        return null;
    }
    }


    @Override
    @Override
    public Future<?> scheduleCopyFromAllUidsCpuTimes() {
    public Future<?> scheduleCopyFromAllUidsCpuTimes(
            boolean onBattery, boolean onBatteryScreenOff) {
        synchronized (mStats) {
        synchronized (mStats) {
            if (!mStats.mPerProcStateCpuTimesAvailable) {
            if (!mStats.mPerProcStateCpuTimesAvailable) {
                return null;
                return null;
@@ -140,26 +144,14 @@ class BatteryExternalStatsWorker implements BatteryStatsImpl.ExternalStatsSync {
        }
        }
        synchronized (BatteryExternalStatsWorker.this) {
        synchronized (BatteryExternalStatsWorker.this) {
            if (!mExecutorService.isShutdown()) {
            if (!mExecutorService.isShutdown()) {
                return mExecutorService.submit(mCopyFromAllUidsCpuTimesTask);
                return mExecutorService.submit(PooledLambda.obtainRunnable(
                        BatteryStatsImpl::copyFromAllUidsCpuTimes,
                        mStats, onBattery, onBatteryScreenOff).recycleOnUse());
            }
            }
        }
        }
        return null;
        return null;
    }
    }


    private final Runnable mReadProcStateCpuTimesTask = new Runnable() {
        @Override
        public void run() {
            mStats.updateProcStateCpuTimes();
        }
    };

    private final Runnable mCopyFromAllUidsCpuTimesTask = new Runnable() {
        @Override
        public void run() {
            mStats.copyFromAllUidsCpuTimes();
        }
    };

    public synchronized Future<?> scheduleWrite() {
    public synchronized Future<?> scheduleWrite() {
        if (mExecutorService.isShutdown()) {
        if (mExecutorService.isShutdown()) {
            return CompletableFuture.failedFuture(new IllegalStateException("worker shutdown"));
            return CompletableFuture.failedFuture(new IllegalStateException("worker shutdown"));