From 06dea749bfb1492a37a2beb3b8864cf725c9e01f Mon Sep 17 00:00:00 2001 From: "daren.liao" Date: Thu, 28 Apr 2022 17:47:23 +0800 Subject: [PATCH] Use elapsed real time for sleep duration for the wake up with home intent getLastWakeup is used for Boot resume feature Currently timer stops running when TV enter STR mode. We replace CPU time to RTC time so that the timer runs even in STR mode Bug: 199339422 Test: atest com.android.server.power.PowerManagerServiceTest Test: atest com.android.server.power.PowerManagerServiceMockingTest Change-Id: Ib092a692e957c3df92cf9b61efad5490e4e221c1 --- core/java/android/os/PowerManager.java | 10 ++--- .../server/policy/PhoneWindowManager.java | 7 ++-- .../server/power/PowerManagerService.java | 37 ++++++++++++++++--- .../power/PowerManagerServiceMockingTest.java | 12 +++++- .../server/power/PowerManagerServiceTest.java | 24 +++++++++--- 5 files changed, 70 insertions(+), 20 deletions(-) diff --git a/core/java/android/os/PowerManager.java b/core/java/android/os/PowerManager.java index 13ca2c34b27ec..bc81acfffd008 100644 --- a/core/java/android/os/PowerManager.java +++ b/core/java/android/os/PowerManager.java @@ -712,28 +712,28 @@ public final class PowerManager { * @hide */ public static class WakeData { - public WakeData(long wakeTime, @WakeReason int wakeReason, long sleepDuration) { + public WakeData(long wakeTime, @WakeReason int wakeReason, long sleepDurationRealtime) { this.wakeTime = wakeTime; this.wakeReason = wakeReason; - this.sleepDuration = sleepDuration; + this.sleepDurationRealtime = sleepDurationRealtime; } public final long wakeTime; public final @WakeReason int wakeReason; - public final long sleepDuration; + public final long sleepDurationRealtime; @Override public boolean equals(@Nullable Object o) { if (o instanceof WakeData) { final WakeData other = (WakeData) o; return wakeTime == other.wakeTime && wakeReason == other.wakeReason - && sleepDuration == other.sleepDuration; + && sleepDurationRealtime == other.sleepDurationRealtime; } return false; } @Override public int hashCode() { - return Objects.hash(wakeTime, wakeReason, sleepDuration); + return Objects.hash(wakeTime, wakeReason, sleepDurationRealtime); } } diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java index dd952f4e903b7..cbab2c594b4e8 100644 --- a/services/core/java/com/android/server/policy/PhoneWindowManager.java +++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java @@ -4585,12 +4585,13 @@ public class PhoneWindowManager implements WindowManagerPolicy { return false; } - final long sleepDuration = mPowerManagerInternal.getLastWakeup().sleepDuration; + final long sleepDurationRealtime = + mPowerManagerInternal.getLastWakeup().sleepDurationRealtime; if (DEBUG_WAKEUP) { - Log.i(TAG, "shouldWakeUpWithHomeIntent: sleepDuration= " + sleepDuration + Log.i(TAG, "shouldWakeUpWithHomeIntent: sleepDurationRealtime= " + sleepDurationRealtime + " mWakeUpToLastStateTimeout= " + mWakeUpToLastStateTimeout); } - return sleepDuration > mWakeUpToLastStateTimeout; + return sleepDurationRealtime > mWakeUpToLastStateTimeout; } private void wakeUpFromPowerKey(long eventTime) { diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java index 50d1bd6c3e33d..3e8e386867ac4 100644 --- a/services/core/java/com/android/server/power/PowerManagerService.java +++ b/services/core/java/com/android/server/power/PowerManagerService.java @@ -360,6 +360,10 @@ public final class PowerManagerService extends SystemService private long mLastGlobalWakeTime; private long mLastGlobalSleepTime; + // Timestamp (in the elapsed realtime timebase) of the last time was awoken or put to sleep. + private long mLastGlobalWakeTimeRealtime; + private long mLastGlobalSleepTimeRealtime; + // Last reason the device went to sleep. private @WakeReason int mLastGlobalWakeReason; private @GoToSleepReason int mLastGlobalSleepReason; @@ -911,6 +915,11 @@ public final class PowerManagerService extends SystemService * Returns current time in milliseconds since boot, not counting time spent in deep sleep. */ long uptimeMillis(); + + /** + * Returns milliseconds since boot, including time spent in sleep. + */ + long elapsedRealtime(); } @VisibleForTesting @@ -984,7 +993,18 @@ public final class PowerManagerService extends SystemService } Clock createClock() { - return SystemClock::uptimeMillis; + return new Clock() { + @Override + public long uptimeMillis() { + return SystemClock.uptimeMillis(); + } + + @Override + public long elapsedRealtime() { + return SystemClock.elapsedRealtime(); + } + }; + } /** @@ -2112,6 +2132,7 @@ public final class PowerManagerService extends SystemService + ")..."); mLastGlobalWakeTime = eventTime; mLastGlobalWakeReason = reason; + mLastGlobalWakeTimeRealtime = mClock.elapsedRealtime(); break; case WAKEFULNESS_DREAMING: @@ -2123,9 +2144,9 @@ public final class PowerManagerService extends SystemService traceMethodName = "goToSleep"; Slog.i(TAG, "Going to sleep due to " + PowerManager.sleepReasonToString(reason) + " (uid " + uid + ")..."); - mLastGlobalSleepTime = eventTime; mLastGlobalSleepReason = reason; + mLastGlobalSleepTimeRealtime = mClock.elapsedRealtime(); mDozeStartInProgress = true; break; @@ -4375,6 +4396,10 @@ public final class PowerManagerService extends SystemService pw.println(" mLastSleepTime=" + TimeUtils.formatUptime(mLastGlobalSleepTime)); pw.println(" mLastSleepReason=" + PowerManager.sleepReasonToString( mLastGlobalSleepReason)); + pw.println(" mLastGlobalWakeTimeRealtime=" + + TimeUtils.formatUptime(mLastGlobalWakeTimeRealtime)); + pw.println(" mLastGlobalSleepTimeRealtime=" + + TimeUtils.formatUptime(mLastGlobalSleepTimeRealtime)); pw.println(" mLastInteractivePowerHintTime=" + TimeUtils.formatUptime(mLastInteractivePowerHintTime)); pw.println(" mLastScreenBrightnessBoostTime=" @@ -5856,7 +5881,7 @@ public final class PowerManagerService extends SystemService boolean isPersonalized) { // Get current time before acquiring the lock so that the calculated end time is as // accurate as possible. - final long nowElapsed = SystemClock.elapsedRealtime(); + final long nowElapsed = mClock.elapsedRealtime(); if (mContext.checkCallingOrSelfPermission( android.Manifest.permission.BATTERY_PREDICTION) != PackageManager.PERMISSION_GRANTED) { @@ -5920,7 +5945,7 @@ public final class PowerManagerService extends SystemService synchronized (mEnhancedDischargeTimeLock) { // Get current time after acquiring the lock so that the calculated duration // is as accurate as possible. - final long nowElapsed = SystemClock.elapsedRealtime(); + final long nowElapsed = mClock.elapsedRealtime(); if (isEnhancedDischargePredictionValidLocked(nowElapsed)) { return new ParcelDuration(mEnhancedDischargeTimeElapsed - nowElapsed); } @@ -5939,7 +5964,7 @@ public final class PowerManagerService extends SystemService final long ident = Binder.clearCallingIdentity(); try { synchronized (mEnhancedDischargeTimeLock) { - return isEnhancedDischargePredictionValidLocked(SystemClock.elapsedRealtime()) + return isEnhancedDischargePredictionValidLocked(mClock.elapsedRealtime()) && mEnhancedDischargePredictionIsPersonalized; } } finally { @@ -6429,7 +6454,7 @@ public final class PowerManagerService extends SystemService private PowerManager.WakeData getLastWakeupInternal() { synchronized (mLock) { return new PowerManager.WakeData(mLastGlobalWakeTime, mLastGlobalWakeReason, - mLastGlobalWakeTime - mLastGlobalSleepTime); + mLastGlobalWakeTimeRealtime - mLastGlobalSleepTimeRealtime); } } diff --git a/services/tests/mockingservicestests/src/com/android/server/power/PowerManagerServiceMockingTest.java b/services/tests/mockingservicestests/src/com/android/server/power/PowerManagerServiceMockingTest.java index 5c4657fb00273..0f2c27c83791a 100644 --- a/services/tests/mockingservicestests/src/com/android/server/power/PowerManagerServiceMockingTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/power/PowerManagerServiceMockingTest.java @@ -223,7 +223,17 @@ public class PowerManagerServiceMockingTest { @Override PowerManagerService.Clock createClock() { - return () -> mClock.now(); + return new PowerManagerService.Clock() { + @Override + public long uptimeMillis() { + return mClock.now(); + } + + @Override + public long elapsedRealtime() { + return mClock.now(); + } + }; } @Override diff --git a/services/tests/servicestests/src/com/android/server/power/PowerManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/power/PowerManagerServiceTest.java index 40ce956a0790e..fee488c54485d 100644 --- a/services/tests/servicestests/src/com/android/server/power/PowerManagerServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/power/PowerManagerServiceTest.java @@ -154,6 +154,7 @@ public class PowerManagerServiceTest { private UserSwitchedReceiver mUserSwitchedReceiver; private Resources mResourcesSpy; private OffsettableClock mClock; + private long mLastElapsedRealtime; private TestLooper mTestLooper; private static class IntentFilterMatcher implements ArgumentMatcher { @@ -282,7 +283,18 @@ public class PowerManagerServiceTest { @Override PowerManagerService.Clock createClock() { - return () -> mClock.now(); + return new PowerManagerService.Clock() { + @Override + public long uptimeMillis() { + return mClock.now(); + } + + @Override + public long elapsedRealtime() { + mLastElapsedRealtime = mClock.now(); + return mLastElapsedRealtime; + } + }; } @Override @@ -1629,6 +1641,7 @@ public class PowerManagerServiceTest { mService.setWakefulnessLocked(nonDefaultPowerGroupId, WAKEFULNESS_DOZING, eventTime2, 0, PowerManager.GO_TO_SLEEP_REASON_APPLICATION, 0, null, null); + long eventElapsedRealtime1 = mLastElapsedRealtime; assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_DOZING); assertThat(mService.getBinderServiceInstance().getLastSleepReason()).isEqualTo( PowerManager.GO_TO_SLEEP_REASON_APPLICATION); @@ -1636,19 +1649,20 @@ public class PowerManagerServiceTest { mService.setWakefulnessLocked(Display.DEFAULT_DISPLAY_GROUP, WAKEFULNESS_AWAKE, eventTime3, /* uid= */ 0, PowerManager.WAKE_REASON_PLUGGED_IN, /* opUid= */ 0, /* opPackageName= */ null, /* details= */ null); + long eventElapsedRealtime2 = mLastElapsedRealtime; PowerManager.WakeData wakeData = mService.getLocalServiceInstance().getLastWakeup(); assertThat(wakeData.wakeTime).isEqualTo(eventTime3); assertThat(wakeData.wakeReason).isEqualTo(PowerManager.WAKE_REASON_PLUGGED_IN); - assertThat(wakeData.sleepDuration).isEqualTo(eventTime3 - eventTime2); + assertThat(wakeData.sleepDurationRealtime) + .isEqualTo(eventElapsedRealtime2 - eventElapsedRealtime1); // The global wake time and reason as well as sleep duration shouldn't change when another // PowerGroup wakes up. mService.setWakefulnessLocked(nonDefaultPowerGroupId, WAKEFULNESS_AWAKE, eventTime4, /* uid= */ 0, PowerManager.WAKE_REASON_CAMERA_LAUNCH, /* opUid= */ 0, /* opPackageName= */ null, /* details= */ null); - assertThat(wakeData.wakeTime).isEqualTo(eventTime3); - assertThat(wakeData.wakeReason).isEqualTo(PowerManager.WAKE_REASON_PLUGGED_IN); - assertThat(wakeData.sleepDuration).isEqualTo(eventTime3 - eventTime2); + PowerManager.WakeData wakeData2 = mService.getLocalServiceInstance().getLastWakeup(); + assertThat(wakeData2).isEqualTo(wakeData); } @Test