Loading core/java/android/os/BatteryStats.java +118 −20 Original line number Diff line number Diff line Loading @@ -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. */ Loading Loading @@ -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. Loading @@ -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"; Loading Loading @@ -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); Loading Loading @@ -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); } } Loading Loading @@ -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); Loading Loading @@ -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; } Loading Loading @@ -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, Loading core/java/com/android/internal/app/IBatteryStats.aidl +1 −1 Original line number Diff line number Diff line Loading @@ -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); Loading core/java/com/android/internal/os/BatteryStatsImpl.java +205 −87 File changed.Preview size limit exceeded, changes collapsed. Show changes core/tests/coretests/src/com/android/internal/os/BatteryStatsBackgroundStatsTest.java +31 −8 Original line number Diff line number Diff line Loading @@ -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); Loading @@ -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 Loading core/tests/coretests/src/com/android/internal/os/BatteryStatsCounterTest.java 0 → 100644 +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
core/java/android/os/BatteryStats.java +118 −20 Original line number Diff line number Diff line Loading @@ -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. */ Loading Loading @@ -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. Loading @@ -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"; Loading Loading @@ -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); Loading Loading @@ -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); } } Loading Loading @@ -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); Loading Loading @@ -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; } Loading Loading @@ -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, Loading
core/java/com/android/internal/app/IBatteryStats.aidl +1 −1 Original line number Diff line number Diff line Loading @@ -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); Loading
core/java/com/android/internal/os/BatteryStatsImpl.java +205 −87 File changed.Preview size limit exceeded, changes collapsed. Show changes
core/tests/coretests/src/com/android/internal/os/BatteryStatsBackgroundStatsTest.java +31 −8 Original line number Diff line number Diff line Loading @@ -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); Loading @@ -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 Loading
core/tests/coretests/src/com/android/internal/os/BatteryStatsCounterTest.java 0 → 100644 +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)); } }