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

Commit 892a3613 authored by Michael Wachenschwanz's avatar Michael Wachenschwanz Committed by Android (Google) Code Review
Browse files

Merge "Add Foreground Service Timer"

parents c956914d b05a3c5f
Loading
Loading
Loading
Loading
+30 −11
Original line number Diff line number Diff line
@@ -16,15 +16,6 @@

package android.os;

import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Formatter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import android.app.job.JobParameters;
import android.content.Context;
import android.content.pm.ApplicationInfo;
@@ -43,6 +34,15 @@ import android.view.Display;
import com.android.internal.os.BatterySipper;
import com.android.internal.os.BatteryStatsHelper;

import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Formatter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * A class providing access to battery usage statistics, including information on
 * wakelocks, processes, packages, and services.  All times are represented in microseconds
@@ -167,6 +167,11 @@ public abstract class BatteryStats implements Parcelable {
     */
    public static final int BLUETOOTH_UNOPTIMIZED_SCAN_ON = 21;

    /**
     * A constant indicating a foreground service timer
     */
    public static final int FOREGROUND_SERVICE = 22;

    /**
     * Include all of the data in the stats, including previously saved data.
     */
@@ -223,7 +228,11 @@ public abstract class BatteryStats implements Parcelable {
    private static final String CPU_TIMES_AT_FREQ_DATA = "ctf";
    private static final String SENSOR_DATA = "sr";
    private static final String VIBRATOR_DATA = "vib";
    private static final String FOREGROUND_DATA = "fg";
    private static final String FOREGROUND_ACTIVITY_DATA = "fg";
    // fgs line is:
    // BATTERY_STATS_CHECKIN_VERSION, uid, category, "fgs",
    // foreground service time, count
    private static final String FOREGROUND_SERVICE_DATA = "fgs";
    private static final String STATE_TIME_DATA = "st";
    // wl line is:
    // BATTERY_STATS_CHECKIN_VERSION, uid, which, "wl", name,
@@ -582,6 +591,11 @@ public abstract class BatteryStats implements Parcelable {
        public abstract Timer getFlashlightTurnedOnTimer();
        public abstract Timer getCameraTurnedOnTimer();
        public abstract Timer getForegroundActivityTimer();

        /**
         * Returns the timer keeping track of Foreground Service time
         */
        public abstract Timer getForegroundServiceTimer();
        public abstract Timer getBluetoothScanTimer();
        public abstract Timer getBluetoothScanBackgroundTimer();
        public abstract Timer getBluetoothUnoptimizedScanTimer();
@@ -3616,7 +3630,10 @@ public abstract class BatteryStats implements Parcelable {
            dumpTimer(pw, uid, category, VIBRATOR_DATA, u.getVibratorOnTimer(),
                    rawRealtime, which);

            dumpTimer(pw, uid, category, FOREGROUND_DATA, u.getForegroundActivityTimer(),
            dumpTimer(pw, uid, category, FOREGROUND_ACTIVITY_DATA, u.getForegroundActivityTimer(),
                    rawRealtime, which);

            dumpTimer(pw, uid, category, FOREGROUND_SERVICE_DATA, u.getForegroundServiceTimer(),
                    rawRealtime, which);

            final Object[] stateTimes = new Object[Uid.NUM_PROCESS_STATE];
@@ -5093,6 +5110,8 @@ public abstract class BatteryStats implements Parcelable {
                    "Vibrator");
            uidActivity |= printTimer(pw, sb, u.getForegroundActivityTimer(), rawRealtime, which,
                    prefix, "Foreground activities");
            uidActivity |= printTimer(pw, sb, u.getForegroundServiceTimer(), rawRealtime, which,
                    prefix, "Foreground services");

            long totalStateTime = 0;
            for (int ips=0; ips<Uid.NUM_PROCESS_STATE; ips++) {
+81 −13
Original line number Diff line number Diff line
@@ -119,7 +119,7 @@ public class BatteryStatsImpl extends BatteryStats {
    private static final int MAGIC = 0xBA757475; // 'BATSTATS'

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

    // Maximum number of items we will record in the history.
    private static final int MAX_HISTORY_ITEMS;
@@ -5637,6 +5637,7 @@ public class BatteryStatsImpl extends BatteryStats {
        StopwatchTimer mFlashlightTurnedOnTimer;
        StopwatchTimer mCameraTurnedOnTimer;
        StopwatchTimer mForegroundActivityTimer;
        StopwatchTimer mForegroundServiceTimer;
        /** Total time spent by the uid holding any partial wakelocks. */
        DualTimer mAggregatedPartialWakelockTimer;
        DualTimer mBluetoothScanTimer;
@@ -5647,6 +5648,8 @@ public class BatteryStatsImpl extends BatteryStats {
        int mProcessState = ActivityManager.PROCESS_STATE_NONEXISTENT;
        StopwatchTimer[] mProcessStateTimer;

        boolean mInForegroundService = false;

        BatchTimer mVibratorOnTimer;

        Counter[] mUserActivityCounters;
@@ -6119,6 +6122,14 @@ public class BatteryStatsImpl extends BatteryStats {
            return mForegroundActivityTimer;
        }

        public StopwatchTimer createForegroundServiceTimerLocked() {
            if (mForegroundServiceTimer == null) {
                mForegroundServiceTimer = new StopwatchTimer(mBsi.mClocks, Uid.this,
                        FOREGROUND_SERVICE, null, mBsi.mOnBatteryTimeBase);
            }
            return mForegroundServiceTimer;
        }

        public DualTimer createAggregatedPartialWakelockTimerLocked() {
            if (mAggregatedPartialWakelockTimer == null) {
                mAggregatedPartialWakelockTimer = new DualTimer(mBsi.mClocks, this,
@@ -6207,6 +6218,16 @@ public class BatteryStatsImpl extends BatteryStats {
            }
        }

        public void noteForegroundServiceResumedLocked(long elapsedRealtimeMs) {
            createForegroundServiceTimerLocked().startRunningLocked(elapsedRealtimeMs);
        }

        public void noteForegroundServicePausedLocked(long elapsedRealtimeMs) {
            if (mForegroundServiceTimer != null) {
                mForegroundServiceTimer.stopRunningLocked(elapsedRealtimeMs);
            }
        }

        public BatchTimer createVibratorOnTimerLocked() {
            if (mVibratorOnTimer == null) {
                mVibratorOnTimer = new BatchTimer(mBsi.mClocks, Uid.this, VIBRATOR_ON,
@@ -6334,6 +6355,11 @@ public class BatteryStatsImpl extends BatteryStats {
            return mForegroundActivityTimer;
        }

        @Override
        public Timer getForegroundServiceTimer() {
            return mForegroundServiceTimer;
        }

        @Override
        public Timer getBluetoothScanTimer() {
            return mBluetoothScanTimer;
@@ -6618,6 +6644,7 @@ public class BatteryStatsImpl extends BatteryStats {
            active |= !resetTimerIfNotNull(mFlashlightTurnedOnTimer, false);
            active |= !resetTimerIfNotNull(mCameraTurnedOnTimer, false);
            active |= !resetTimerIfNotNull(mForegroundActivityTimer, false);
            active |= !resetTimerIfNotNull(mForegroundServiceTimer, false);
            active |= !resetTimerIfNotNull(mAggregatedPartialWakelockTimer, false);
            active |= !resetTimerIfNotNull(mBluetoothScanTimer, false);
            active |= !resetTimerIfNotNull(mBluetoothUnoptimizedScanTimer, false);
@@ -6817,6 +6844,10 @@ public class BatteryStatsImpl extends BatteryStats {
                    mForegroundActivityTimer.detach();
                    mForegroundActivityTimer = null;
                }
                if (mForegroundServiceTimer != null) {
                    mForegroundServiceTimer.detach();
                    mForegroundServiceTimer = null;
                }
                if (mAggregatedPartialWakelockTimer != null) {
                    mAggregatedPartialWakelockTimer.detach();
                    mAggregatedPartialWakelockTimer = null;
@@ -7026,6 +7057,12 @@ public class BatteryStatsImpl extends BatteryStats {
            } else {
                out.writeInt(0);
            }
            if (mForegroundServiceTimer != null) {
                out.writeInt(1);
                mForegroundServiceTimer.writeToParcel(out, elapsedRealtimeUs);
            } else {
                out.writeInt(0);
            }
            if (mAggregatedPartialWakelockTimer != null) {
                out.writeInt(1);
                mAggregatedPartialWakelockTimer.writeToParcel(out, elapsedRealtimeUs);
@@ -7304,6 +7341,12 @@ public class BatteryStatsImpl extends BatteryStats {
            } else {
                mForegroundActivityTimer = null;
            }
            if (in.readInt() != 0) {
                mForegroundServiceTimer = new StopwatchTimer(mBsi.mClocks, Uid.this,
                        FOREGROUND_SERVICE, null, mBsi.mOnBatteryTimeBase, in);
            } else {
                mForegroundServiceTimer = null;
            }
            if (in.readInt() != 0) {
                mAggregatedPartialWakelockTimer = new DualTimer(mBsi.mClocks, this,
                        AGGREGATED_WAKE_TYPE_PARTIAL, null,
@@ -8350,6 +8393,9 @@ public class BatteryStatsImpl extends BatteryStats {

        public void updateUidProcessStateLocked(int procState) {
            int uidRunningState;
            // Make special note of Foreground Services
            final boolean userAwareService =
                    (procState == ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
            if (procState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
                uidRunningState = ActivityManager.PROCESS_STATE_NONEXISTENT;
            } else if (procState == ActivityManager.PROCESS_STATE_TOP) {
@@ -8368,9 +8414,12 @@ public class BatteryStatsImpl extends BatteryStats {
                uidRunningState = PROCESS_STATE_CACHED;
            }

            if (mProcessState == uidRunningState) return;
            if (mProcessState == uidRunningState && userAwareService == mInForegroundService) {
                return;
            }

            final long elapsedRealtimeMs = mBsi.mClocks.elapsedRealtime();
            if (mProcessState != uidRunningState) {
                final long uptimeMs = mBsi.mClocks.uptimeMillis();

                if (mProcessState != ActivityManager.PROCESS_STATE_NONEXISTENT) {
@@ -8388,6 +8437,16 @@ public class BatteryStatsImpl extends BatteryStats {
                updateOnBatteryScreenOffBgTimeBase(uptimeMs * 1000, elapsedRealtimeMs * 1000);
            }

            if (userAwareService != mInForegroundService) {
                if (userAwareService) {
                    noteForegroundServiceResumedLocked(elapsedRealtimeMs);
                } else {
                    noteForegroundServicePausedLocked(elapsedRealtimeMs);
                }
                mInForegroundService = userAwareService;
            }
        }

        /** 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
@@ -11609,6 +11668,9 @@ public class BatteryStatsImpl extends BatteryStats {
            if (in.readInt() != 0) {
                u.createForegroundActivityTimerLocked().readSummaryFromParcelLocked(in);
            }
            if (in.readInt() != 0) {
                u.createForegroundServiceTimerLocked().readSummaryFromParcelLocked(in);
            }
            if (in.readInt() != 0) {
                u.createAggregatedPartialWakelockTimerLocked().readSummaryFromParcelLocked(in);
            }
@@ -12021,6 +12083,12 @@ public class BatteryStatsImpl extends BatteryStats {
            } else {
                out.writeInt(0);
            }
            if (u.mForegroundServiceTimer != null) {
                out.writeInt(1);
                u.mForegroundServiceTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
            } else {
                out.writeInt(0);
            }
            if (u.mAggregatedPartialWakelockTimer != null) {
                out.writeInt(1);
                u.mAggregatedPartialWakelockTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
+105 −0
Original line number Diff line number Diff line
@@ -25,8 +25,22 @@ import android.support.test.filters.SmallTest;

import junit.framework.TestCase;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Test various BatteryStatsImpl noteStart methods.
 *
 * Build/Install/Run: bit FrameworksCoreTests:com.android.internal.os.BatteryStatsNoteTest
 *
 * Alternatively,
 * 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.BatteryStatsNoteTest -w \
 *      com.android.frameworks.coretests/android.support.test.runner.AndroidJUnitRunner
 */
public class BatteryStatsNoteTest extends TestCase{
    private static final int UID = 10500;
@@ -86,4 +100,95 @@ public class BatteryStatsNoteTest extends TestCase{
        assertEquals(220_000, actualTime);
        assertEquals(120_000, bgTime);
    }


    /** Test BatteryStatsImpl.noteUidProcessStateLocked. */
    @SmallTest
    public void testNoteUidProcessStateLocked() throws Exception {
        final MockClocks clocks = new MockClocks();
        MockBatteryStatsImpl bi = new MockBatteryStatsImpl(clocks);

        // map of ActivityManager process states and how long to simulate run time in each state
        Map<Integer, Integer> stateRuntimeMap = new HashMap<Integer, Integer>();
        stateRuntimeMap.put(ActivityManager.PROCESS_STATE_TOP, 1111);
        stateRuntimeMap.put(ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE, 1234);
        stateRuntimeMap.put(ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE, 2468);
        stateRuntimeMap.put(ActivityManager.PROCESS_STATE_TOP_SLEEPING, 7531);
        stateRuntimeMap.put(ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND, 4455);
        stateRuntimeMap.put(ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND, 1337);
        stateRuntimeMap.put(ActivityManager.PROCESS_STATE_BACKUP, 90210);
        stateRuntimeMap.put(ActivityManager.PROCESS_STATE_HEAVY_WEIGHT, 911);
        stateRuntimeMap.put(ActivityManager.PROCESS_STATE_SERVICE, 404);
        stateRuntimeMap.put(ActivityManager.PROCESS_STATE_RECEIVER, 31459);
        stateRuntimeMap.put(ActivityManager.PROCESS_STATE_HOME, 1123);
        stateRuntimeMap.put(ActivityManager.PROCESS_STATE_LAST_ACTIVITY, 5813);
        stateRuntimeMap.put(ActivityManager.PROCESS_STATE_CACHED_ACTIVITY, 867);
        stateRuntimeMap.put(ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT, 5309);
        stateRuntimeMap.put(ActivityManager.PROCESS_STATE_CACHED_EMPTY, 42);

        bi.updateTimeBasesLocked(true, false, 0, 0);

        for (Map.Entry<Integer, Integer> entry : stateRuntimeMap.entrySet()) {
            bi.noteUidProcessStateLocked(UID, entry.getKey());
            clocks.realtime += entry.getValue();
            clocks.uptime = clocks.realtime;
        }

        long actualRunTimeUs;
        long expectedRunTimeMs;
        long elapsedTimeUs = clocks.realtime * 1000;
        BatteryStats.Uid uid = bi.getUidStats().get(UID);

        // compare runtime of process states to the Uid process states they map to
        actualRunTimeUs = uid.getProcessStateTime(BatteryStats.Uid.PROCESS_STATE_TOP, elapsedTimeUs,
                STATS_SINCE_CHARGED);
        expectedRunTimeMs = stateRuntimeMap.get(ActivityManager.PROCESS_STATE_TOP);
        assertEquals(expectedRunTimeMs * 1000, actualRunTimeUs);


        actualRunTimeUs = uid.getProcessStateTime(BatteryStats.Uid.PROCESS_STATE_FOREGROUND_SERVICE,
                elapsedTimeUs, STATS_SINCE_CHARGED);
        expectedRunTimeMs = stateRuntimeMap.get(
                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE)
                + stateRuntimeMap.get(ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
        assertEquals(expectedRunTimeMs * 1000, actualRunTimeUs);


        actualRunTimeUs = uid.getProcessStateTime(BatteryStats.Uid.PROCESS_STATE_TOP_SLEEPING,
                elapsedTimeUs, STATS_SINCE_CHARGED);
        expectedRunTimeMs = stateRuntimeMap.get(ActivityManager.PROCESS_STATE_TOP_SLEEPING);
        assertEquals(expectedRunTimeMs * 1000, actualRunTimeUs);


        actualRunTimeUs = uid.getProcessStateTime(BatteryStats.Uid.PROCESS_STATE_FOREGROUND,
                elapsedTimeUs, STATS_SINCE_CHARGED);
        expectedRunTimeMs = stateRuntimeMap.get(ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND);
        assertEquals(expectedRunTimeMs * 1000, actualRunTimeUs);


        actualRunTimeUs = uid.getProcessStateTime(BatteryStats.Uid.PROCESS_STATE_BACKGROUND,
                elapsedTimeUs, STATS_SINCE_CHARGED);
        expectedRunTimeMs = stateRuntimeMap.get(ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND)
                + stateRuntimeMap.get(ActivityManager.PROCESS_STATE_BACKUP)
                + stateRuntimeMap.get(ActivityManager.PROCESS_STATE_HEAVY_WEIGHT)
                + stateRuntimeMap.get(ActivityManager.PROCESS_STATE_SERVICE)
                + stateRuntimeMap.get(ActivityManager.PROCESS_STATE_RECEIVER);
        assertEquals(expectedRunTimeMs * 1000, actualRunTimeUs);


        actualRunTimeUs = uid.getProcessStateTime(BatteryStats.Uid.PROCESS_STATE_CACHED,
                elapsedTimeUs, STATS_SINCE_CHARGED);
        expectedRunTimeMs = stateRuntimeMap.get(ActivityManager.PROCESS_STATE_HOME)
                + stateRuntimeMap.get(ActivityManager.PROCESS_STATE_LAST_ACTIVITY)
                + stateRuntimeMap.get(ActivityManager.PROCESS_STATE_CACHED_ACTIVITY)
                + stateRuntimeMap.get(ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT)
                + stateRuntimeMap.get(ActivityManager.PROCESS_STATE_CACHED_EMPTY);
        assertEquals(expectedRunTimeMs * 1000, actualRunTimeUs);

        // Special check for foreground service timer
        actualRunTimeUs = uid.getForegroundServiceTimer().getTotalTimeLocked(elapsedTimeUs,
                STATS_SINCE_CHARGED);
        expectedRunTimeMs = stateRuntimeMap.get(ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
        assertEquals(expectedRunTimeMs * 1000, actualRunTimeUs);
    }
}