diff options
12 files changed, 247 insertions, 84 deletions
diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java index c4d12d4336c6..996a288ef59d 100644 --- a/core/java/android/os/BatteryStats.java +++ b/core/java/android/os/BatteryStats.java @@ -2066,9 +2066,11 @@ public abstract class BatteryStats { public static final int EVENT_LONG_WAKE_LOCK = 0x0014; // Event for reporting change of some device states, triggered by a specific UID public static final int EVENT_STATE_CHANGE = 0x0015; + // Event for reporting change of screen states. + public static final int EVENT_DISPLAY_STATE_CHANGED = 0x0016; // Number of event types. - public static final int EVENT_COUNT = 0x0016; + public static final int EVENT_COUNT = 0x0017; // Mask to extract out only the type part of the event. public static final int EVENT_TYPE_MASK = ~(EVENT_FLAG_START|EVENT_FLAG_FINISH); @@ -3079,13 +3081,14 @@ public abstract class BatteryStats { public static final String[] HISTORY_EVENT_NAMES = new String[] { "null", "proc", "fg", "top", "sync", "wake_lock_in", "job", "user", "userfg", "conn", "active", "pkginst", "pkgunin", "alarm", "stats", "pkginactive", "pkgactive", - "tmpwhitelist", "screenwake", "wakeupap", "longwake", "state" + "tmpwhitelist", "screenwake", "wakeupap", "longwake", "state", + "display_state_changed" }; public static final String[] HISTORY_EVENT_CHECKIN_NAMES = new String[] { "Enl", "Epr", "Efg", "Etp", "Esy", "Ewl", "Ejb", "Eur", "Euf", "Ecn", "Eac", "Epi", "Epu", "Eal", "Est", "Eai", "Eaa", "Etw", - "Esw", "Ewa", "Elw", "Eec", "Esc" + "Esw", "Ewa", "Elw", "Eec", "Esc", "Eds" }; @FunctionalInterface diff --git a/core/java/com/android/internal/app/IBatteryStats.aidl b/core/java/com/android/internal/app/IBatteryStats.aidl index ebcae277c62b..a5e166b95177 100644 --- a/core/java/com/android/internal/app/IBatteryStats.aidl +++ b/core/java/com/android/internal/app/IBatteryStats.aidl @@ -144,9 +144,9 @@ interface IBatteryStats { @EnforcePermission("UPDATE_DEVICE_STATS") void noteGpsSignalQuality(int signalLevel); @EnforcePermission("UPDATE_DEVICE_STATS") - void noteScreenState(int state); + void noteScreenState(int displayId, int state, int reason); @EnforcePermission("UPDATE_DEVICE_STATS") - void noteScreenBrightness(int brightness); + void noteScreenBrightness(int displayId, int brightness); @EnforcePermission("UPDATE_DEVICE_STATS") void noteUserActivity(int uid, int event); @EnforcePermission("UPDATE_DEVICE_STATS") diff --git a/services/core/java/com/android/server/am/BatteryStatsService.java b/services/core/java/com/android/server/am/BatteryStatsService.java index 2416ab68c1af..75e9fadbd917 100644 --- a/services/core/java/com/android/server/am/BatteryStatsService.java +++ b/services/core/java/com/android/server/am/BatteryStatsService.java @@ -1833,7 +1833,7 @@ public final class BatteryStatsService extends IBatteryStats.Stub @Override @EnforcePermission(UPDATE_DEVICE_STATS) - public void noteScreenState(final int state) { + public void noteScreenState(final int displayId, final int state, final int reason) { super.noteScreenState_enforcePermission(); synchronized (mLock) { @@ -1843,7 +1843,8 @@ public final class BatteryStatsService extends IBatteryStats.Stub mHandler.post(() -> { if (DBG) Slog.d(TAG, "begin noteScreenState"); synchronized (mStats) { - mStats.noteScreenStateLocked(0, state, elapsedRealtime, uptime, currentTime); + mStats.noteScreenStateLocked( + displayId, state, reason, elapsedRealtime, uptime, currentTime); } if (DBG) Slog.d(TAG, "end noteScreenState"); }); @@ -1853,7 +1854,7 @@ public final class BatteryStatsService extends IBatteryStats.Stub @Override @EnforcePermission(UPDATE_DEVICE_STATS) - public void noteScreenBrightness(final int brightness) { + public void noteScreenBrightness(final int displayId, final int brightness) { super.noteScreenBrightness_enforcePermission(); synchronized (mLock) { @@ -1861,7 +1862,8 @@ public final class BatteryStatsService extends IBatteryStats.Stub final long uptime = SystemClock.uptimeMillis(); mHandler.post(() -> { synchronized (mStats) { - mStats.noteScreenBrightnessLocked(0, brightness, elapsedRealtime, uptime); + mStats.noteScreenBrightnessLocked( + displayId, brightness, elapsedRealtime, uptime); } }); } diff --git a/services/core/java/com/android/server/display/DisplayPowerController.java b/services/core/java/com/android/server/display/DisplayPowerController.java index c3faec007552..04573f4b7514 100644 --- a/services/core/java/com/android/server/display/DisplayPowerController.java +++ b/services/core/java/com/android/server/display/DisplayPowerController.java @@ -536,7 +536,9 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call mLastBrightnessEvent = new BrightnessEvent(mDisplayId); mTempBrightnessEvent = new BrightnessEvent(mDisplayId); - if (mDisplayId == Display.DEFAULT_DISPLAY) { + if (flags.isBatteryStatsEnabledForAllDisplays()) { + mBatteryStats = BatteryStatsService.getService(); + } else if (mDisplayId == Display.DEFAULT_DISPLAY) { mBatteryStats = BatteryStatsService.getService(); } else { mBatteryStats = null; @@ -2791,8 +2793,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call screenState, mDisplayStatsId, reason); if (mBatteryStats != null) { try { - // TODO(multi-display): make this multi-display - mBatteryStats.noteScreenState(screenState); + mBatteryStats.noteScreenState(mDisplayId, screenState, reason); } catch (RemoteException e) { // same process } @@ -2807,7 +2808,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call int brightnessInt = mFlags.isBrightnessIntRangeUserPerceptionEnabled() ? BrightnessSynchronizer.brightnessFloatToIntSetting(mContext, brightness) : BrightnessSynchronizer.brightnessFloatToInt(brightness); - mBatteryStats.noteScreenBrightness(brightnessInt); + mBatteryStats.noteScreenBrightness(mDisplayId, brightnessInt); } catch (RemoteException e) { // same process } diff --git a/services/core/java/com/android/server/display/feature/DisplayManagerFlags.java b/services/core/java/com/android/server/display/feature/DisplayManagerFlags.java index 69b67c87afb9..f600e7fc2946 100644 --- a/services/core/java/com/android/server/display/feature/DisplayManagerFlags.java +++ b/services/core/java/com/android/server/display/feature/DisplayManagerFlags.java @@ -200,6 +200,11 @@ public class DisplayManagerFlags { Flags::normalBrightnessForDozeParameter ); + private final FlagState mEnableBatteryStatsForAllDisplays = new FlagState( + Flags.FLAG_ENABLE_BATTERY_STATS_FOR_ALL_DISPLAYS, + Flags::enableBatteryStatsForAllDisplays + ); + /** * @return {@code true} if 'port' is allowed in display layout configuration file. */ @@ -415,6 +420,14 @@ public class DisplayManagerFlags { } /** + * @return {@code true} if battery stats is enabled for all displays, not just the primary + * display. + */ + public boolean isBatteryStatsEnabledForAllDisplays() { + return mEnableBatteryStatsForAllDisplays.isEnabled(); + } + + /** * dumps all flagstates * @param pw printWriter */ @@ -456,6 +469,7 @@ public class DisplayManagerFlags { pw.println(" " + mNewHdrBrightnessModifier); pw.println(" " + mNormalBrightnessForDozeParameter); pw.println(" " + mIdleScreenConfigInSubscribingLightSensor); + pw.println(" " + mEnableBatteryStatsForAllDisplays); } private static class FlagState { diff --git a/services/core/java/com/android/server/display/feature/display_flags.aconfig b/services/core/java/com/android/server/display/feature/display_flags.aconfig index 70230b48a672..9968ba57bba4 100644 --- a/services/core/java/com/android/server/display/feature/display_flags.aconfig +++ b/services/core/java/com/android/server/display/feature/display_flags.aconfig @@ -349,3 +349,11 @@ flag { purpose: PURPOSE_BUGFIX } } + +flag { + name: "enable_battery_stats_for_all_displays" + namespace: "display_manager" + description: "Flag to enable battery stats for all displays." + bug: "366112793" + is_fixed_read_only: true +}
\ No newline at end of file diff --git a/services/core/java/com/android/server/power/stats/BatteryStatsImpl.java b/services/core/java/com/android/server/power/stats/BatteryStatsImpl.java index 680b1acedf78..cb8e1a0f35b8 100644 --- a/services/core/java/com/android/server/power/stats/BatteryStatsImpl.java +++ b/services/core/java/com/android/server/power/stats/BatteryStatsImpl.java @@ -5031,9 +5031,7 @@ public class BatteryStatsImpl extends BatteryStats { if (mPretendScreenOff != pretendScreenOff) { mPretendScreenOff = pretendScreenOff; final int primaryScreenState = mPerDisplayBatteryStats[0].screenState; - noteScreenStateLocked(0, primaryScreenState, - mClock.elapsedRealtime(), mClock.uptimeMillis(), - mClock.currentTimeMillis()); + noteScreenStateLocked(0, primaryScreenState); } } @@ -5554,15 +5552,29 @@ public class BatteryStatsImpl extends BatteryStats { } } + private static String getScreenStateTag( + int display, int state, @Display.StateReason int reason) { + return String.format( + "display=%d state=%s reason=%s", + display, Display.stateToString(state), Display.stateReasonToString(reason)); + } + @GuardedBy("this") public void noteScreenStateLocked(int display, int state) { - noteScreenStateLocked(display, state, mClock.elapsedRealtime(), mClock.uptimeMillis(), - mClock.currentTimeMillis()); + noteScreenStateLocked(display, state, Display.STATE_REASON_UNKNOWN, + mClock.elapsedRealtime(), mClock.uptimeMillis(), mClock.currentTimeMillis()); } @GuardedBy("this") public void noteScreenStateLocked(int display, int displayState, - long elapsedRealtimeMs, long uptimeMs, long currentTimeMs) { + @Display.StateReason int displayStateReason, long elapsedRealtimeMs, long uptimeMs, + long currentTimeMs) { + if (Flags.batteryStatsScreenStateEvent()) { + mHistory.recordEvent( + elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_DISPLAY_STATE_CHANGED, + getScreenStateTag(display, displayState, displayStateReason), + Process.INVALID_UID); + } // Battery stats relies on there being 4 states. To accommodate this, new states beyond the // original 4 are mapped to one of the originals. if (displayState > MAX_TRACKED_SCREEN_STATE) { diff --git a/services/core/java/com/android/server/power/stats/flags.aconfig b/services/core/java/com/android/server/power/stats/flags.aconfig index cc0a283db6a0..05d29f50085c 100644 --- a/services/core/java/com/android/server/power/stats/flags.aconfig +++ b/services/core/java/com/android/server/power/stats/flags.aconfig @@ -68,3 +68,11 @@ flag { description: "Disable deprecated BatteryUsageStatsAtom pulled atom" bug: "324602949" } + +flag { + name: "battery_stats_screen_state_event" + namespace: "backstage_power" + description: "Guards the battery stats event for screen state changes." + bug: "364350206" + is_fixed_read_only: true +} diff --git a/services/tests/displayservicetests/src/com/android/server/display/DisplayPowerControllerTest.java b/services/tests/displayservicetests/src/com/android/server/display/DisplayPowerControllerTest.java index d0aec3b6cef8..bf5a692ef8ca 100644 --- a/services/tests/displayservicetests/src/com/android/server/display/DisplayPowerControllerTest.java +++ b/services/tests/displayservicetests/src/com/android/server/display/DisplayPowerControllerTest.java @@ -75,6 +75,7 @@ import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.filters.SmallTest; import androidx.test.platform.app.InstrumentationRegistry; +import com.android.internal.app.IBatteryStats; import com.android.modules.utils.testing.ExtendedMockitoRule; import com.android.server.LocalServices; import com.android.server.am.BatteryStatsService; @@ -158,6 +159,8 @@ public final class DisplayPowerControllerTest { private DisplayManagerFlags mDisplayManagerFlagsMock; @Mock private DisplayManagerInternal.DisplayOffloadSession mDisplayOffloadSession; + @Mock + private IBatteryStats mMockBatteryStats; @Captor private ArgumentCaptor<SensorEventListener> mSensorEventListenerCaptor; @@ -204,7 +207,8 @@ public final class DisplayPowerControllerTest { doAnswer((Answer<Void>) invocationOnMock -> null).when(() -> SystemProperties.set(anyString(), any())); - doAnswer((Answer<Void>) invocationOnMock -> null).when(BatteryStatsService::getService); + doAnswer((Answer<IBatteryStats>) invocationOnMock -> mMockBatteryStats) + .when(BatteryStatsService::getService); doAnswer((Answer<Boolean>) invocationOnMock -> false) .when(ActivityManager::isLowRamDeviceStatic); @@ -2227,6 +2231,52 @@ public final class DisplayPowerControllerTest { verify(mHolder.brightnessSetting).saveIfNeeded(); } + @Test + public void testBatteryStatNotes_enabledOnDefaultDisplayWhenDisabledOnOthers() + throws Exception { + when(mDisplayManagerFlagsMock.isBatteryStatsEnabledForAllDisplays()).thenReturn(false); + + verifyNoteScreenState(Display.DEFAULT_DISPLAY, /* expectNote= */ true); + } + + @Test + public void testBatteryStatNotes_enabledOnDefaultDisplayWhenEnabledOnOthers() throws Exception { + when(mDisplayManagerFlagsMock.isBatteryStatsEnabledForAllDisplays()).thenReturn(true); + + verifyNoteScreenState(Display.DEFAULT_DISPLAY, /* expectNote= */ true); + } + + @Test + public void testBatteryStatNotes_flagGuardedOnNonDefaultDisplays() throws Exception { + when(mDisplayManagerFlagsMock.isBatteryStatsEnabledForAllDisplays()).thenReturn(false); + + verifyNoteScreenState(/* displayId= */ 2, /* expectNote= */ false); + + when(mDisplayManagerFlagsMock.isBatteryStatsEnabledForAllDisplays()).thenReturn(true); + + verifyNoteScreenState(/* displayId= */ 2, /* expectNote= */ true); + } + + private void verifyNoteScreenState(int displayId, boolean expectNote) throws Exception { + mHolder = createDisplayPowerController(displayId, UNIQUE_ID); + DisplayPowerRequest dpr = new DisplayPowerRequest(); + dpr.policy = DisplayPowerRequest.POLICY_BRIGHT; + when(mHolder.displayPowerState.getScreenState()).thenReturn(Display.STATE_ON); + + mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false); + advanceTime(1); // Run updatePowerState + + if (expectNote) { + verify(mMockBatteryStats) + .noteScreenState( + displayId, Display.STATE_ON, Display.STATE_REASON_DEFAULT_POLICY); + verify(mMockBatteryStats).noteScreenBrightness(eq(displayId), anyInt()); + } else { + verify(mMockBatteryStats, never()).noteScreenState(anyInt(), anyInt(), anyInt()); + verify(mMockBatteryStats, never()).noteScreenBrightness(anyInt(), anyInt()); + } + } + /** * Creates a mock and registers it to {@link LocalServices}. */ diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/AmbientDisplayPowerCalculatorTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/AmbientDisplayPowerCalculatorTest.java index f74cfae6a81b..c0be8652f303 100644 --- a/services/tests/powerstatstests/src/com/android/server/power/stats/AmbientDisplayPowerCalculatorTest.java +++ b/services/tests/powerstatstests/src/com/android/server/power/stats/AmbientDisplayPowerCalculatorTest.java @@ -56,14 +56,14 @@ public class AmbientDisplayPowerCalculatorTest { stats.updateDisplayEnergyConsumerStatsLocked(new long[]{300_000_000}, new int[]{Display.STATE_ON}, 0); - stats.noteScreenStateLocked(0, Display.STATE_DOZE, 30 * MINUTE_IN_MS, 30 * MINUTE_IN_MS, - 30 * MINUTE_IN_MS); + stats.noteScreenStateLocked(0, Display.STATE_DOZE, Display.STATE_REASON_DEFAULT_POLICY, + 30 * MINUTE_IN_MS, 30 * MINUTE_IN_MS, 30 * MINUTE_IN_MS); stats.updateDisplayEnergyConsumerStatsLocked(new long[]{200_000_000}, new int[]{Display.STATE_DOZE}, 30 * MINUTE_IN_MS); - stats.noteScreenStateLocked(0, Display.STATE_OFF, 120 * MINUTE_IN_MS, 120 * MINUTE_IN_MS, - 120 * MINUTE_IN_MS); + stats.noteScreenStateLocked(0, Display.STATE_OFF, Display.STATE_REASON_DEFAULT_POLICY, + 120 * MINUTE_IN_MS, 120 * MINUTE_IN_MS, 120 * MINUTE_IN_MS); stats.updateDisplayEnergyConsumerStatsLocked(new long[]{100_000_000}, new int[]{Display.STATE_OFF}, 120 * MINUTE_IN_MS); @@ -93,37 +93,37 @@ public class AmbientDisplayPowerCalculatorTest { final int[] screenStates = new int[] {Display.STATE_OFF, Display.STATE_OFF}; - stats.noteScreenStateLocked(0, screenStates[0], 0, 0, 0); - stats.noteScreenStateLocked(1, screenStates[1], 0, 0, 0); + stats.noteScreenStateLocked(0, screenStates[0], Display.STATE_REASON_UNKNOWN, 0, 0, 0); + stats.noteScreenStateLocked(1, screenStates[1], Display.STATE_REASON_UNKNOWN, 0, 0, 0); stats.updateDisplayEnergyConsumerStatsLocked(new long[]{300, 400}, screenStates, 0); // Switch display0 to doze screenStates[0] = Display.STATE_DOZE; - stats.noteScreenStateLocked(0, screenStates[0], 30 * MINUTE_IN_MS, 30 * MINUTE_IN_MS, - 30 * MINUTE_IN_MS); + stats.noteScreenStateLocked(0, screenStates[0], Display.STATE_REASON_UNKNOWN, + 30 * MINUTE_IN_MS, 30 * MINUTE_IN_MS, 30 * MINUTE_IN_MS); stats.updateDisplayEnergyConsumerStatsLocked(new long[]{200, 300}, screenStates, 30 * MINUTE_IN_MS); // Switch display1 to doze screenStates[1] = Display.STATE_DOZE; - stats.noteScreenStateLocked(1, Display.STATE_DOZE, 90 * MINUTE_IN_MS, 90 * MINUTE_IN_MS, - 90 * MINUTE_IN_MS); + stats.noteScreenStateLocked(1, Display.STATE_DOZE, Display.STATE_REASON_UNKNOWN, + 90 * MINUTE_IN_MS, 90 * MINUTE_IN_MS, 90 * MINUTE_IN_MS); // 100,000,000 uC should be attributed to display 0 doze here. stats.updateDisplayEnergyConsumerStatsLocked(new long[]{100_000_000, 700_000_000}, screenStates, 90 * MINUTE_IN_MS); // Switch display0 to off screenStates[0] = Display.STATE_OFF; - stats.noteScreenStateLocked(0, screenStates[0], 120 * MINUTE_IN_MS, 120 * MINUTE_IN_MS, - 120 * MINUTE_IN_MS); + stats.noteScreenStateLocked(0, screenStates[0], Display.STATE_REASON_UNKNOWN, + 120 * MINUTE_IN_MS, 120 * MINUTE_IN_MS, 120 * MINUTE_IN_MS); // 40,000,000 and 70,000,000 uC should be attributed to display 0 and 1 doze here. stats.updateDisplayEnergyConsumerStatsLocked(new long[]{40_000_000, 70_000_000}, screenStates, 120 * MINUTE_IN_MS); // Switch display1 to off screenStates[1] = Display.STATE_OFF; - stats.noteScreenStateLocked(1, screenStates[1], 150 * MINUTE_IN_MS, 150 * MINUTE_IN_MS, - 150 * MINUTE_IN_MS); + stats.noteScreenStateLocked(1, screenStates[1], Display.STATE_REASON_UNKNOWN, + 150 * MINUTE_IN_MS, 150 * MINUTE_IN_MS, 150 * MINUTE_IN_MS); stats.updateDisplayEnergyConsumerStatsLocked(new long[]{100, 90_000_000}, screenStates, 150 * MINUTE_IN_MS); // 90,000,000 uC should be attributed to display 1 doze here. @@ -148,10 +148,10 @@ public class AmbientDisplayPowerCalculatorTest { public void testPowerProfileBasedModel() { BatteryStatsImpl stats = mStatsRule.getBatteryStats(); - stats.noteScreenStateLocked(0, Display.STATE_DOZE, 30 * MINUTE_IN_MS, 30 * MINUTE_IN_MS, - 30 * MINUTE_IN_MS); - stats.noteScreenStateLocked(0, Display.STATE_OFF, 120 * MINUTE_IN_MS, 120 * MINUTE_IN_MS, - 120 * MINUTE_IN_MS); + stats.noteScreenStateLocked(0, Display.STATE_DOZE, Display.STATE_REASON_UNKNOWN, + 30 * MINUTE_IN_MS, 30 * MINUTE_IN_MS, 30 * MINUTE_IN_MS); + stats.noteScreenStateLocked(0, Display.STATE_OFF, Display.STATE_REASON_UNKNOWN, + 120 * MINUTE_IN_MS, 120 * MINUTE_IN_MS, 120 * MINUTE_IN_MS); AmbientDisplayPowerCalculator calculator = new AmbientDisplayPowerCalculator(mStatsRule.getPowerProfile()); @@ -174,15 +174,15 @@ public class AmbientDisplayPowerCalculatorTest { BatteryStatsImpl stats = mStatsRule.getBatteryStats(); - stats.noteScreenStateLocked(1, Display.STATE_OFF, 0, 0, 0); - stats.noteScreenStateLocked(0, Display.STATE_DOZE, 30 * MINUTE_IN_MS, 30 * MINUTE_IN_MS, - 30 * MINUTE_IN_MS); - stats.noteScreenStateLocked(1, Display.STATE_DOZE, 90 * MINUTE_IN_MS, 90 * MINUTE_IN_MS, - 90 * MINUTE_IN_MS); - stats.noteScreenStateLocked(0, Display.STATE_OFF, 120 * MINUTE_IN_MS, 120 * MINUTE_IN_MS, - 120 * MINUTE_IN_MS); - stats.noteScreenStateLocked(1, Display.STATE_OFF, 150 * MINUTE_IN_MS, 150 * MINUTE_IN_MS, - 150 * MINUTE_IN_MS); + stats.noteScreenStateLocked(1, Display.STATE_OFF, Display.STATE_REASON_UNKNOWN, 0, 0, 0); + stats.noteScreenStateLocked(0, Display.STATE_DOZE, Display.STATE_REASON_UNKNOWN, + 30 * MINUTE_IN_MS, 30 * MINUTE_IN_MS, 30 * MINUTE_IN_MS); + stats.noteScreenStateLocked(1, Display.STATE_DOZE, Display.STATE_REASON_UNKNOWN, + 90 * MINUTE_IN_MS, 90 * MINUTE_IN_MS, 90 * MINUTE_IN_MS); + stats.noteScreenStateLocked(0, Display.STATE_OFF, Display.STATE_REASON_UNKNOWN, + 120 * MINUTE_IN_MS, 120 * MINUTE_IN_MS, 120 * MINUTE_IN_MS); + stats.noteScreenStateLocked(1, Display.STATE_OFF, Display.STATE_REASON_UNKNOWN, + 150 * MINUTE_IN_MS, 150 * MINUTE_IN_MS, 150 * MINUTE_IN_MS); AmbientDisplayPowerCalculator calculator = new AmbientDisplayPowerCalculator(mStatsRule.getPowerProfile()); diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsNoteTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsNoteTest.java index afbe9159b66a..2ccb6420bc43 100644 --- a/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsNoteTest.java +++ b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsNoteTest.java @@ -44,6 +44,10 @@ import android.os.Looper; import android.os.Process; import android.os.UserHandle; import android.os.WorkSource; +import android.platform.test.annotations.DisableFlags; +import android.platform.test.annotations.DisabledOnRavenwood; +import android.platform.test.annotations.EnableFlags; +import android.platform.test.flag.junit.SetFlagsRule; import android.platform.test.ravenwood.RavenwoodRule; import android.telephony.AccessNetworkConstants; import android.telephony.ActivityStatsTechSpecificInfo; @@ -65,6 +69,7 @@ import com.android.internal.os.BatteryStatsHistoryIterator; import com.android.internal.os.MonotonicClock; import com.android.internal.os.PowerProfile; import com.android.internal.power.EnergyConsumerStats; +import com.android.server.power.optimization.Flags; import com.android.server.power.stats.BatteryStatsImpl.DualTimer; import org.junit.Rule; @@ -90,6 +95,8 @@ public class BatteryStatsNoteTest { .setProvideMainThread(true) .build(); + @Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(); + private static final String TAG = BatteryStatsNoteTest.class.getSimpleName(); private static final int UID = 10500; @@ -104,6 +111,54 @@ public class BatteryStatsNoteTest { @Mock NetworkStatsManager mNetworkStatsManager; + @DisabledOnRavenwood + @EnableFlags(Flags.FLAG_BATTERY_STATS_SCREEN_STATE_EVENT) + @Test + public void testScreenStateEvent_screenStateEventFlagOn_eventsRecorded() throws Exception { + MockBatteryStatsImpl bi = new MockBatteryStatsImpl(new MockClock()); + bi.forceRecordAllHistory(); + + bi.noteScreenStateLocked(0, Display.STATE_ON, Display.STATE_REASON_DEFAULT_POLICY, + 0, 0, 0); + bi.noteScreenStateLocked(2, Display.STATE_DOZE_SUSPEND, Display.STATE_REASON_DRAW_WAKE_LOCK, + 1, 1, 1); + + BatteryStatsHistoryIterator iterator = + bi.iterateBatteryStatsHistory(0, MonotonicClock.UNDEFINED); + BatteryStats.HistoryItem item = + iterateAndFind(iterator, HistoryItem.EVENT_DISPLAY_STATE_CHANGED); + assertThat(item).isNotNull(); + assertThat(item.eventTag).isNotNull(); + assertThat(item.eventTag.string).isEqualTo("display=0 state=ON reason=DEFAULT_POLICY"); + assertThat(item.eventTag.uid).isEqualTo(Process.INVALID_UID); + + item = iterateAndFind(iterator, HistoryItem.EVENT_DISPLAY_STATE_CHANGED); + assertThat(item).isNotNull(); + assertThat(item.eventTag).isNotNull(); + assertThat(item.eventTag.string) + .isEqualTo("display=2 state=DOZE_SUSPEND reason=DRAW_WAKE_LOCK"); + assertThat(item.eventTag.uid).isEqualTo(Process.INVALID_UID); + + // Last check to make sure that we did not record any extra event. + assertThat(iterateAndFind(iterator, HistoryItem.EVENT_DISPLAY_STATE_CHANGED)).isNull(); + } + + @DisableFlags(Flags.FLAG_BATTERY_STATS_SCREEN_STATE_EVENT) + @Test + public void testScreenStateEvent_screenStateEventFlagOff_eventsNotRecorded() throws Exception { + MockBatteryStatsImpl bi = new MockBatteryStatsImpl(new MockClock()); + bi.forceRecordAllHistory(); + + bi.noteScreenStateLocked(0, Display.STATE_ON, Display.STATE_REASON_DEFAULT_POLICY, + 0, 0, 0); + bi.noteScreenStateLocked(2, Display.STATE_DOZE_SUSPEND, Display.STATE_REASON_DRAW_WAKE_LOCK, + 1, 1, 1); + + BatteryStatsHistoryIterator iterator = + bi.iterateBatteryStatsHistory(0, MonotonicClock.UNDEFINED); + assertThat(iterateAndFind(iterator, HistoryItem.EVENT_DISPLAY_STATE_CHANGED)).isNull(); + } + /** * Test BatteryStatsImpl.Uid.noteBluetoothScanResultLocked. */ @@ -285,20 +340,15 @@ public class BatteryStatsNoteTest { final BatteryStatsHistoryIterator iterator = bi.iterateBatteryStatsHistory(0, MonotonicClock.UNDEFINED); - BatteryStats.HistoryItem item; + BatteryStats.HistoryItem item = + iterateAndFind(iterator, HistoryItem.EVENT_LONG_WAKE_LOCK_START); - while ((item = iterator.next()) != null) { - if (item.eventCode == HistoryItem.EVENT_LONG_WAKE_LOCK_START) break; - } - assertThat(item.eventCode).isEqualTo(HistoryItem.EVENT_LONG_WAKE_LOCK_START); + assertThat(item).isNotNull(); assertThat(item.eventTag).isNotNull(); assertThat(item.eventTag.string).isEqualTo(historyName); assertThat(item.eventTag.uid).isEqualTo(UID); - while ((item = iterator.next()) != null) { - if (item.eventCode == HistoryItem.EVENT_LONG_WAKE_LOCK_FINISH) break; - } - assertThat(item.eventCode).isEqualTo(HistoryItem.EVENT_LONG_WAKE_LOCK_FINISH); + item = iterateAndFind(iterator, HistoryItem.EVENT_LONG_WAKE_LOCK_FINISH); assertThat(item.eventTag).isNotNull(); assertThat(item.eventTag.string).isEqualTo(historyName); assertThat(item.eventTag.uid).isEqualTo(UID); @@ -343,20 +393,15 @@ public class BatteryStatsNoteTest { final BatteryStatsHistoryIterator iterator = bi.iterateBatteryStatsHistory(0, MonotonicClock.UNDEFINED); - BatteryStats.HistoryItem item; - - while ((item = iterator.next()) != null) { - if (item.eventCode == HistoryItem.EVENT_LONG_WAKE_LOCK_START) break; - } - assertThat(item.eventCode).isEqualTo(HistoryItem.EVENT_LONG_WAKE_LOCK_START); + BatteryStats.HistoryItem item = + iterateAndFind(iterator, HistoryItem.EVENT_LONG_WAKE_LOCK_START); + assertThat(item).isNotNull(); assertThat(item.eventTag).isNotNull(); assertThat(item.eventTag.string).isEqualTo(historyName); assertThat(item.eventTag.uid).isEqualTo(UID); - while ((item = iterator.next()) != null) { - if (item.eventCode == HistoryItem.EVENT_LONG_WAKE_LOCK_FINISH) break; - } - assertThat(item.eventCode).isEqualTo(HistoryItem.EVENT_LONG_WAKE_LOCK_FINISH); + item = iterateAndFind(iterator, HistoryItem.EVENT_LONG_WAKE_LOCK_FINISH); + assertThat(item).isNotNull(); assertThat(item.eventTag).isNotNull(); assertThat(item.eventTag.string).isEqualTo(historyName); assertThat(item.eventTag.uid).isEqualTo(UID); @@ -2562,4 +2607,18 @@ public class BatteryStatsNoteTest { currentTimeMs, currentTimeMs, mNetworkStatsManager); } } + + /** + * Moves a given {@link BatteryStatsHistoryIterator} until a history item with the given + * {@code eventCode} is found and returns the history item. Returns {@code null} if no such item + * is found. + */ + private static BatteryStats.HistoryItem iterateAndFind( + BatteryStatsHistoryIterator iterator, int eventCode) { + BatteryStats.HistoryItem item; + while ((item = iterator.next()) != null) { + if (item.eventCode == eventCode) return item; + } + return null; + } } diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/ScreenPowerCalculatorTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/ScreenPowerCalculatorTest.java index 88d4ea75501d..2da98e8b9a61 100644 --- a/services/tests/powerstatstests/src/com/android/server/power/stats/ScreenPowerCalculatorTest.java +++ b/services/tests/powerstatstests/src/com/android/server/power/stats/ScreenPowerCalculatorTest.java @@ -61,7 +61,8 @@ public class ScreenPowerCalculatorTest { mStatsRule.initMeasuredEnergyStatsLocked(); BatteryStatsImpl batteryStats = mStatsRule.getBatteryStats(); - batteryStats.noteScreenStateLocked(0, Display.STATE_ON, 0, 0, 0); + batteryStats.noteScreenStateLocked(0, Display.STATE_ON, Display.STATE_REASON_UNKNOWN, + 0, 0, 0); batteryStats.updateDisplayEnergyConsumerStatsLocked(new long[]{0}, new int[]{Display.STATE_ON}, 0); setProcState(APP_UID1, ActivityManager.PROCESS_STATE_TOP, true, @@ -79,7 +80,7 @@ public class ScreenPowerCalculatorTest { batteryStats.updateDisplayEnergyConsumerStatsLocked(new long[]{300_000_000}, new int[]{Display.STATE_ON}, 60 * MINUTE_IN_MS); - batteryStats.noteScreenStateLocked(0, Display.STATE_OFF, + batteryStats.noteScreenStateLocked(0, Display.STATE_OFF, Display.STATE_REASON_UNKNOWN, 80 * MINUTE_IN_MS, 80 * MINUTE_IN_MS, 80 * MINUTE_IN_MS); setProcState(APP_UID2, ActivityManager.PROCESS_STATE_TOP_SLEEPING, false, 80 * MINUTE_IN_MS, 80 * MINUTE_IN_MS); @@ -150,8 +151,10 @@ public class ScreenPowerCalculatorTest { final int[] screenStates = new int[]{Display.STATE_ON, Display.STATE_OFF}; - batteryStats.noteScreenStateLocked(0, screenStates[0], 0, 0, 0); - batteryStats.noteScreenStateLocked(1, screenStates[1], 0, 0, 0); + batteryStats.noteScreenStateLocked(0, screenStates[0], Display.STATE_REASON_UNKNOWN, + 0, 0, 0); + batteryStats.noteScreenStateLocked(1, screenStates[1], Display.STATE_REASON_UNKNOWN, + 0, 0, 0); batteryStats.noteScreenBrightnessLocked(0, 255, 0, 0); setProcState(APP_UID1, ActivityManager.PROCESS_STATE_TOP, true, 0, 0); batteryStats.updateDisplayEnergyConsumerStatsLocked(new long[]{300, 400}, screenStates, 0); @@ -166,10 +169,10 @@ public class ScreenPowerCalculatorTest { screenStates[0] = Display.STATE_OFF; screenStates[1] = Display.STATE_ON; - batteryStats.noteScreenStateLocked(0, screenStates[0], + batteryStats.noteScreenStateLocked(0, screenStates[0], Display.STATE_REASON_UNKNOWN, + 80 * MINUTE_IN_MS, 80 * MINUTE_IN_MS, 80 * MINUTE_IN_MS); + batteryStats.noteScreenStateLocked(1, screenStates[1], Display.STATE_REASON_UNKNOWN, 80 * MINUTE_IN_MS, 80 * MINUTE_IN_MS, 80 * MINUTE_IN_MS); - batteryStats.noteScreenStateLocked(1, screenStates[1], 80 * MINUTE_IN_MS, - 80 * MINUTE_IN_MS, 80 * MINUTE_IN_MS); batteryStats.updateDisplayEnergyConsumerStatsLocked(new long[]{600_000_000, 500}, screenStates, 80 * MINUTE_IN_MS); @@ -178,8 +181,8 @@ public class ScreenPowerCalculatorTest { batteryStats.noteScreenBrightnessLocked(1, 75, 98 * MINUTE_IN_MS, 98 * MINUTE_IN_MS); screenStates[1] = Display.STATE_OFF; - batteryStats.noteScreenStateLocked(1, screenStates[1], 110 * MINUTE_IN_MS, - 110 * MINUTE_IN_MS, 110 * MINUTE_IN_MS); + batteryStats.noteScreenStateLocked(1, screenStates[1], Display.STATE_REASON_UNKNOWN, + 110 * MINUTE_IN_MS, 110 * MINUTE_IN_MS, 110 * MINUTE_IN_MS); batteryStats.updateDisplayEnergyConsumerStatsLocked(new long[]{700, 800_000_000}, screenStates, 110 * MINUTE_IN_MS); @@ -240,7 +243,8 @@ public class ScreenPowerCalculatorTest { public void testPowerProfileBasedModel() { BatteryStatsImpl batteryStats = mStatsRule.getBatteryStats(); - batteryStats.noteScreenStateLocked(0, Display.STATE_ON, 0, 0, 0); + batteryStats.noteScreenStateLocked(0, Display.STATE_ON, Display.STATE_REASON_UNKNOWN, + 0, 0, 0); batteryStats.noteScreenBrightnessLocked(0, 255, 0, 0); setProcState(APP_UID1, ActivityManager.PROCESS_STATE_TOP, true, 0, 0); @@ -253,7 +257,7 @@ public class ScreenPowerCalculatorTest { setProcState(APP_UID2, ActivityManager.PROCESS_STATE_TOP, true, 20 * MINUTE_IN_MS, 20 * MINUTE_IN_MS); - batteryStats.noteScreenStateLocked(0, Display.STATE_OFF, + batteryStats.noteScreenStateLocked(0, Display.STATE_OFF, Display.STATE_REASON_UNKNOWN, 80 * MINUTE_IN_MS, 80 * MINUTE_IN_MS, 80 * MINUTE_IN_MS); setProcState(APP_UID2, ActivityManager.PROCESS_STATE_TOP_SLEEPING, false, 80 * MINUTE_IN_MS, 80 * MINUTE_IN_MS); @@ -313,8 +317,10 @@ public class ScreenPowerCalculatorTest { BatteryStatsImpl batteryStats = mStatsRule.getBatteryStats(); - batteryStats.noteScreenStateLocked(0, Display.STATE_ON, 0, 0, 0); - batteryStats.noteScreenStateLocked(1, Display.STATE_OFF, 0, 0, 0); + batteryStats.noteScreenStateLocked(0, Display.STATE_ON, Display.STATE_REASON_UNKNOWN, + 0, 0, 0); + batteryStats.noteScreenStateLocked(1, Display.STATE_OFF, Display.STATE_REASON_UNKNOWN, + 0, 0, 0); batteryStats.noteScreenBrightnessLocked(0, 255, 0, 0); setProcState(APP_UID1, ActivityManager.PROCESS_STATE_TOP, true, 0, 0); @@ -327,16 +333,16 @@ public class ScreenPowerCalculatorTest { setProcState(APP_UID2, ActivityManager.PROCESS_STATE_TOP, true, 20 * MINUTE_IN_MS, 20 * MINUTE_IN_MS); - batteryStats.noteScreenStateLocked(0, Display.STATE_OFF, + batteryStats.noteScreenStateLocked(0, Display.STATE_OFF, Display.STATE_REASON_UNKNOWN, + 80 * MINUTE_IN_MS, 80 * MINUTE_IN_MS, 80 * MINUTE_IN_MS); + batteryStats.noteScreenStateLocked(1, Display.STATE_ON, Display.STATE_REASON_UNKNOWN, 80 * MINUTE_IN_MS, 80 * MINUTE_IN_MS, 80 * MINUTE_IN_MS); - batteryStats.noteScreenStateLocked(1, Display.STATE_ON, 80 * MINUTE_IN_MS, - 80 * MINUTE_IN_MS, 80 * MINUTE_IN_MS); batteryStats.noteScreenBrightnessLocked(1, 20, 80 * MINUTE_IN_MS, 80 * MINUTE_IN_MS); batteryStats.noteScreenBrightnessLocked(1, 250, 86 * MINUTE_IN_MS, 86 * MINUTE_IN_MS); batteryStats.noteScreenBrightnessLocked(1, 75, 98 * MINUTE_IN_MS, 98 * MINUTE_IN_MS); - batteryStats.noteScreenStateLocked(1, Display.STATE_OFF, 110 * MINUTE_IN_MS, - 110 * MINUTE_IN_MS, 110 * MINUTE_IN_MS); + batteryStats.noteScreenStateLocked(1, Display.STATE_OFF, Display.STATE_REASON_UNKNOWN, + 110 * MINUTE_IN_MS, 110 * MINUTE_IN_MS, 110 * MINUTE_IN_MS); setProcState(APP_UID2, ActivityManager.PROCESS_STATE_TOP_SLEEPING, false, 110 * MINUTE_IN_MS, 110 * MINUTE_IN_MS); |