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

Commit b7b838fc authored by Android Build Merger (Role)'s avatar Android Build Merger (Role) Committed by Android (Google) Code Review
Browse files

Merge changes from topic 'am-a47d2b51b72a4b9da02be5683a2ecaae'

* changes:
  Merge "Track Partial wakelock time in background" into oc-dev am: 1dfd194f am: b5ba4b1f
  Merge "Fix batterystat Counter misreporting when charging" into oc-dev am: 413b1352 am: 95d00a9a
  Merge "Batterystats track background bad ble scan time" into oc-dev am: fe06de1f am: 41e3f147
parents 76843898 619f506c
Loading
Loading
Loading
Loading
+118 −20
Original line number Diff line number Diff line
@@ -161,6 +161,11 @@ public abstract class BatteryStats implements Parcelable {
     */
    public static final int AGGREGATED_WAKE_TYPE_PARTIAL = 20;

    /**
     * A constant indicating a bluetooth scan timer for unoptimized scans.
     */
    public static final int BLUETOOTH_UNOPTIMIZED_SCAN_ON = 21;

    /**
     * Include all of the data in the stats, including previously saved data.
     */
@@ -191,8 +196,12 @@ public abstract class BatteryStats implements Parcelable {
     * 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.
     *   - BLE scan result count
     *   - CPU frequency time per uid
     * New in version 22:
     *   - BLE scan result background count, BLE unoptimized scan time
     */
    static final String CHECKIN_VERSION = "21";
    static final String CHECKIN_VERSION = "22";

    /**
     * Old version, we hit 9 and ran out of room, need to remove.
@@ -219,6 +228,7 @@ public abstract class BatteryStats implements Parcelable {
    // BATTERY_STATS_CHECKIN_VERSION, uid, which, "wl", name,
    // full        totalTime, 'f',  count, current duration, max duration, total duration,
    // partial     totalTime, 'p',  count, current duration, max duration, total duration,
    // bg partial  totalTime, 'bp', count, current duration, max duration, total duration,
    // 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";
@@ -565,7 +575,10 @@ public abstract class BatteryStats implements Parcelable {
        public abstract Timer getForegroundActivityTimer();
        public abstract Timer getBluetoothScanTimer();
        public abstract Timer getBluetoothScanBackgroundTimer();
        public abstract Timer getBluetoothUnoptimizedScanTimer();
        public abstract Timer getBluetoothUnoptimizedScanBackgroundTimer();
        public abstract Counter getBluetoothScanResultCounter();
        public abstract Counter getBluetoothScanResultBgCounter();

        public abstract long[] getCpuFreqTimes(int which);
        public abstract long[] getScreenOffCpuFreqTimes(int which);
@@ -3429,10 +3442,29 @@ public abstract class BatteryStats implements Parcelable {
                    final long actualTime = bleTimer.getTotalDurationMsLocked(rawRealtimeMs);
                    final long actualTimeBg = bleTimerBg != null ?
                            bleTimerBg.getTotalDurationMsLocked(rawRealtimeMs) : 0;
                    // Result counters
                    final int resultCount = u.getBluetoothScanResultCounter() != null ?
                            u.getBluetoothScanResultCounter().getCountLocked(which) : 0;
                    final int resultCountBg = u.getBluetoothScanResultBgCounter() != null ?
                            u.getBluetoothScanResultBgCounter().getCountLocked(which) : 0;
                    // Unoptimized scan timer. Unpooled and since reset (regardless of 'which').
                    final Timer unoptimizedScanTimer = u.getBluetoothUnoptimizedScanTimer();
                    final long unoptimizedScanTotalTime = unoptimizedScanTimer != null ?
                            unoptimizedScanTimer.getTotalDurationMsLocked(rawRealtimeMs) : 0;
                    final long unoptimizedScanMaxTime = unoptimizedScanTimer != null ?
                            unoptimizedScanTimer.getMaxDurationMsLocked(rawRealtimeMs) : 0;
                    // Unoptimized bg scan timer. Unpooled and since reset (regardless of 'which').
                    final Timer unoptimizedScanTimerBg =
                            u.getBluetoothUnoptimizedScanBackgroundTimer();
                    final long unoptimizedScanTotalTimeBg = unoptimizedScanTimerBg != null ?
                            unoptimizedScanTimerBg.getTotalDurationMsLocked(rawRealtimeMs) : 0;
                    final long unoptimizedScanMaxTimeBg = unoptimizedScanTimerBg != null ?
                            unoptimizedScanTimerBg.getMaxDurationMsLocked(rawRealtimeMs) : 0;

                    dumpLine(pw, uid, category, BLUETOOTH_MISC_DATA, totalTime, count,
                            countBg, actualTime, actualTimeBg, resultCount);
                            countBg, actualTime, actualTimeBg, resultCount, resultCountBg,
                            unoptimizedScanTotalTime, unoptimizedScanTotalTimeBg,
                            unoptimizedScanMaxTime, unoptimizedScanMaxTimeBg);
                }
            }

@@ -3469,8 +3501,11 @@ public abstract class BatteryStats implements Parcelable {
                sb.setLength(0);
                linePrefix = printWakeLockCheckin(sb, wl.getWakeTime(WAKE_TYPE_FULL),
                        rawRealtime, "f", which, linePrefix);
                linePrefix = printWakeLockCheckin(sb, wl.getWakeTime(WAKE_TYPE_PARTIAL),
                final Timer pTimer = wl.getWakeTime(WAKE_TYPE_PARTIAL);
                linePrefix = printWakeLockCheckin(sb, pTimer,
                        rawRealtime, "p", which, linePrefix);
                linePrefix = printWakeLockCheckin(sb, pTimer != null ? pTimer.getSubTimer() : null,
                        rawRealtime, "bp", which, linePrefix);
                linePrefix = printWakeLockCheckin(sb, wl.getWakeTime(WAKE_TYPE_WINDOW),
                        rawRealtime, "w", which, linePrefix);

@@ -4625,34 +4660,94 @@ public abstract class BatteryStats implements Parcelable {
                    final long actualTimeMs = bleTimer.getTotalDurationMsLocked(rawRealtimeMs);
                    final long actualTimeMsBg = bleTimerBg != null ?
                            bleTimerBg.getTotalDurationMsLocked(rawRealtimeMs) : 0;
                    // Result counters
                    final int resultCount = u.getBluetoothScanResultCounter() != null ?
                            u.getBluetoothScanResultCounter().getCountLocked(which) : 0;
                    final int resultCountBg = u.getBluetoothScanResultBgCounter() != null ?
                            u.getBluetoothScanResultBgCounter().getCountLocked(which) : 0;
                    // Unoptimized scan timer. Unpooled and since reset (regardless of 'which').
                    final Timer unoptimizedScanTimer = u.getBluetoothUnoptimizedScanTimer();
                    final long unoptimizedScanTotalTime = unoptimizedScanTimer != null ?
                            unoptimizedScanTimer.getTotalDurationMsLocked(rawRealtimeMs) : 0;
                    final long unoptimizedScanMaxTime = unoptimizedScanTimer != null ?
                            unoptimizedScanTimer.getMaxDurationMsLocked(rawRealtimeMs) : 0;
                    // Unoptimized bg scan timer. Unpooled and since reset (regardless of 'which').
                    final Timer unoptimizedScanTimerBg =
                            u.getBluetoothUnoptimizedScanBackgroundTimer();
                    final long unoptimizedScanTotalTimeBg = unoptimizedScanTimerBg != null ?
                            unoptimizedScanTimerBg.getTotalDurationMsLocked(rawRealtimeMs) : 0;
                    final long unoptimizedScanMaxTimeBg = unoptimizedScanTimerBg != null ?
                            unoptimizedScanTimerBg.getMaxDurationMsLocked(rawRealtimeMs) : 0;

                    sb.setLength(0);
                    sb.append(prefix);
                    sb.append("    ");
                    sb.append("Bluetooth Scan");
                    sb.append(": ");
                    if (actualTimeMs != totalTimeMs) {
                        sb.append(prefix);
                        sb.append("    Bluetooth Scan (total blamed realtime): ");
                        formatTimeMs(sb, totalTimeMs);
                        sb.append("blamed realtime, ");
                        sb.append(" (");
                        sb.append(count);
                        sb.append(" times)");
                        if (bleTimer.isRunningLocked()) {
                            sb.append(" (currently running)");
                        }
                    formatTimeMs(sb, actualTimeMs); // since reset, regardless of 'which'
                    sb.append("realtime (");
                        sb.append("\n");
                    }

                    sb.append(prefix);
                    sb.append("    Bluetooth Scan (total actual realtime): ");
                    formatTimeMs(sb, actualTimeMs); // since reset, ignores 'which'
                    sb.append(" (");
                    sb.append(count);
                    sb.append(" times)");
                    if (bleTimer.isRunningLocked()) {
                            sb.append(" (running)");
                            sb.append(" (currently running)");
                    }
                    if (actualTimeMsBg != 0 || countBg > 0) {
                        sb.append(", ");
                        formatTimeMs(sb, actualTimeMsBg); // since reset, regardless of 'which'
                        sb.append("background (");
                    sb.append("\n");
                    if (actualTimeMsBg > 0 || countBg > 0) {
                        sb.append(prefix);
                        sb.append("    Bluetooth Scan (background realtime): ");
                        formatTimeMs(sb, actualTimeMsBg); // since reset, ignores 'which'
                        sb.append(" (");
                        sb.append(countBg);
                        sb.append(" times)");
                        if (bleTimerBg != null && bleTimerBg.isRunningLocked()) {
                            sb.append(" (currently running in background)");
                        }
                        sb.append("\n");
                    }
                    sb.append("; Results count ");

                    sb.append(prefix);
                    sb.append("    Bluetooth Scan Results: ");
                    sb.append(resultCount);
                    sb.append(" (");
                    sb.append(resultCountBg);
                    sb.append(" in background)");

                    if (unoptimizedScanTotalTime > 0 || unoptimizedScanTotalTimeBg > 0) {
                        sb.append("\n");
                        sb.append(prefix);
                        sb.append("    Unoptimized Bluetooth Scan (realtime): ");
                        formatTimeMs(sb, unoptimizedScanTotalTime); // since reset, ignores 'which'
                        sb.append(" (max ");
                        formatTimeMs(sb, unoptimizedScanMaxTime); // since reset, ignores 'which'
                        sb.append(")");
                        if (unoptimizedScanTimer != null
                                && unoptimizedScanTimer.isRunningLocked()) {
                            sb.append(" (currently running unoptimized)");
                        }
                        if (unoptimizedScanTimerBg != null && unoptimizedScanTotalTimeBg > 0) {
                            sb.append("\n");
                            sb.append(prefix);
                            sb.append("    Unoptimized Bluetooth Scan (background realtime): ");
                            formatTimeMs(sb, unoptimizedScanTotalTimeBg); // since reset
                            sb.append(" (max ");
                            formatTimeMs(sb, unoptimizedScanMaxTimeBg); // since reset
                            sb.append(")");
                            if (unoptimizedScanTimerBg.isRunningLocked()) {
                                sb.append(" (currently running unoptimized in background)");
                            }
                        }
                    }
                    pw.println(sb.toString());
                    uidActivity = true;
                }
@@ -4696,8 +4791,11 @@ public abstract class BatteryStats implements Parcelable {
                sb.append(wakelocks.keyAt(iw));
                linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_FULL), rawRealtime,
                        "full", which, linePrefix);
                linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_PARTIAL), rawRealtime,
                final Timer pTimer = wl.getWakeTime(WAKE_TYPE_PARTIAL);
                linePrefix = printWakeLock(sb, pTimer, rawRealtime,
                        "partial", which, linePrefix);
                linePrefix = printWakeLock(sb, pTimer != null ? pTimer.getSubTimer() : null,
                        rawRealtime, "background partial", which, linePrefix);
                linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_WINDOW), rawRealtime,
                        "window", which, linePrefix);
                linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_DRAW), rawRealtime,
+1 −1
Original line number Diff line number Diff line
@@ -129,7 +129,7 @@ interface IBatteryStats {
    long getAwakeTimeBattery();
    long getAwakeTimePlugged();

    void noteBleScanStarted(in WorkSource ws);
    void noteBleScanStarted(in WorkSource ws, boolean isUnoptimized);
    void noteBleScanStopped(in WorkSource ws);
    void noteResetBleScan();
    void noteBleScanResults(in WorkSource ws, int numNewResults);
+205 −87

File changed.

Preview size limit exceeded, changes collapsed.

+31 −8
Original line number Diff line number Diff line
@@ -205,9 +205,9 @@ public class BatteryStatsBackgroundStatsTest extends TestCase {
        // App in foreground
        bi.noteUidProcessStateLocked(UID, ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND);

        // Start timer
        // Start timer (optimized)
        curr = 1000 * (clocks.realtime = clocks.uptime = 202);
        bi.noteBluetoothScanStartedFromSourceLocked(ws);
        bi.noteBluetoothScanStartedFromSourceLocked(ws, false);

        // Move to background
        curr = 1000 * (clocks.realtime = clocks.uptime = 254);
@@ -221,21 +221,44 @@ public class BatteryStatsBackgroundStatsTest extends TestCase {
        curr = 1000 * (clocks.realtime = clocks.uptime = 409);
        bi.noteBluetoothScanStoppedFromSourceLocked(ws);

        // Start timer (unoptimized)
        curr = 1000 * (clocks.realtime = clocks.uptime = 1000);
        bi.noteBluetoothScanStartedFromSourceLocked(ws, true);

        // On battery
        curr = 1000 * (clocks.realtime = clocks.uptime = 2001);
        bi.updateTimeBasesLocked(true, false, curr, curr); // on battery

        // Move to foreground
        curr = 1000 * (clocks.realtime = clocks.uptime = 3004);
        bi.noteUidProcessStateLocked(UID, ActivityManager.PROCESS_STATE_TOP);

        // Stop timer
        curr = 1000 * (clocks.realtime = clocks.uptime = 4008);
        bi.noteBluetoothScanStoppedFromSourceLocked(ws);

        // Test
        curr = 1000 * (clocks.realtime = clocks.uptime = 657);
        curr = 1000 * (clocks.realtime = clocks.uptime = 5000);
        BatteryStats.Timer timer = bi.getUidStats().get(UID).getBluetoothScanTimer();
        BatteryStats.Timer bgTimer = bi.getUidStats().get(UID).getBluetoothScanBackgroundTimer();
        BatteryStats.Timer badTimer = bi.getUidStats().get(UID).getBluetoothUnoptimizedScanTimer();
        BatteryStats.Timer badBgTimer = bi.getUidStats().get(UID)
                .getBluetoothUnoptimizedScanBackgroundTimer();

        long time = timer.getTotalTimeLocked(curr, STATS_SINCE_CHARGED);
        int count = timer.getCountLocked(STATS_SINCE_CHARGED);
        int bgCount = bgTimer.getCountLocked(STATS_SINCE_CHARGED);
        long actualTime = timer.getTotalDurationMsLocked(clocks.realtime) * 1000;
        long bgTime = bgTimer.getTotalDurationMsLocked(clocks.realtime) * 1000;
        assertEquals((305 - 202) * 1000, time);
        assertEquals(1, count);
        assertEquals(0, bgCount);
        assertEquals((305 - 202) * 1000, actualTime);
        assertEquals((305 - 254) * 1000, bgTime);
        long badTime = badTimer.getTotalDurationMsLocked(clocks.realtime) * 1000;
        long badBgTime = badBgTimer.getTotalDurationMsLocked(clocks.realtime) * 1000;
        assertEquals((305 - 202 + 4008 - 2001) * 1000, time);
        assertEquals(1, count); // second scan starts off-battery
        assertEquals(0, bgCount); // first scan starts in fg, second starts off-battery
        assertEquals((305 - 202 + 4008 - 2001) * 1000, actualTime);
        assertEquals((305 - 254 + 3004 - 2001) * 1000, bgTime);
        assertEquals((4008 - 2001) * 1000, badTime);
        assertEquals((3004 - 2001) * 1000, badBgTime);
    }

    @SmallTest
+148 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package com.android.internal.os;

import android.os.BatteryStats;
import android.os.Parcel;
import android.support.test.filters.SmallTest;

import junit.framework.TestCase;

/**
 * Test BatteryStatsImpl.Counter.
 */
public class BatteryStatsCounterTest extends TestCase {

    @SmallTest
    public void testCounter() throws Exception {
        final MockClocks clocks = new MockClocks(); // holds realtime and uptime in ms
        final BatteryStatsImpl.TimeBase timeBase = new BatteryStatsImpl.TimeBase();
        timeBase.init(clocks.uptimeMillis(), clocks.elapsedRealtime());

        final BatteryStatsImpl.Counter counter = new BatteryStatsImpl.Counter(timeBase);

        // timeBase off (i.e. plugged in)
        timeBase.setRunning(false, 1, 1);
        counter.stepAtomic();
        counter.stepAtomic();
        counter.stepAtomic();
        counter.stepAtomic();
        counter.stepAtomic();
        assertEquals(0, counter.getCountLocked(BatteryStats.STATS_SINCE_CHARGED));
        assertEquals(0, counter.getCountLocked(BatteryStats.STATS_CURRENT));
        assertEquals(0, counter.getCountLocked(BatteryStats.STATS_SINCE_UNPLUGGED));

        // timeBase on (i.e. unplugged)
        timeBase.setRunning(true, 2, 2);
        counter.stepAtomic();
        counter.stepAtomic();
        counter.stepAtomic();
        counter.stepAtomic();
        assertEquals(4, counter.getCountLocked(BatteryStats.STATS_SINCE_CHARGED));
        assertEquals(4, counter.getCountLocked(BatteryStats.STATS_CURRENT));
        assertEquals(4, counter.getCountLocked(BatteryStats.STATS_SINCE_UNPLUGGED));

        // timeBase off (i.e. plugged in)
        timeBase.setRunning(false, 3, 3);
        counter.stepAtomic();
        counter.stepAtomic();
        counter.stepAtomic();
        assertEquals(4, counter.getCountLocked(BatteryStats.STATS_SINCE_CHARGED));
        assertEquals(4, counter.getCountLocked(BatteryStats.STATS_CURRENT));
        assertEquals(4, counter.getCountLocked(BatteryStats.STATS_SINCE_UNPLUGGED));

        // timeBase on (i.e. unplugged)
        timeBase.setRunning(true, 4, 4);
        counter.stepAtomic();
        counter.stepAtomic();
        assertEquals(6, counter.getCountLocked(BatteryStats.STATS_SINCE_CHARGED));
        assertEquals(6, counter.getCountLocked(BatteryStats.STATS_CURRENT));
        assertEquals(2, counter.getCountLocked(BatteryStats.STATS_SINCE_UNPLUGGED));
    }


    @SmallTest
    public void testParceling() throws Exception {
        final MockClocks clocks = new MockClocks(); // holds realtime and uptime in ms
        final BatteryStatsImpl.TimeBase timeBase = new BatteryStatsImpl.TimeBase();
        timeBase.init(clocks.uptimeMillis(), clocks.elapsedRealtime());

        final BatteryStatsImpl.Counter origCounter = new BatteryStatsImpl.Counter(timeBase);

        // timeBase on (i.e. unplugged)
        timeBase.setRunning(true, 1, 1);
        origCounter.stepAtomic(); origCounter.stepAtomic(); origCounter.stepAtomic(); // three times
        assertEquals(3, origCounter.getCountLocked(BatteryStats.STATS_SINCE_CHARGED));
        assertEquals(3, origCounter.getCountLocked(BatteryStats.STATS_CURRENT));
        assertEquals(3, origCounter.getCountLocked(BatteryStats.STATS_SINCE_UNPLUGGED));

        // Test summary parcelling (from origCounter)
        final Parcel summaryParcel = Parcel.obtain();
        origCounter.writeSummaryFromParcelLocked(summaryParcel);
        summaryParcel.setDataPosition(0);
        final BatteryStatsImpl.Counter summaryCounter = new BatteryStatsImpl.Counter(timeBase);
        summaryCounter.stepAtomic(); // occurs before reading the summary, so must not count later
        summaryCounter.readSummaryFromParcelLocked(summaryParcel);

        // timeBase still on (i.e. unplugged)
        summaryCounter.stepAtomic(); // once
        assertEquals(4, summaryCounter.getCountLocked(BatteryStats.STATS_SINCE_CHARGED));
        assertEquals(1, summaryCounter.getCountLocked(BatteryStats.STATS_CURRENT));
        assertEquals(1, summaryCounter.getCountLocked(BatteryStats.STATS_SINCE_UNPLUGGED));

        // timeBase off (i.e. plugged in)
        timeBase.setRunning(false, 3, 3);
        summaryCounter.stepAtomic(); summaryCounter.stepAtomic(); // twice
        assertEquals(4, summaryCounter.getCountLocked(BatteryStats.STATS_SINCE_CHARGED));
        assertEquals(1, summaryCounter.getCountLocked(BatteryStats.STATS_CURRENT));
        assertEquals(1, summaryCounter.getCountLocked(BatteryStats.STATS_SINCE_UNPLUGGED));

        // timeBase on (i.e. unplugged)
        timeBase.setRunning(true, 4, 4);
        summaryCounter.stepAtomic(); summaryCounter.stepAtomic(); // twice
        assertEquals(6, summaryCounter.getCountLocked(BatteryStats.STATS_SINCE_CHARGED));
        assertEquals(3, summaryCounter.getCountLocked(BatteryStats.STATS_CURRENT));
        assertEquals(2, summaryCounter.getCountLocked(BatteryStats.STATS_SINCE_UNPLUGGED));


        // Test full parcelling (from summaryCounter)
        final Parcel fullParcel = Parcel.obtain();
        summaryCounter.writeToParcel(fullParcel);
        fullParcel.setDataPosition(0);
        final BatteryStatsImpl.Counter fullParcelCounter
                = new BatteryStatsImpl.Counter(timeBase, fullParcel);

        // timeBase still on (i.e. unplugged)
        fullParcelCounter.stepAtomic(); // once
        assertEquals(7, fullParcelCounter.getCountLocked(BatteryStats.STATS_SINCE_CHARGED));
        assertEquals(4, fullParcelCounter.getCountLocked(BatteryStats.STATS_CURRENT));
        assertEquals(3, fullParcelCounter.getCountLocked(BatteryStats.STATS_SINCE_UNPLUGGED));

        // timeBase off (i.e. plugged in)
        timeBase.setRunning(false, 5, 5);
        fullParcelCounter.stepAtomic(); fullParcelCounter.stepAtomic(); // twice
        assertEquals(7, fullParcelCounter.getCountLocked(BatteryStats.STATS_SINCE_CHARGED));
        assertEquals(4, fullParcelCounter.getCountLocked(BatteryStats.STATS_CURRENT));
        assertEquals(3, fullParcelCounter.getCountLocked(BatteryStats.STATS_SINCE_UNPLUGGED));

        // timeBase on (i.e. unplugged)
        timeBase.setRunning(true, 6, 6);
        fullParcelCounter.stepAtomic(); fullParcelCounter.stepAtomic(); // twice
        assertEquals(9, fullParcelCounter.getCountLocked(BatteryStats.STATS_SINCE_CHARGED));
        assertEquals(6, fullParcelCounter.getCountLocked(BatteryStats.STATS_CURRENT));
        assertEquals(2, fullParcelCounter.getCountLocked(BatteryStats.STATS_SINCE_UNPLUGGED));
    }
}
Loading