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

Commit c8c44960 authored by Bookatz's avatar Bookatz
Browse files

Cumulative wakelock time per uid

Currently, the time for each partial wakelock was tracked. If one
wants the total time that a uid held partial wakelocks (over all of its
wakelocks), they could sum over all the uid's partial wakelock
totalTimes, but this would underestimate the value because totalTimes
are pooled amongst all uids. Alternatively, they could sum over all the
uid's partial wakelock totalDurations, but this would overestimate the
value because totalDurations are not pooled within the uid (so there
will be double-counting if two wakelocks are held simultaneously). This
cl adds a new timer that specifically tracks the actual total time that
the uid spent holding wakelocks, and also provides the ability to see
how much time the uid was in the background when doing so.

Bug: 38198272
Test: runtest -x frameworks/base/core/tests/coretests/src/com/android/internal/os/BatteryStatsTests.java

Change-Id: I20ea3546338c44ffdf06859bc840d9059fb18321
parent b2bd3292
Loading
Loading
Loading
Loading
+114 −56
Original line number Diff line number Diff line
@@ -156,6 +156,11 @@ public abstract class BatteryStats implements Parcelable {
     */
    public static final int BLUETOOTH_SCAN_ON = 19;

    /**
     * A constant indicating an aggregated partial wake lock timer.
     */
    public static final int AGGREGATED_WAKE_TYPE_PARTIAL = 20;

    /**
     * Include all of the data in the stats, including previously saved data.
     */
@@ -185,6 +190,7 @@ public abstract class BatteryStats implements Parcelable {
     *   - Background timers and counters for: Sensor, BluetoothScan, WifiScan, Jobs, Syncs.
     * New in version 21:
     *   - Actual (not just apportioned) Wakelock time is also recorded.
     *   - Aggregated partial wakelock time (per uid, instead of per wakelock) is recorded.
     */
    static final String CHECKIN_VERSION = "21";

@@ -216,6 +222,10 @@ public abstract class BatteryStats implements Parcelable {
    // window totalTime,  'w', count, current duration, max duration, total duration
    // [Currently, full and window wakelocks have durations current = max = total = -1]
    private static final String WAKELOCK_DATA = "wl";
    // awl line is:
    // BATTERY_STATS_CHECKIN_VERSION, uid, which, "awl",
    // cumulative partial wakelock duration, cumulative background partial wakelock duration
    private static final String AGGREGATED_WAKELOCK_DATA = "awl";
    private static final String SYNC_DATA = "sy";
    private static final String JOB_DATA = "jb";
    private static final String KERNEL_WAKELOCK_DATA = "kwl";
@@ -484,6 +494,13 @@ public abstract class BatteryStats implements Parcelable {
            public abstract Timer getWakeTime(int type);
        }

        /**
         * The cumulative time the uid spent holding any partial wakelocks. This will generally
         * differ from summing over the Wakelocks in getWakelockStats since the latter may have
         * wakelocks that overlap in time (and therefore over-counts).
         */
        public abstract Timer getAggregatedPartialWakelockTimer();

        /**
         * Returns a mapping containing sensor statistics.
         *
@@ -3435,6 +3452,16 @@ public abstract class BatteryStats implements Parcelable {
                }
            }

            if (u.getAggregatedPartialWakelockTimer() != null) {
                final Timer timer = u.getAggregatedPartialWakelockTimer();
                // Convert from microseconds to milliseconds with rounding
                final long totTimeMs = (timer.getTotalTimeLocked(rawRealtime, which) + 500) / 1000;
                final Timer bgTimer = timer.getSubTimer();
                final long bgTimeMs = bgTimer != null ?
                        (bgTimer.getTotalTimeLocked(rawRealtime, which) + 500) / 1000 : 0;
                dumpLine(pw, uid, category, AGGREGATED_WAKELOCK_DATA, totTimeMs, bgTimeMs);
            }

            final ArrayMap<String, ? extends Uid.Wakelock> wakelocks = u.getWakelockStats();
            for (int iw=wakelocks.size()-1; iw>=0; iw--) {
                final Uid.Wakelock wl = wakelocks.valueAt(iw);
@@ -4690,8 +4717,23 @@ public abstract class BatteryStats implements Parcelable {
                        rawRealtime, which);
            }
            if (countWakelock > 1) {
                if (totalFullWakelock != 0 || totalPartialWakelock != 0
                        || totalWindowWakelock != 0) {
                // get unpooled partial wakelock quantities (unlike totalPartialWakelock, which is
                // pooled and therefore just a lower bound)
                long actualTotalPartialWakelock = 0;
                long actualBgPartialWakelock = 0;
                if (u.getAggregatedPartialWakelockTimer() != null) {
                    final Timer aggTimer = u.getAggregatedPartialWakelockTimer();
                    // Convert from microseconds to milliseconds with rounding
                    actualTotalPartialWakelock =
                            (aggTimer.getTotalTimeLocked(rawRealtime, which) + 500) / 1000;
                    final Timer bgAggTimer = aggTimer.getSubTimer();
                    actualBgPartialWakelock = bgAggTimer != null ?
                            (bgAggTimer.getTotalTimeLocked(rawRealtime, which) + 500) / 1000 : 0;
                }

                if (actualTotalPartialWakelock != 0 || actualBgPartialWakelock != 0 ||
                        totalFullWakelock != 0 || totalPartialWakelock != 0 ||
                        totalWindowWakelock != 0) {
                    sb.setLength(0);
                    sb.append(prefix);
                    sb.append("    TOTAL wake: ");
@@ -4707,7 +4749,23 @@ public abstract class BatteryStats implements Parcelable {
                        }
                        needComma = true;
                        formatTimeMs(sb, totalPartialWakelock);
                        sb.append("partial");
                        sb.append("blamed partial");
                    }
                    if (actualTotalPartialWakelock != 0) {
                        if (needComma) {
                            sb.append(", ");
                        }
                        needComma = true;
                        formatTimeMs(sb, actualTotalPartialWakelock);
                        sb.append("actual partial");
                    }
                    if (actualBgPartialWakelock != 0) {
                        if (needComma) {
                            sb.append(", ");
                        }
                        needComma = true;
                        formatTimeMs(sb, actualBgPartialWakelock);
                        sb.append("actual background partial");
                    }
                    if (totalWindowWakelock != 0) {
                        if (needComma) {
+95 −18
Original line number Diff line number Diff line
@@ -116,7 +116,7 @@ public class BatteryStatsImpl extends BatteryStats {
    private static final int MAGIC = 0xBA757475; // 'BATSTATS'

    // Current on-disk Parcel version
    private static final int VERSION = 157 + (USE_OLD_HISTORY ? 1000 : 0);
    private static final int VERSION = 158 + (USE_OLD_HISTORY ? 1000 : 0);

    // Maximum number of items we will record in the history.
    private static final int MAX_HISTORY_ITEMS = 2000;
@@ -3428,7 +3428,7 @@ public class BatteryStatsImpl extends BatteryStats {

        if (batteryStatusChanged) {
            for (int i = 0; i < mUidStats.size(); i++) {
                mUidStats.valueAt(i).updateBgTimeBase(uptime, realtime);
                mUidStats.valueAt(i).updateOnBatteryBgTimeBase(uptime, realtime);
            }
        }

@@ -3442,6 +3442,9 @@ public class BatteryStatsImpl extends BatteryStats {
            }
            updateCpuTimeLocked();
            mOnBatteryScreenOffTimeBase.setRunning(unpluggedScreenOff, uptime, realtime);
            for (int i = 0; i < mUidStats.size(); i++) {
                mUidStats.valueAt(i).updateOnBatteryScreenOffBgTimeBase(uptime, realtime);
            }
        }
    }

@@ -5541,6 +5544,8 @@ public class BatteryStatsImpl extends BatteryStats {
        /** TimeBase for when uid is in background and device is on battery. */
        @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
        public final TimeBase mOnBatteryBackgroundTimeBase;
        @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
        public final TimeBase mOnBatteryScreenOffBackgroundTimeBase;

        boolean mWifiRunning;
        StopwatchTimer mWifiRunningTimer;
@@ -5563,6 +5568,8 @@ public class BatteryStatsImpl extends BatteryStats {
        StopwatchTimer mFlashlightTurnedOnTimer;
        StopwatchTimer mCameraTurnedOnTimer;
        StopwatchTimer mForegroundActivityTimer;
        /** Total time spent by the uid holding any partial wakelocks. */
        DualTimer mAggregatedPartialWakelockTimer;
        DualTimer mBluetoothScanTimer;
        Counter mBluetoothScanResultCounter;

@@ -5664,6 +5671,10 @@ public class BatteryStatsImpl extends BatteryStats {
            mOnBatteryBackgroundTimeBase.init(mBsi.mClocks.uptimeMillis() * 1000,
                    mBsi.mClocks.elapsedRealtime() * 1000);

            mOnBatteryScreenOffBackgroundTimeBase = new TimeBase();
            mOnBatteryScreenOffBackgroundTimeBase.init(mBsi.mClocks.uptimeMillis() * 1000,
                    mBsi.mClocks.elapsedRealtime() * 1000);

            mUserCpuTime = new LongSamplingCounter(mBsi.mOnBatteryTimeBase);
            mSystemCpuTime = new LongSamplingCounter(mBsi.mOnBatteryTimeBase);

@@ -5733,6 +5744,11 @@ public class BatteryStatsImpl extends BatteryStats {
            return null;
        }

        @Override
        public Timer getAggregatedPartialWakelockTimer() {
            return mAggregatedPartialWakelockTimer;
        }

        @Override
        public ArrayMap<String, ? extends BatteryStats.Uid.Wakelock> getWakelockStats() {
            return mWakelockStats.getMap();
@@ -6022,6 +6038,15 @@ public class BatteryStatsImpl extends BatteryStats {
            return mForegroundActivityTimer;
        }

        public DualTimer createAggregatedPartialWakelockTimerLocked() {
            if (mAggregatedPartialWakelockTimer == null) {
                mAggregatedPartialWakelockTimer = new DualTimer(mBsi.mClocks, this,
                        AGGREGATED_WAKE_TYPE_PARTIAL, null,
                        mBsi.mOnBatteryScreenOffTimeBase, mOnBatteryScreenOffBackgroundTimeBase);
            }
            return mAggregatedPartialWakelockTimer;
        }

        public DualTimer createBluetoothScanTimerLocked() {
            if (mBluetoothScanTimer == null) {
                mBluetoothScanTimer = new DualTimer(mBsi.mClocks, Uid.this, BLUETOOTH_SCAN_ON,
@@ -6464,6 +6489,7 @@ public class BatteryStatsImpl extends BatteryStats {
            active |= !resetTimerIfNotNull(mFlashlightTurnedOnTimer, false);
            active |= !resetTimerIfNotNull(mCameraTurnedOnTimer, false);
            active |= !resetTimerIfNotNull(mForegroundActivityTimer, false);
            active |= !resetTimerIfNotNull(mAggregatedPartialWakelockTimer, false);
            active |= !resetTimerIfNotNull(mBluetoothScanTimer, false);
            if (mBluetoothScanResultCounter != null) {
                mBluetoothScanResultCounter.reset(false);
@@ -6616,6 +6642,8 @@ public class BatteryStatsImpl extends BatteryStats {

            mOnBatteryBackgroundTimeBase.reset(mBsi.mClocks.elapsedRealtime() * 1000,
                    mBsi.mClocks.uptimeMillis() * 1000);
            mOnBatteryScreenOffBackgroundTimeBase.reset(mBsi.mClocks.elapsedRealtime() * 1000,
                    mBsi.mClocks.uptimeMillis() * 1000);

            if (!active) {
                if (mWifiRunningTimer != null) {
@@ -6655,6 +6683,10 @@ public class BatteryStatsImpl extends BatteryStats {
                    mForegroundActivityTimer.detach();
                    mForegroundActivityTimer = null;
                }
                if (mAggregatedPartialWakelockTimer != null) {
                    mAggregatedPartialWakelockTimer.detach();
                    mAggregatedPartialWakelockTimer = null;
                }
                if (mBluetoothScanTimer != null) {
                    mBluetoothScanTimer.detach();
                    mBluetoothScanTimer = null;
@@ -6720,6 +6752,7 @@ public class BatteryStatsImpl extends BatteryStats {

        void writeToParcelLocked(Parcel out, long uptimeUs, long elapsedRealtimeUs) {
            mOnBatteryBackgroundTimeBase.writeToParcel(out, uptimeUs, elapsedRealtimeUs);
            mOnBatteryScreenOffBackgroundTimeBase.writeToParcel(out, uptimeUs, elapsedRealtimeUs);

            final ArrayMap<String, Wakelock> wakeStats = mWakelockStats.getMap();
            int NW = wakeStats.size();
@@ -6834,6 +6867,12 @@ public class BatteryStatsImpl extends BatteryStats {
            } else {
                out.writeInt(0);
            }
            if (mAggregatedPartialWakelockTimer != null) {
                out.writeInt(1);
                mAggregatedPartialWakelockTimer.writeToParcel(out, elapsedRealtimeUs);
            } else {
                out.writeInt(0);
            }
            if (mBluetoothScanTimer != null) {
                out.writeInt(1);
                mBluetoothScanTimer.writeToParcel(out, elapsedRealtimeUs);
@@ -6957,6 +6996,7 @@ public class BatteryStatsImpl extends BatteryStats {

        void readFromParcelLocked(TimeBase timeBase, TimeBase screenOffTimeBase, Parcel in) {
            mOnBatteryBackgroundTimeBase.readFromParcel(in);
            mOnBatteryScreenOffBackgroundTimeBase.readFromParcel(in);

            int numWakelocks = in.readInt();
            mWakelockStats.clear();
@@ -7082,6 +7122,14 @@ public class BatteryStatsImpl extends BatteryStats {
            } else {
                mForegroundActivityTimer = null;
            }
            if (in.readInt() != 0) {
                mAggregatedPartialWakelockTimer = new DualTimer(mBsi.mClocks, this,
                        AGGREGATED_WAKE_TYPE_PARTIAL, null,
                        mBsi.mOnBatteryScreenOffTimeBase, mOnBatteryScreenOffBackgroundTimeBase,
                        in);
            } else {
                mAggregatedPartialWakelockTimer = null;
            }
            if (in.readInt() != 0) {
                mBluetoothScanTimer = new DualTimer(mBsi.mClocks, Uid.this, BLUETOOTH_SCAN_ON,
                        mBsi.mBluetoothScanOnTimers, mBsi.mOnBatteryTimeBase,
@@ -8202,15 +8250,25 @@ public class BatteryStatsImpl extends BatteryStats {
                mProcessStateTimer[uidRunningState].startRunningLocked(elapsedRealtimeMs);
            }

            updateBgTimeBase(uptimeMs * 1000, elapsedRealtimeMs * 1000);
            updateOnBatteryBgTimeBase(uptimeMs * 1000, elapsedRealtimeMs * 1000);
            updateOnBatteryScreenOffBgTimeBase(uptimeMs * 1000, elapsedRealtimeMs * 1000);
        }

        public boolean updateBgTimeBase(long uptimeUs, long realtimeUs) {
        /** Whether to consider Uid to be in the background for background timebase purposes. */
        public boolean isInBackground() {
            // Note that PROCESS_STATE_CACHED and ActivityManager.PROCESS_STATE_NONEXISTENT is
            // also considered to be 'background' for our purposes, because it's not foreground.
            boolean isBgAndUnplugged = mBsi.mOnBatteryTimeBase.isRunning()
                    && mProcessState >= PROCESS_STATE_BACKGROUND;
            return mOnBatteryBackgroundTimeBase.setRunning(isBgAndUnplugged, uptimeUs, realtimeUs);
            return mProcessState >= PROCESS_STATE_BACKGROUND;
        }

        public boolean updateOnBatteryBgTimeBase(long uptimeUs, long realtimeUs) {
            boolean on = mBsi.mOnBatteryTimeBase.isRunning() && isInBackground();
            return mOnBatteryBackgroundTimeBase.setRunning(on, uptimeUs, realtimeUs);
        }

        public boolean updateOnBatteryScreenOffBgTimeBase(long uptimeUs, long realtimeUs) {
            boolean on = mBsi.mOnBatteryScreenOffTimeBase.isRunning() && isInBackground();
            return mOnBatteryScreenOffBackgroundTimeBase.setRunning(on, uptimeUs, realtimeUs);
        }

        public SparseArray<? extends Pid> getPidStats() {
@@ -8341,20 +8399,27 @@ public class BatteryStatsImpl extends BatteryStats {
            if (wl != null) {
                wl.getStopwatchTimer(type).startRunningLocked(elapsedRealtimeMs);
            }
            if (pid >= 0 && type == WAKE_TYPE_PARTIAL) {
            if (type == WAKE_TYPE_PARTIAL) {
                createAggregatedPartialWakelockTimerLocked().startRunningLocked(elapsedRealtimeMs);
                if (pid >= 0) {
                    Pid p = getPidStatsLocked(pid);
                    if (p.mWakeNesting++ == 0) {
                        p.mWakeStartMs = elapsedRealtimeMs;
                    }
                }
            }
        }

        public void noteStopWakeLocked(int pid, String name, int type, long elapsedRealtimeMs) {
            Wakelock wl = mWakelockStats.stopObject(name);
            if (wl != null) {
                wl.getStopwatchTimer(type).stopRunningLocked(elapsedRealtimeMs);
            }
            if (pid >= 0 && type == WAKE_TYPE_PARTIAL) {
            if (type == WAKE_TYPE_PARTIAL) {
                if (mAggregatedPartialWakelockTimer != null) {
                    mAggregatedPartialWakelockTimer.stopRunningLocked(elapsedRealtimeMs);
                }
                if (pid >= 0) {
                    Pid p = mPids.get(pid);
                    if (p != null && p.mWakeNesting > 0) {
                        if (p.mWakeNesting-- == 1) {
@@ -8364,6 +8429,7 @@ public class BatteryStatsImpl extends BatteryStats {
                    }
                }
            }
        }

        public void reportExcessiveWakeLocked(String proc, long overTime, long usedTime) {
            Proc p = getProcessStatsLocked(proc);
@@ -11243,6 +11309,7 @@ public class BatteryStatsImpl extends BatteryStats {
            mUidStats.put(uid, u);

            u.mOnBatteryBackgroundTimeBase.readSummaryFromParcel(in);
            u.mOnBatteryScreenOffBackgroundTimeBase.readSummaryFromParcel(in);

            u.mWifiRunning = false;
            if (in.readInt() != 0) {
@@ -11282,6 +11349,9 @@ public class BatteryStatsImpl extends BatteryStats {
            if (in.readInt() != 0) {
                u.createForegroundActivityTimerLocked().readSummaryFromParcelLocked(in);
            }
            if (in.readInt() != 0) {
                u.createAggregatedPartialWakelockTimerLocked().readSummaryFromParcelLocked(in);
            }
            if (in.readInt() != 0) {
                u.createBluetoothScanTimerLocked().readSummaryFromParcelLocked(in);
            }
@@ -11628,6 +11698,7 @@ public class BatteryStatsImpl extends BatteryStats {
            Uid u = mUidStats.valueAt(iu);

            u.mOnBatteryBackgroundTimeBase.writeSummaryToParcel(out, NOW_SYS, NOWREAL_SYS);
            u.mOnBatteryScreenOffBackgroundTimeBase.writeSummaryToParcel(out, NOW_SYS, NOWREAL_SYS);

            if (u.mWifiRunningTimer != null) {
                out.writeInt(1);
@@ -11691,6 +11762,12 @@ public class BatteryStatsImpl extends BatteryStats {
            } else {
                out.writeInt(0);
            }
            if (u.mAggregatedPartialWakelockTimer != null) {
                out.writeInt(1);
                u.mAggregatedPartialWakelockTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
            } else {
                out.writeInt(0);
            }
            if (u.mBluetoothScanTimer != null) {
                out.writeInt(1);
                u.mBluetoothScanTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
+49 −0
Original line number Diff line number Diff line
@@ -100,6 +100,55 @@ public class BatteryStatsBackgroundStatsTest extends TestCase {
        assertEquals(227_000, bgtb.computeRealtime(cur, STATS_SINCE_CHARGED));
    }

    /** Test that BatteryStatsImpl.Uid.mOnBatteryScreenOffBackgroundTimeBase works correctly. */
    @SmallTest
    public void testScreenOffBgTimeBase() throws Exception {
        final MockClocks clocks = new MockClocks(); // holds realtime and uptime in ms
        MockBatteryStatsImpl bi = new MockBatteryStatsImpl(clocks);
        long cur = 0; // realtime in us

        BatteryStatsImpl.TimeBase bgtb = bi.getOnBatteryScreenOffBackgroundTimeBase(UID);

        // battery=off, screen=off, background=off
        cur = (clocks.realtime = clocks.uptime = 100) * 1000;
        bi.noteUidProcessStateLocked(UID, ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND);
        bi.updateTimeBasesLocked(false, false, cur, cur);
        assertFalse(bgtb.isRunning());

        // battery=on, screen=off, background=off
        cur = (clocks.realtime = clocks.uptime = 200) * 1000;
        bi.updateTimeBasesLocked(true, false, cur, cur);
        assertFalse(bgtb.isRunning());

        // battery=on, screen=on, background=off
        cur = (clocks.realtime = clocks.uptime = 300) * 1000;
        bi.updateTimeBasesLocked(true, true, cur, cur);
        assertFalse(bgtb.isRunning());

        // battery=on, screen=on, background=on
        // Only during this period should the timebase progress
        cur = (clocks.realtime = clocks.uptime = 400) * 1000;
        bi.noteUidProcessStateLocked(UID, ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND);
        assertTrue(bgtb.isRunning());

        // battery=on, screen=off, background=on
        cur = (clocks.realtime = clocks.uptime = 550) * 1000;
        bi.updateTimeBasesLocked(true, false, cur, cur);
        assertFalse(bgtb.isRunning());

        // battery=off, screen=off, background=on
        cur = (clocks.realtime = clocks.uptime = 660) * 1000;
        bi.updateTimeBasesLocked(false, false, cur, cur);
        assertFalse(bgtb.isRunning());

        // battery=off, screen=off, background=off
        cur = (clocks.realtime = clocks.uptime = 770) * 1000;
        bi.noteUidProcessStateLocked(UID, ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND);
        assertFalse(bgtb.isRunning());

        assertEquals(150_000, bgtb.computeRealtime(cur, STATS_SINCE_CHARGED));
    }

    @SmallTest
    public void testWifiScan() throws Exception {
        final MockClocks clocks = new MockClocks();
+30 −1
Original line number Diff line number Diff line
@@ -16,7 +16,10 @@
package com.android.internal.os;

import static android.os.BatteryStats.STATS_SINCE_CHARGED;
import static android.os.BatteryStats.WAKE_TYPE_PARTIAL;

import android.app.ActivityManager;
import android.os.BatteryStats;
import android.os.WorkSource;
import android.support.test.filters.SmallTest;

@@ -29,7 +32,7 @@ public class BatteryStatsNoteTest extends TestCase{
    private static final int UID = 10500;
    private static final WorkSource WS = new WorkSource(UID);

    /** Test that BatteryStatsImpl.Uid.noteBluetoothScanResultsLocked. */
    /** Test BatteryStatsImpl.Uid.noteBluetoothScanResultLocked. */
    @SmallTest
    public void testNoteBluetoothScanResultLocked() throws Exception {
        MockBatteryStatsImpl bi = new MockBatteryStatsImpl(new MockClocks());
@@ -41,4 +44,30 @@ public class BatteryStatsNoteTest extends TestCase{
                bi.getUidStats().get(UID).getBluetoothScanResultCounter()
                        .getCountLocked(STATS_SINCE_CHARGED));
    }

    /** Test BatteryStatsImpl.Uid.noteStartWakeLocked. */
    @SmallTest
    public void testNoteStartWakeLocked() throws Exception {
        final MockClocks clocks = new MockClocks(); // holds realtime and uptime in ms
        MockBatteryStatsImpl bi = new MockBatteryStatsImpl(clocks);

        int pid = 10;
        String name = "name";

        bi.updateTimeBasesLocked(true, true, 0, 0);
        bi.noteUidProcessStateLocked(UID, ActivityManager.PROCESS_STATE_TOP);
        bi.getUidStatsLocked(UID).noteStartWakeLocked(pid, name, WAKE_TYPE_PARTIAL, clocks.realtime);

        clocks.realtime = clocks.uptime = 100;
        bi.noteUidProcessStateLocked(UID, ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND);

        clocks.realtime = clocks.uptime = 220;
        bi.getUidStatsLocked(UID).noteStopWakeLocked(pid, name, WAKE_TYPE_PARTIAL, clocks.realtime);

        BatteryStats.Timer aggregTimer = bi.getUidStats().get(UID).getAggregatedPartialWakelockTimer();
        long actualTime = aggregTimer.getTotalTimeLocked(300_000, STATS_SINCE_CHARGED);
        long bgTime = aggregTimer.getSubTimer().getTotalTimeLocked(300_000, STATS_SINCE_CHARGED);
        assertEquals(220_000, actualTime);
        assertEquals(120_000, bgTime);
    }
}
+4 −0
Original line number Diff line number Diff line
@@ -44,5 +44,9 @@ public class MockBatteryStatsImpl extends BatteryStatsImpl {
    public TimeBase getOnBatteryBackgroundTimeBase(int uid) {
        return getUidStatsLocked(uid).mOnBatteryBackgroundTimeBase;
    }

    public TimeBase getOnBatteryScreenOffBackgroundTimeBase(int uid) {
        return getUidStatsLocked(uid).mOnBatteryScreenOffBackgroundTimeBase;
    }
}