diff --git a/core/java/android/os/PowerManager.java b/core/java/android/os/PowerManager.java index 18109046daf8b..b75459873eb90 100644 --- a/core/java/android/os/PowerManager.java +++ b/core/java/android/os/PowerManager.java @@ -704,6 +704,21 @@ public final class PowerManager { public long wakeTime; public @WakeReason int wakeReason; public long sleepDuration; + + @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; + } + return false; + } + + @Override + public int hashCode() { + return Objects.hash(wakeTime, wakeReason, sleepDuration); + } } /** diff --git a/services/core/java/com/android/server/power/PowerGroup.java b/services/core/java/com/android/server/power/PowerGroup.java index 9127484e89773..c1bfdf7a343f0 100644 --- a/services/core/java/com/android/server/power/PowerGroup.java +++ b/services/core/java/com/android/server/power/PowerGroup.java @@ -16,9 +16,16 @@ package com.android.server.power; +import static android.os.PowerManagerInternal.WAKEFULNESS_ASLEEP; import static android.os.PowerManagerInternal.WAKEFULNESS_AWAKE; +import static android.os.PowerManagerInternal.WAKEFULNESS_DOZING; +import static android.os.PowerManagerInternal.WAKEFULNESS_DREAMING; +import static android.os.PowerManagerInternal.isInteractive; import android.hardware.display.DisplayManagerInternal.DisplayPowerRequest; +import android.os.PowerManager; +import android.os.Trace; +import android.util.Slog; import android.view.Display; /** @@ -31,47 +38,66 @@ import android.view.Display; */ public class PowerGroup { private static final String TAG = PowerGroup.class.getSimpleName(); + private static final boolean DEBUG = false; private final DisplayPowerRequest mDisplayPowerRequest; + private final PowerGroupListener mWakefulnessListener; private final boolean mSupportsSandman; private final int mGroupId; - - // True if DisplayManagerService has applied all the latest display states that were requested - // for this group + /** True if DisplayManagerService has applied all the latest display states that were requested + * for this group. */ private boolean mReady; - // True if this group is in the process of powering on + /** True if this group is in the process of powering on */ private boolean mPoweringOn; - // True if this group is about to dream + /** True if this group is about to dream */ private boolean mIsSandmanSummoned; private int mUserActivitySummary; - // The current wakefulness of this group + /** The current wakefulness of this group */ private int mWakefulness; private int mWakeLockSummary; private long mLastPowerOnTime; private long mLastUserActivityTime; private long mLastUserActivityTimeNoChangeLights; + /** Timestamp (milliseconds since boot) of the last time the power group was awoken.*/ + private long mLastWakeTime; + /** Timestamp (milliseconds since boot) of the last time the power group was put to sleep. */ + private long mLastSleepTime; - PowerGroup(int groupId, DisplayPowerRequest displayPowerRequest, int wakefulness, boolean ready, - boolean supportsSandman) { - this.mGroupId = groupId; - this.mDisplayPowerRequest = displayPowerRequest; - this.mWakefulness = wakefulness; - this.mReady = ready; - this.mSupportsSandman = supportsSandman; + PowerGroup(int groupId, PowerGroupListener wakefulnessListener, + DisplayPowerRequest displayPowerRequest, int wakefulness, boolean ready, + boolean supportsSandman, long eventTime) { + mGroupId = groupId; + mWakefulnessListener = wakefulnessListener; + mDisplayPowerRequest = displayPowerRequest; + mWakefulness = wakefulness; + mReady = ready; + mSupportsSandman = supportsSandman; + mLastWakeTime = eventTime; + mLastSleepTime = eventTime; } - PowerGroup() { - this.mGroupId = Display.DEFAULT_DISPLAY_GROUP; - this.mDisplayPowerRequest = new DisplayPowerRequest(); - this.mWakefulness = WAKEFULNESS_AWAKE; - this.mReady = false; - this.mSupportsSandman = true; - } + PowerGroup(int wakefulness, PowerGroupListener wakefulnessListener, long eventTime) { + mGroupId = Display.DEFAULT_DISPLAY_GROUP; + mWakefulnessListener = wakefulnessListener; + mDisplayPowerRequest = new DisplayPowerRequest(); + mWakefulness = wakefulness; + mReady = false; + mSupportsSandman = true; + mLastWakeTime = eventTime; + mLastSleepTime = eventTime; } DisplayPowerRequest getDisplayPowerRequestLocked() { return mDisplayPowerRequest; } + long getLastWakeTimeLocked() { + return mLastWakeTime; + } + + long getLastSleepTimeLocked() { + return mLastSleepTime; + } + int getWakefulnessLocked() { return mWakefulness; } @@ -85,9 +111,19 @@ public class PowerGroup { * * @return {@code true} if the wakefulness value was changed; {@code false} otherwise. */ - boolean setWakefulnessLocked(int newWakefulness) { + boolean setWakefulnessLocked(int newWakefulness, long eventTime, int uid, int reason, int opUid, + String opPackageName, String details) { if (mWakefulness != newWakefulness) { + if (newWakefulness == WAKEFULNESS_AWAKE) { + setLastPowerOnTimeLocked(eventTime); + setIsPoweringOnLocked(true); + mLastWakeTime = eventTime; + } else if (isInteractive(mWakefulness) && !isInteractive(newWakefulness)) { + mLastSleepTime = eventTime; + } mWakefulness = newWakefulness; + mWakefulnessListener.onWakefulnessChangedLocked(mGroupId, mWakefulness, eventTime, + reason, uid, opUid, opPackageName, details); return true; } return false; @@ -105,8 +141,9 @@ public class PowerGroup { * Sets whether the displays of this group are all ready. * *

A display is ready if its reported - * {@link DisplayManagerInternal.DisplayPowerCallbacks#onStateChanged() actual state} matches - * its {@link DisplayManagerInternal#requestPowerState requested state}. + * {@link android.hardware.display.DisplayManagerInternal.DisplayPowerCallbacks#onStateChanged() + * actual state} matches its + * {@link android.hardware.display.DisplayManagerInternal#requestPowerState requested state}. * * @param isReady {@code true} if every display in the group is ready; otherwise {@code false}. * @return {@code true} if the ready state changed; otherwise {@code false}. @@ -148,6 +185,62 @@ public class PowerGroup { mIsSandmanSummoned = isSandmanSummoned; } + boolean dreamLocked(long eventTime, int uid) { + if (eventTime < mLastWakeTime || mWakefulness != WAKEFULNESS_AWAKE) { + return false; + } + + Trace.traceBegin(Trace.TRACE_TAG_POWER, "dreamPowerGroup" + getGroupId()); + try { + Slog.i(TAG, "Napping power group (groupId=" + getGroupId() + ", uid=" + uid + ")..."); + setSandmanSummonedLocked(true); + setWakefulnessLocked(WAKEFULNESS_DREAMING, eventTime, uid, /* reason= */0, + /* opUid= */ 0, /* opPackageName= */ null, /* details= */ null); + } finally { + Trace.traceEnd(Trace.TRACE_TAG_POWER); + } + return true; + } + + boolean dozeLocked(long eventTime, int uid, int reason) { + if (eventTime < getLastWakeTimeLocked() || !isInteractive(mWakefulness)) { + return false; + } + + Trace.traceBegin(Trace.TRACE_TAG_POWER, "powerOffDisplay"); + try { + reason = Math.min(PowerManager.GO_TO_SLEEP_REASON_MAX, + Math.max(reason, PowerManager.GO_TO_SLEEP_REASON_MIN)); + Slog.i(TAG, "Powering off display group due to " + + PowerManager.sleepReasonToString(reason) + " (groupId= " + getGroupId() + + ", uid= " + uid + ")..."); + + setSandmanSummonedLocked(/* isSandmanSummoned= */ true); + setWakefulnessLocked(WAKEFULNESS_DOZING, eventTime, uid, reason, /* opUid= */ 0, + /* opPackageName= */ null, /* details= */ null); + } finally { + Trace.traceEnd(Trace.TRACE_TAG_POWER); + } + return true; + } + + boolean sleepLocked(long eventTime, int uid, int reason) { + if (eventTime < mLastWakeTime || getWakefulnessLocked() == WAKEFULNESS_ASLEEP) { + return false; + } + + Trace.traceBegin(Trace.TRACE_TAG_POWER, "sleepPowerGroup"); + try { + Slog.i(TAG, "Sleeping power group (groupId=" + getGroupId() + ", uid=" + uid + ")..."); + setSandmanSummonedLocked(/* isSandmanSummoned= */ true); + setWakefulnessLocked(WAKEFULNESS_ASLEEP, eventTime, uid, reason, /* opUid= */0, + /* opPackageName= */ null, /* details= */ null); + } finally { + Trace.traceEnd(Trace.TRACE_TAG_POWER); + } + return true; + } + long getLastUserActivityTimeLocked() { return mLastUserActivityTime; } @@ -187,4 +280,22 @@ public class PowerGroup { public boolean supportsSandmanLocked() { return mSupportsSandman; } + + protected interface PowerGroupListener { + /** + * Informs the recipient about a wakefulness change of a {@link PowerGroup}. + * + * @param groupId The PowerGroup's id for which the wakefulness has changed. + * @param wakefulness The new wakefulness. + * @param eventTime The time of the event. + * @param reason The reason, any of {@link android.os.PowerManager.WakeReason} or + * {@link android.os.PowerManager.GoToSleepReason}. + * @param uid The uid which caused the wakefulness change. + * @param opUid The uid used for AppOps. + * @param opPackageName The Package name used for AppOps. + * @param details Details about the event. + */ + void onWakefulnessChangedLocked(int groupId, int wakefulness, long eventTime, int reason, + int uid, int opUid, String opPackageName, String details); + } } diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java index abfa016aef438..4185b2d9e4975 100644 --- a/services/core/java/com/android/server/power/PowerManagerService.java +++ b/services/core/java/com/android/server/power/PowerManagerService.java @@ -29,6 +29,7 @@ import static android.os.PowerManagerInternal.WAKEFULNESS_ASLEEP; import static android.os.PowerManagerInternal.WAKEFULNESS_AWAKE; import static android.os.PowerManagerInternal.WAKEFULNESS_DOZING; import static android.os.PowerManagerInternal.WAKEFULNESS_DREAMING; +import static android.os.PowerManagerInternal.isInteractive; import static android.os.PowerManagerInternal.wakefulnessToString; import static com.android.internal.util.LatencyTracker.ACTION_TURN_ON_SCREEN; @@ -338,12 +339,12 @@ public final class PowerManagerService extends SystemService private boolean mRequestWaitForNegativeProximity; // Timestamp of the last time the device was awoken or put to sleep. - private long mLastWakeTime; - private long mLastSleepTime; + private long mLastGlobalWakeTime; + private long mLastGlobalSleepTime; // Last reason the device went to sleep. - private @WakeReason int mLastWakeReason; - private int mLastSleepReason; + private @WakeReason int mLastGlobalWakeReason; + private int mLastGlobalSleepReason; // Timestamp of last time power boost interaction was sent. private long mLastInteractivePowerHintTime; @@ -352,6 +353,8 @@ public final class PowerManagerService extends SystemService private long mLastScreenBrightnessBoostTime; private boolean mScreenBrightnessBoostInProgress; + private final PowerGroupWakefulnessChangeListener mPowerGroupWakefulnessChangeListener; + // The suspend blocker used to keep the CPU alive while the device is booting. private final SuspendBlocker mBootingSuspendBlocker; @@ -397,6 +400,10 @@ public final class PowerManagerService extends SystemService // The current battery level percentage. private int mBatteryLevel; + // True if updatePowerStateLocked() is already in progress. + // TODO(b/215518989): Remove this once transactions are in place + private boolean mUpdatePowerStateInProgress; + /** * The lock that should be held when interacting with {@link #mEnhancedDischargeTimeElapsed}, * {@link #mLastEnhancedDischargeTimeUpdatedElapsed}, and @@ -640,6 +647,23 @@ public final class PowerManagerService extends SystemService // but the DreamService has not yet been told to start (it's an async process). private boolean mDozeStartInProgress; + private final class PowerGroupWakefulnessChangeListener implements + PowerGroup.PowerGroupListener { + @GuardedBy("mLock") + @Override + public void onWakefulnessChangedLocked(int groupId, int wakefulness, long eventTime, + int reason, int uid, int opUid, String opPackageName, String details) { + if (wakefulness == WAKEFULNESS_AWAKE) { + // Kick user activity to prevent newly awake group from timing out instantly. + userActivityNoUpdateLocked(mPowerGroups.get(groupId), eventTime, + PowerManager.USER_ACTIVITY_EVENT_OTHER, 0, uid); + } + mDirty |= DIRTY_DISPLAY_GROUP_WAKEFULNESS; + updateGlobalWakefulnessLocked(eventTime, reason, uid, opUid, opPackageName, details); + updatePowerStateLocked(); + } + } + private final class DisplayGroupPowerChangeListener implements DisplayManagerInternal.DisplayGroupListener { @@ -658,10 +682,12 @@ public final class PowerManagerService extends SystemService final boolean supportsSandman = groupId == Display.DEFAULT_DISPLAY_GROUP; final PowerGroup powerGroup = new PowerGroup( groupId, + mPowerGroupWakefulnessChangeListener, new DisplayPowerRequest(), - getGlobalWakefulnessLocked(), + WAKEFULNESS_AWAKE, /* ready= */ false, - supportsSandman); + supportsSandman, + mClock.uptimeMillis()); mPowerGroups.append(groupId, powerGroup); onPowerGroupEventLocked(DISPLAY_GROUP_ADDED, powerGroup); } @@ -992,6 +1018,8 @@ public final class PowerManagerService extends SystemService mInattentiveSleepWarningOverlayController = mInjector.createInattentiveSleepWarningController(); + mPowerGroupWakefulnessChangeListener = new PowerGroupWakefulnessChangeListener(); + // Save brightness values: // Get float values from config. // Store float if valid @@ -1144,10 +1172,10 @@ public final class PowerManagerService extends SystemService updatePowerStateLocked(); if (sQuiescent) { - sleepDisplayGroupNoUpdateLocked(mPowerGroups.get(Display.DEFAULT_DISPLAY_GROUP), + sleepPowerGroupLocked(mPowerGroups.get(Display.DEFAULT_DISPLAY_GROUP), mClock.uptimeMillis(), PowerManager.GO_TO_SLEEP_REASON_QUIESCENT, - PowerManager.GO_TO_SLEEP_FLAG_NO_DOZE, Process.SYSTEM_UID); + Process.SYSTEM_UID); } mContext.getSystemService(DeviceStateManager.class).registerCallback( @@ -1164,7 +1192,9 @@ public final class PowerManagerService extends SystemService mPolicy = getLocalService(WindowManagerPolicy.class); mBatteryManagerInternal = getLocalService(BatteryManagerInternal.class); mAttentionDetector.systemReady(mContext); - mPowerGroups.append(Display.DEFAULT_DISPLAY_GROUP, new PowerGroup()); + mPowerGroups.append(Display.DEFAULT_DISPLAY_GROUP, + new PowerGroup(WAKEFULNESS_AWAKE, mPowerGroupWakefulnessChangeListener, + mClock.uptimeMillis())); DisplayGroupPowerChangeListener displayGroupPowerChangeListener = new DisplayGroupPowerChangeListener(); mDisplayManagerInternal.registerDisplayGroupListener(displayGroupPowerChangeListener); @@ -1503,7 +1533,7 @@ public final class PowerManagerService extends SystemService opUid = wakeLock.mOwnerUid; } for (int idx = 0; idx < mPowerGroups.size(); idx++) { - wakeDisplayGroupNoUpdateLocked(mPowerGroups.valueAt(idx), mClock.uptimeMillis(), + wakePowerGroupLocked(mPowerGroups.valueAt(idx), mClock.uptimeMillis(), PowerManager.WAKE_REASON_APPLICATION, wakeLock.mTag, opUid, opPackageName, opUid); } @@ -1777,13 +1807,15 @@ public final class PowerManagerService extends SystemService @GuardedBy("mLock") private boolean userActivityNoUpdateLocked(final PowerGroup powerGroup, long eventTime, int event, int flags, int uid) { + final int groupId = powerGroup.getGroupId(); if (DEBUG_SPEW) { - Slog.d(TAG, "userActivityNoUpdateLocked: groupId=" + powerGroup.getGroupId() + Slog.d(TAG, "userActivityNoUpdateLocked: groupId=" + groupId + ", eventTime=" + eventTime + ", event=" + event + ", flags=0x" + Integer.toHexString(flags) + ", uid=" + uid); } - if (eventTime < mLastSleepTime || eventTime < mLastWakeTime || !mSystemReady) { + if (eventTime < powerGroup.getLastSleepTimeLocked() + || eventTime < powerGroup.getLastWakeTimeLocked() || !mSystemReady) { return false; } @@ -1801,7 +1833,6 @@ public final class PowerManagerService extends SystemService mUserInactiveOverrideFromWindowManager = false; mOverriddenTimeout = -1; } - final int wakefulness = powerGroup.getWakefulnessLocked(); if (wakefulness == WAKEFULNESS_ASLEEP || wakefulness == WAKEFULNESS_DOZING @@ -1846,42 +1877,33 @@ public final class PowerManagerService extends SystemService } } - private void wakeDisplayGroup(int groupId, long eventTime, @WakeReason int reason, - String details, int uid, String opPackageName, int opUid) { - synchronized (mLock) { - if (wakeDisplayGroupNoUpdateLocked(mPowerGroups.get(groupId), eventTime, reason, - details, uid, opPackageName, opUid)) { - updatePowerStateLocked(); - } - } - } - @GuardedBy("mLock") - private boolean wakeDisplayGroupNoUpdateLocked(final PowerGroup powerGroup, long eventTime, + private void wakePowerGroupLocked(final PowerGroup powerGroup, long eventTime, @WakeReason int reason, String details, int uid, String opPackageName, int opUid) { final int groupId = powerGroup.getGroupId(); if (DEBUG_SPEW) { - Slog.d(TAG, "wakeDisplayGroupNoUpdateLocked: eventTime=" + eventTime + Slog.d(TAG, "wakePowerGroupLocked: eventTime=" + eventTime + ", groupId=" + groupId + ", uid=" + uid); } - if (eventTime < mLastSleepTime || mForceSuspendActive || !mSystemReady) { - return false; + if (eventTime < powerGroup.getLastSleepTimeLocked() || mForceSuspendActive + || !mSystemReady) { + return; } - final int currentState = powerGroup.getWakefulnessLocked(); - if (currentState == WAKEFULNESS_AWAKE) { + final int currentWakefulness = powerGroup.getWakefulnessLocked(); + if (currentWakefulness == WAKEFULNESS_AWAKE) { if (!mBootCompleted && sQuiescent) { mDirty |= DIRTY_QUIESCENT; - return true; + updatePowerStateLocked(); } - return false; + return; } Trace.traceBegin(Trace.TRACE_TAG_POWER, "powerOnDisplay"); try { - Slog.i(TAG, "Powering on display group from" - + PowerManagerInternal.wakefulnessToString(currentState) + Slog.i(TAG, "Waking up power group from " + + PowerManagerInternal.wakefulnessToString(currentWakefulness) + " (groupId=" + groupId + ", uid=" + uid + ", reason=" + PowerManager.wakeReasonToString(reason) @@ -1892,183 +1914,96 @@ public final class PowerManagerService extends SystemService LatencyTracker.getInstance(mContext) .onActionStart(ACTION_TURN_ON_SCREEN, String.valueOf(groupId)); - setWakefulnessLocked(powerGroup, WAKEFULNESS_AWAKE, eventTime, uid, reason, opUid, + powerGroup.setWakefulnessLocked(WAKEFULNESS_AWAKE, eventTime, uid, reason, opUid, opPackageName, details); - powerGroup.setLastPowerOnTimeLocked(eventTime); - powerGroup.setIsPoweringOnLocked(true); } finally { Trace.traceEnd(Trace.TRACE_TAG_POWER); } - - return true; - } - - private void sleepDisplayGroup(int groupId, long eventTime, int reason, int flags, - int uid) { - synchronized (mLock) { - if (sleepDisplayGroupNoUpdateLocked(mPowerGroups.get(groupId), eventTime, reason, flags, - uid)) { - updatePowerStateLocked(); - } - } } @GuardedBy("mLock") - private boolean sleepDisplayGroupNoUpdateLocked(final PowerGroup powerGroup, long eventTime, - int reason, int flags, int uid) { + private boolean dreamPowerGroupLocked(PowerGroup powerGroup, long eventTime, int uid) { + if (DEBUG_SPEW) { + Slog.d(TAG, "dreamPowerGroup: groupId=" + powerGroup.getGroupId() + ", eventTime=" + + eventTime + ", uid=" + uid); + } + if (!mBootCompleted || !mSystemReady) { + return false; + } + return powerGroup.dreamLocked(eventTime, uid); + } + + @GuardedBy("mLock") + private boolean dozePowerGroupLocked(final PowerGroup powerGroup, long eventTime, + int reason, int uid) { if (DEBUG_SPEW) { Slog.d(TAG, "sleepDisplayGroupNoUpdateLocked: eventTime=" + eventTime + ", groupId=" + powerGroup.getGroupId() + ", reason=" + reason - + ", flags=" + flags + ", uid=" + uid); + + ", uid=" + uid); } - if (eventTime < mLastWakeTime - || !PowerManagerInternal.isInteractive(getWakefulnessLocked()) - || !mSystemReady - || !mBootCompleted) { + if (!mSystemReady || !mBootCompleted) { return false; } - final int wakefulness = powerGroup.getWakefulnessLocked(); - if (!PowerManagerInternal.isInteractive(wakefulness)) { - return false; - } - - Trace.traceBegin(Trace.TRACE_TAG_POWER, "powerOffDisplay"); - try { - reason = Math.min(PowerManager.GO_TO_SLEEP_REASON_MAX, - Math.max(reason, PowerManager.GO_TO_SLEEP_REASON_MIN)); - Slog.i(TAG, "Powering off display group due to " - + PowerManager.sleepReasonToString(reason) - + " (groupId= " + powerGroup.getGroupId() + ", uid= " + uid + ")..."); - - powerGroup.setSandmanSummonedLocked(/* isSandmanSummoned= */ true); - setWakefulnessLocked(powerGroup, WAKEFULNESS_DOZING, eventTime, uid, reason, - /* opUid= */ 0, /* opPackageName= */ null, /* details= */ null); - if ((flags & PowerManager.GO_TO_SLEEP_FLAG_NO_DOZE) != 0) { - reallySleepDisplayGroupNoUpdateLocked(powerGroup, eventTime, uid); - } - } finally { - Trace.traceEnd(Trace.TRACE_TAG_POWER); - } - return true; - } - - private void dreamDisplayGroup(int groupId, long eventTime, int uid) { - synchronized (mLock) { - if (dreamDisplayGroupNoUpdateLocked(mPowerGroups.get(groupId), eventTime, uid)) { - updatePowerStateLocked(); - } - } + return powerGroup.dozeLocked(eventTime, uid, reason); } @GuardedBy("mLock") - private boolean dreamDisplayGroupNoUpdateLocked(final PowerGroup powerGroup, long eventTime, + private boolean sleepPowerGroupLocked(final PowerGroup powerGroup, long eventTime, int reason, int uid) { if (DEBUG_SPEW) { - Slog.d(TAG, "dreamDisplayGroupNoUpdateLocked: eventTime=" + eventTime - + ", uid=" + uid); + Slog.d(TAG, "sleepPowerGroup: eventTime=" + eventTime + ", uid=" + uid); } - - if (eventTime < mLastWakeTime || getWakefulnessLocked() != WAKEFULNESS_AWAKE - || !mBootCompleted || !mSystemReady) { + if (!mBootCompleted || !mSystemReady) { return false; } - Trace.traceBegin(Trace.TRACE_TAG_POWER, "napDisplayGroup"); - try { - Slog.i(TAG, "Napping display group (groupId=" + powerGroup.getGroupId() + ", uid=" + uid - + ")..."); - - powerGroup.setSandmanSummonedLocked(/* isSandmanSummoned= */ true); - setWakefulnessLocked(powerGroup, WAKEFULNESS_DREAMING, eventTime, uid, - /* reason= */0, /* opUid= */ 0, /* opPackageName= */ null, /* details= */ null); - - } finally { - Trace.traceEnd(Trace.TRACE_TAG_POWER); - } - return true; - } - - @GuardedBy("mLock") - private boolean reallySleepDisplayGroupNoUpdateLocked(final PowerGroup powerGroup, - long eventTime, int uid) { - if (DEBUG_SPEW) { - Slog.d(TAG, "reallySleepDisplayGroupNoUpdateLocked: eventTime=" + eventTime - + ", uid=" + uid); - } - - if (eventTime < mLastWakeTime || getWakefulnessLocked() == WAKEFULNESS_ASLEEP - || !mBootCompleted || !mSystemReady - || powerGroup.getWakefulnessLocked() - == WAKEFULNESS_ASLEEP) { - return false; - } - - Trace.traceBegin(Trace.TRACE_TAG_POWER, "reallySleepDisplayGroup"); - try { - Slog.i(TAG, - "Sleeping display group (groupId=" + powerGroup.getGroupId() + ", uid=" + uid - + ")..."); - - setWakefulnessLocked(powerGroup, WAKEFULNESS_ASLEEP, eventTime, uid, - PowerManager.GO_TO_SLEEP_REASON_TIMEOUT, /* opUid= */ 0, - /* opPackageName= */ null, /* details= */ null); - } finally { - Trace.traceEnd(Trace.TRACE_TAG_POWER); - } - return true; + return powerGroup.sleepLocked(eventTime, uid, reason); } @VisibleForTesting @GuardedBy("mLock") void setWakefulnessLocked(int groupId, int wakefulness, long eventTime, int uid, int reason, int opUid, String opPackageName, String details) { - setWakefulnessLocked(mPowerGroups.get(groupId), wakefulness, eventTime, uid, reason, opUid, + mPowerGroups.get(groupId).setWakefulnessLocked(wakefulness, eventTime, uid, reason, opUid, opPackageName, details); } - @GuardedBy("mLock") - private void setWakefulnessLocked(final PowerGroup powerGroup, int wakefulness, long eventTime, - int uid, int reason, int opUid, String opPackageName, String details) { - if (powerGroup.setWakefulnessLocked(wakefulness)) { - mDirty |= DIRTY_DISPLAY_GROUP_WAKEFULNESS; - setGlobalWakefulnessLocked(getGlobalWakefulnessLocked(), - eventTime, reason, uid, opUid, opPackageName, details); - if (wakefulness == WAKEFULNESS_AWAKE) { - // Kick user activity to prevent newly awake group from timing out instantly. - userActivityNoUpdateLocked(powerGroup, eventTime, - PowerManager.USER_ACTIVITY_EVENT_OTHER, 0, uid); - } - } - } - @SuppressWarnings("deprecation") @GuardedBy("mLock") - private void setGlobalWakefulnessLocked(int wakefulness, long eventTime, int reason, int uid, + private void updateGlobalWakefulnessLocked(long eventTime, int reason, int uid, int opUid, String opPackageName, String details) { - if (getWakefulnessLocked() == wakefulness) { + int newWakefulness = recalculateGlobalWakefulnessLocked(); + int currentWakefulness = getGlobalWakefulnessLocked(); + if (currentWakefulness == newWakefulness) { return; } // Phase 1: Handle pre-wakefulness change bookkeeping. final String traceMethodName; - switch (wakefulness) { + switch (newWakefulness) { case WAKEFULNESS_ASLEEP: traceMethodName = "reallyGoToSleep"; Slog.i(TAG, "Sleeping (uid " + uid + ")..."); + // TODO(b/215518989): Remove this once transactions are in place + if (currentWakefulness != WAKEFULNESS_DOZING) { + // in case we are going to sleep without dozing before + mLastGlobalSleepTime = eventTime; + mLastGlobalSleepReason = reason; + } break; case WAKEFULNESS_AWAKE: traceMethodName = "wakeUp"; Slog.i(TAG, "Waking up from " - + PowerManagerInternal.wakefulnessToString(getWakefulnessLocked()) + + PowerManagerInternal.wakefulnessToString(currentWakefulness) + " (uid=" + uid + ", reason=" + PowerManager.wakeReasonToString(reason) + ", details=" + details + ")..."); - mLastWakeTime = eventTime; - mLastWakeReason = reason; + mLastGlobalWakeTime = eventTime; + mLastGlobalWakeReason = reason; break; case WAKEFULNESS_DREAMING: @@ -2081,13 +2016,13 @@ public final class PowerManagerService extends SystemService Slog.i(TAG, "Going to sleep due to " + PowerManager.sleepReasonToString(reason) + " (uid " + uid + ")..."); - mLastSleepTime = eventTime; - mLastSleepReason = reason; + mLastGlobalSleepTime = eventTime; + mLastGlobalSleepReason = reason; mDozeStartInProgress = true; break; default: - throw new IllegalArgumentException("Unexpected wakefulness: " + wakefulness); + throw new IllegalArgumentException("Unexpected wakefulness: " + newWakefulness); } Trace.traceBegin(Trace.TRACE_TAG_POWER, traceMethodName); @@ -2095,20 +2030,20 @@ public final class PowerManagerService extends SystemService // Phase 2: Handle wakefulness change and bookkeeping. // Under lock, invalidate before set ensures caches won't return stale values. mInjector.invalidateIsInteractiveCaches(); - mWakefulnessRaw = wakefulness; + mWakefulnessRaw = newWakefulness; mWakefulnessChanging = true; mDirty |= DIRTY_WAKEFULNESS; // This is only valid while we are in wakefulness dozing. Set to false otherwise. - mDozeStartInProgress &= (getWakefulnessLocked() == WAKEFULNESS_DOZING); + mDozeStartInProgress &= (newWakefulness == WAKEFULNESS_DOZING); if (mNotifier != null) { - mNotifier.onWakefulnessChangeStarted(wakefulness, reason, eventTime); + mNotifier.onWakefulnessChangeStarted(newWakefulness, reason, eventTime); } - mAttentionDetector.onWakefulnessChangeStarted(wakefulness); + mAttentionDetector.onWakefulnessChangeStarted(newWakefulness); // Phase 3: Handle post-wakefulness change bookkeeping. - switch (wakefulness) { + switch (newWakefulness) { case WAKEFULNESS_AWAKE: mNotifier.onWakeUp(reason, details, uid, opPackageName, opUid); if (sQuiescent) { @@ -2116,7 +2051,13 @@ public final class PowerManagerService extends SystemService } break; + case WAKEFULNESS_ASLEEP: + // fallthrough case WAKEFULNESS_DOZING: + if (!isInteractive(currentWakefulness)) { + // TODO(b/215518989): remove this once transactions are in place + break; + } // Report the number of wake locks that will be cleared by going to sleep. int numWakeLocksCleared = 0; final int numWakeLocks = mWakeLocks.size(); @@ -2140,7 +2081,7 @@ public final class PowerManagerService extends SystemService @VisibleForTesting @GuardedBy("mLock") - int getWakefulnessLocked() { + int getGlobalWakefulnessLocked() { return mWakefulnessRaw; } @@ -2163,10 +2104,9 @@ public final class PowerManagerService extends SystemService * */ @GuardedBy("mLock") - int getGlobalWakefulnessLocked() { - final int size = mPowerGroups.size(); + int recalculateGlobalWakefulnessLocked() { int deviceWakefulness = WAKEFULNESS_ASLEEP; - for (int i = 0; i < size; i++) { + for (int i = 0; i < mPowerGroups.size(); i++) { final int wakefulness = mPowerGroups.valueAt(i).getWakefulnessLocked(); if (wakefulness == WAKEFULNESS_AWAKE) { return WAKEFULNESS_AWAKE; @@ -2187,10 +2127,10 @@ public final class PowerManagerService extends SystemService void onPowerGroupEventLocked(int event, PowerGroup powerGroup) { final int groupId = powerGroup.getGroupId(); if (event == DisplayGroupPowerChangeListener.DISPLAY_GROUP_REMOVED) { - mPowerGroups.remove(groupId); + mPowerGroups.delete(groupId); } - final int oldWakefulness = getWakefulnessLocked(); - final int newWakefulness = getGlobalWakefulnessLocked(); + final int oldWakefulness = getGlobalWakefulnessLocked(); + final int newWakefulness = recalculateGlobalWakefulnessLocked(); if (event == DisplayGroupPowerChangeListener.DISPLAY_GROUP_ADDED && newWakefulness == WAKEFULNESS_AWAKE) { @@ -2215,13 +2155,9 @@ public final class PowerManagerService extends SystemService default: reason = 0; } - - setGlobalWakefulnessLocked( - getGlobalWakefulnessLocked(), - mClock.uptimeMillis(), reason, Process.SYSTEM_UID, Process.SYSTEM_UID, - mContext.getOpPackageName(), "groupId: " + groupId); + updateGlobalWakefulnessLocked(mClock.uptimeMillis(), reason, Process.SYSTEM_UID, + Process.SYSTEM_UID, mContext.getOpPackageName(), "groupId: " + groupId); } - mDirty |= DIRTY_DISPLAY_GROUP_WAKEFULNESS; updatePowerStateLocked(); } @@ -2243,15 +2179,15 @@ public final class PowerManagerService extends SystemService @GuardedBy("mLock") private void finishWakefulnessChangeIfNeededLocked() { if (mWakefulnessChanging && areAllDisplaysReadyLocked()) { - if (getWakefulnessLocked() == WAKEFULNESS_DOZING + if (getGlobalWakefulnessLocked() == WAKEFULNESS_DOZING && (mWakeLockSummary & WAKE_LOCK_DOZE) == 0) { return; // wait until dream has enabled dozing } else { // Doze wakelock acquired (doze started) or device is no longer dozing. mDozeStartInProgress = false; } - if (getWakefulnessLocked() == WAKEFULNESS_DOZING - || getWakefulnessLocked() == WAKEFULNESS_ASLEEP) { + if (getGlobalWakefulnessLocked() == WAKEFULNESS_DOZING + || getGlobalWakefulnessLocked() == WAKEFULNESS_ASLEEP) { logSleepTimeoutRecapturedLocked(); } mWakefulnessChanging = false; @@ -2282,7 +2218,7 @@ public final class PowerManagerService extends SystemService */ @GuardedBy("mLock") private void updatePowerStateLocked() { - if (!mSystemReady || mDirty == 0) { + if (!mSystemReady || mDirty == 0 || mUpdatePowerStateInProgress) { return; } if (!Thread.holdsLock(mLock)) { @@ -2290,6 +2226,7 @@ public final class PowerManagerService extends SystemService } Trace.traceBegin(Trace.TRACE_TAG_POWER, "updatePowerState"); + mUpdatePowerStateInProgress = true; try { // Phase 0: Basic state updates. updateIsPoweredLocked(mDirty); @@ -2332,6 +2269,7 @@ public final class PowerManagerService extends SystemService updateSuspendBlockerLocked(); } finally { Trace.traceEnd(Trace.TRACE_TAG_POWER); + mUpdatePowerStateInProgress = false; } } @@ -2397,7 +2335,7 @@ public final class PowerManagerService extends SystemService final long now = mClock.uptimeMillis(); if (shouldWakeUpWhenPluggedOrUnpluggedLocked(wasPowered, oldPlugType, dockedOnWirelessCharger)) { - wakeDisplayGroupNoUpdateLocked(mPowerGroups.get(Display.DEFAULT_DISPLAY_GROUP), + wakePowerGroupLocked(mPowerGroups.get(Display.DEFAULT_DISPLAY_GROUP), now, PowerManager.WAKE_REASON_PLUGGED_IN, "android.server.power:PLUGGED:" + mIsPowered, Process.SYSTEM_UID, mContext.getOpPackageName(), Process.SYSTEM_UID); @@ -2446,7 +2384,7 @@ public final class PowerManagerService extends SystemService } // If already dreaming and becoming powered, then don't wake. - if (mIsPowered && getWakefulnessLocked() == WAKEFULNESS_DREAMING) { + if (mIsPowered && getGlobalWakefulnessLocked() == WAKEFULNESS_DREAMING) { return false; } @@ -2456,7 +2394,7 @@ public final class PowerManagerService extends SystemService } // On Always On Display, SystemUI shows the charging indicator - if (mAlwaysOnEnabled && getWakefulnessLocked() == WAKEFULNESS_DOZING) { + if (mAlwaysOnEnabled && getGlobalWakefulnessLocked() == WAKEFULNESS_DOZING) { return false; } @@ -2540,24 +2478,23 @@ public final class PowerManagerService extends SystemService for (int idx = 0; idx < mPowerGroups.size(); idx++) { final PowerGroup powerGroup = mPowerGroups.valueAt(idx); - final int wakeLockSummary = adjustWakeLockSummary( - powerGroup.getWakefulnessLocked(), + final int wakeLockSummary = adjustWakeLockSummary(powerGroup.getWakefulnessLocked(), invalidGroupWakeLockSummary | powerGroup.getWakeLockSummaryLocked()); powerGroup.setWakeLockSummaryLocked(wakeLockSummary); } - mWakeLockSummary = adjustWakeLockSummary(getWakefulnessLocked(), + mWakeLockSummary = adjustWakeLockSummary(getGlobalWakefulnessLocked(), mWakeLockSummary); for (int i = 0; i < numProfiles; i++) { final ProfilePowerState profile = mProfilePowerState.valueAt(i); - profile.mWakeLockSummary = adjustWakeLockSummary(getWakefulnessLocked(), + profile.mWakeLockSummary = adjustWakeLockSummary(getGlobalWakefulnessLocked(), profile.mWakeLockSummary); } if (DEBUG_SPEW) { Slog.d(TAG, "updateWakeLockSummaryLocked: mWakefulness=" - + PowerManagerInternal.wakefulnessToString(getWakefulnessLocked()) + + PowerManagerInternal.wakefulnessToString(getGlobalWakefulnessLocked()) + ", mWakeLockSummary=0x" + Integer.toHexString(mWakeLockSummary)); } } @@ -2706,11 +2643,12 @@ public final class PowerManagerService extends SystemService int groupUserActivitySummary = 0; long groupNextTimeout = 0; final PowerGroup powerGroup = mPowerGroups.valueAt(idx); - if (powerGroup.getWakefulnessLocked() != WAKEFULNESS_ASLEEP) { + final int wakefulness = powerGroup.getWakefulnessLocked(); + if (wakefulness != WAKEFULNESS_ASLEEP) { final long lastUserActivityTime = powerGroup.getLastUserActivityTimeLocked(); final long lastUserActivityTimeNoChangeLights = powerGroup.getLastUserActivityTimeNoChangeLightsLocked(); - if (lastUserActivityTime >= mLastWakeTime) { + if (lastUserActivityTime >= powerGroup.getLastWakeTimeLocked()) { groupNextTimeout = lastUserActivityTime + screenOffTimeout - screenDimDuration; if (now < groupNextTimeout) { groupUserActivitySummary = USER_ACTIVITY_SCREEN_BRIGHT; @@ -2721,8 +2659,8 @@ public final class PowerManagerService extends SystemService } } } - if (groupUserActivitySummary == 0 - && lastUserActivityTimeNoChangeLights >= mLastWakeTime) { + if (groupUserActivitySummary == 0 && lastUserActivityTimeNoChangeLights + >= powerGroup.getLastWakeTimeLocked()) { groupNextTimeout = lastUserActivityTimeNoChangeLights + screenOffTimeout; if (now < groupNextTimeout) { final DisplayPowerRequest displayPowerRequest = @@ -2740,7 +2678,7 @@ public final class PowerManagerService extends SystemService if (sleepTimeout >= 0) { final long anyUserActivity = Math.max(lastUserActivityTime, lastUserActivityTimeNoChangeLights); - if (anyUserActivity >= mLastWakeTime) { + if (anyUserActivity >= powerGroup.getLastWakeTimeLocked()) { groupNextTimeout = anyUserActivity + sleepTimeout; if (now < groupNextTimeout) { groupUserActivitySummary = USER_ACTIVITY_SCREEN_DREAM; @@ -2786,7 +2724,7 @@ public final class PowerManagerService extends SystemService if (DEBUG_SPEW) { Slog.d(TAG, "updateUserActivitySummaryLocked: groupId=" + powerGroup.getGroupId() - + ", mWakefulness=" + wakefulnessToString(powerGroup.getWakefulnessLocked()) + + ", mWakefulness=" + wakefulnessToString(wakefulness) + ", mUserActivitySummary=0x" + Integer.toHexString( groupUserActivitySummary) + ", nextTimeout=" + TimeUtils.formatUptime(groupNextTimeout)); @@ -2884,7 +2822,7 @@ public final class PowerManagerService extends SystemService return false; } - if (getWakefulnessLocked() != WAKEFULNESS_AWAKE) { + if (getGlobalWakefulnessLocked() != WAKEFULNESS_AWAKE) { mInattentiveSleepWarningOverlayController.dismiss(false); return true; } else if (attentiveTimeout < 0 || isBeingKeptFromInattentiveSleepLocked() @@ -3024,14 +2962,13 @@ public final class PowerManagerService extends SystemService if (DEBUG) { Slog.i(TAG, "Going to sleep now due to long user inactivity"); } - changed = sleepDisplayGroupNoUpdateLocked(powerGroup, time, - PowerManager.GO_TO_SLEEP_REASON_INATTENTIVE, - PowerManager.GO_TO_SLEEP_FLAG_NO_DOZE, Process.SYSTEM_UID); + changed = sleepPowerGroupLocked(powerGroup, time, + PowerManager.GO_TO_SLEEP_REASON_INATTENTIVE, Process.SYSTEM_UID); } else if (shouldNapAtBedTimeLocked()) { - changed = dreamDisplayGroupNoUpdateLocked(powerGroup, time, Process.SYSTEM_UID); + changed = dreamPowerGroupLocked(powerGroup, time, Process.SYSTEM_UID); } else { - changed = sleepDisplayGroupNoUpdateLocked(powerGroup, time, - PowerManager.GO_TO_SLEEP_REASON_TIMEOUT, 0, Process.SYSTEM_UID); + changed = dozePowerGroupLocked(powerGroup, time, + PowerManager.GO_TO_SLEEP_REASON_TIMEOUT, Process.SYSTEM_UID); } } return changed; @@ -3228,25 +3165,27 @@ public final class PowerManagerService extends SystemService // Dream has ended or will be stopped. Update the power state. if (isItBedTimeYetLocked(powerGroup)) { - final int flags = isAttentiveTimeoutExpired(powerGroup, now) - ? PowerManager.GO_TO_SLEEP_FLAG_NO_DOZE : 0; - sleepDisplayGroupNoUpdateLocked(powerGroup, now, - PowerManager.GO_TO_SLEEP_REASON_TIMEOUT, flags, Process.SYSTEM_UID); + if (isAttentiveTimeoutExpired(powerGroup, now)) { + sleepPowerGroupLocked(powerGroup, now, + PowerManager.GO_TO_SLEEP_REASON_TIMEOUT, Process.SYSTEM_UID); + } else { + dozePowerGroupLocked(powerGroup, now, + PowerManager.GO_TO_SLEEP_REASON_TIMEOUT, Process.SYSTEM_UID); + } } else { - wakeDisplayGroupNoUpdateLocked(powerGroup, now, + wakePowerGroupLocked(powerGroup, now, PowerManager.WAKE_REASON_UNKNOWN, "android.server.power:DREAM_FINISHED", Process.SYSTEM_UID, mContext.getOpPackageName(), Process.SYSTEM_UID); } - updatePowerStateLocked(); } else if (wakefulness == WAKEFULNESS_DOZING) { if (isDreaming) { return; // continue dozing } // Doze has ended or will be stopped. Update the power state. - reallySleepDisplayGroupNoUpdateLocked(powerGroup, now, Process.SYSTEM_UID); - updatePowerStateLocked(); + sleepPowerGroupLocked(powerGroup, now, PowerManager.GO_TO_SLEEP_REASON_TIMEOUT, + Process.SYSTEM_UID); } } @@ -3263,7 +3202,7 @@ public final class PowerManagerService extends SystemService private boolean canDreamLocked(final PowerGroup powerGroup) { final DisplayPowerRequest displayPowerRequest = powerGroup.getDisplayPowerRequestLocked(); if (!mBootCompleted - || getWakefulnessLocked() != WAKEFULNESS_DREAMING + || getGlobalWakefulnessLocked() != WAKEFULNESS_DREAMING || !mDreamsSupportedConfig || !mDreamsEnabledSetting || !displayPowerRequest.isBrightOrDim() @@ -3294,7 +3233,7 @@ public final class PowerManagerService extends SystemService @GuardedBy("mLock") private boolean canDozeLocked() { // TODO (b/175764708): Support per-display doze. - return getWakefulnessLocked() == WAKEFULNESS_DOZING; + return getGlobalWakefulnessLocked() == WAKEFULNESS_DOZING; } /** @@ -3375,15 +3314,15 @@ public final class PowerManagerService extends SystemService final boolean ready = mDisplayManagerInternal.requestPowerState(groupId, displayPowerRequest, mRequestWaitForNegativeProximity); - mNotifier.onScreenPolicyUpdate(groupId, displayPowerRequest.policy); + mNotifier.onScreenPolicyUpdate(powerGroup.getGroupId(), displayPowerRequest.policy); + int wakefulness = powerGroup.getWakefulnessLocked(); if (DEBUG_SPEW) { Slog.d(TAG, "updateDisplayPowerStateLocked: displayReady=" + ready + ", groupId=" + groupId + ", policy=" + policyToString(displayPowerRequest.policy) + ", mWakefulness=" - + PowerManagerInternal.wakefulnessToString( - powerGroup.getWakefulnessLocked()) + + PowerManagerInternal.wakefulnessToString(wakefulness) + ", mWakeLockSummary=0x" + Integer.toHexString( powerGroup.getWakeLockSummaryLocked()) + ", mUserActivitySummary=0x" + Integer.toHexString( @@ -3401,7 +3340,7 @@ public final class PowerManagerService extends SystemService final boolean displayReadyStateChanged = powerGroup.setReadyLocked(ready); final boolean poweringOn = powerGroup.isPoweringOnLocked(); if (ready && displayReadyStateChanged && poweringOn - && powerGroup.getWakefulnessLocked() == WAKEFULNESS_AWAKE) { + && wakefulness == WAKEFULNESS_AWAKE) { powerGroup.setIsPoweringOnLocked(false); LatencyTracker.getInstance(mContext).onActionEnd(ACTION_TURN_ON_SCREEN); Trace.asyncTraceEnd(Trace.TRACE_TAG_POWER, TRACE_SCREEN_ON, groupId); @@ -3424,7 +3363,7 @@ public final class PowerManagerService extends SystemService if (mScreenBrightnessBoostInProgress) { final long now = mClock.uptimeMillis(); mHandler.removeMessages(MSG_SCREEN_BRIGHTNESS_BOOST_TIMEOUT); - if (mLastScreenBrightnessBoostTime > mLastSleepTime) { + if (mLastScreenBrightnessBoostTime > mLastGlobalSleepTime) { final long boostTimeout = mLastScreenBrightnessBoostTime + SCREEN_BRIGHTNESS_BOOST_TIMEOUT; if (boostTimeout > now) { @@ -3656,7 +3595,7 @@ public final class PowerManagerService extends SystemService // Here we wait for mWakefulnessChanging to become false since the wakefulness // transition to DOZING isn't considered "changed" until the doze wake lock is // acquired. - if (getWakefulnessLocked() == WAKEFULNESS_DOZING && mDozeStartInProgress) { + if (getGlobalWakefulnessLocked() == WAKEFULNESS_DOZING && mDozeStartInProgress) { return true; } @@ -3721,7 +3660,7 @@ public final class PowerManagerService extends SystemService private boolean isInteractiveInternal() { synchronized (mLock) { - return PowerManagerInternal.isInteractive(getWakefulnessLocked()); + return PowerManagerInternal.isInteractive(getGlobalWakefulnessLocked()); } } @@ -4092,7 +4031,7 @@ public final class PowerManagerService extends SystemService private void boostScreenBrightnessInternal(long eventTime, int uid) { synchronized (mLock) { - if (!mSystemReady || getWakefulnessLocked() == WAKEFULNESS_ASLEEP + if (!mSystemReady || getGlobalWakefulnessLocked() == WAKEFULNESS_ASLEEP || eventTime < mLastScreenBrightnessBoostTime) { return; } @@ -4225,14 +4164,9 @@ public final class PowerManagerService extends SystemService synchronized (mLock) { mForceSuspendActive = true; // Place the system in an non-interactive state - boolean updatePowerState = false; for (int idx = 0; idx < mPowerGroups.size(); idx++) { - updatePowerState |= sleepDisplayGroupNoUpdateLocked(mPowerGroups.valueAt(idx), - mClock.uptimeMillis(), PowerManager.GO_TO_SLEEP_REASON_FORCE_SUSPEND, - PowerManager.GO_TO_SLEEP_FLAG_NO_DOZE, uid); - } - if (updatePowerState) { - updatePowerStateLocked(); + sleepPowerGroupLocked(mPowerGroups.valueAt(idx), mClock.uptimeMillis(), + PowerManager.GO_TO_SLEEP_REASON_FORCE_SUSPEND, uid); } // Disable all the partial wake locks as well @@ -4331,7 +4265,7 @@ public final class PowerManagerService extends SystemService mConstants.dump(pw); pw.println(" mDirty=0x" + Integer.toHexString(mDirty)); pw.println(" mWakefulness=" - + PowerManagerInternal.wakefulnessToString(getWakefulnessLocked())); + + PowerManagerInternal.wakefulnessToString(getGlobalWakefulnessLocked())); pw.println(" mWakefulnessChanging=" + mWakefulnessChanging); pw.println(" mIsPowered=" + mIsPowered); pw.println(" mPlugType=" + mPlugType); @@ -4382,9 +4316,10 @@ public final class PowerManagerService extends SystemService pw.println(" mDeviceIdleMode=" + mDeviceIdleMode); pw.println(" mDeviceIdleWhitelist=" + Arrays.toString(mDeviceIdleWhitelist)); pw.println(" mDeviceIdleTempWhitelist=" + Arrays.toString(mDeviceIdleTempWhitelist)); - pw.println(" mLastWakeTime=" + TimeUtils.formatUptime(mLastWakeTime)); - pw.println(" mLastSleepTime=" + TimeUtils.formatUptime(mLastSleepTime)); - pw.println(" mLastSleepReason=" + PowerManager.sleepReasonToString(mLastSleepReason)); + pw.println(" mLastWakeTime=" + TimeUtils.formatUptime(mLastGlobalWakeTime)); + pw.println(" mLastSleepTime=" + TimeUtils.formatUptime(mLastGlobalSleepTime)); + pw.println(" mLastSleepReason=" + PowerManager.sleepReasonToString( + mLastGlobalSleepReason)); pw.println(" mLastInteractivePowerHintTime=" + TimeUtils.formatUptime(mLastInteractivePowerHintTime)); pw.println(" mLastScreenBrightnessBoostTime=" @@ -4565,7 +4500,7 @@ public final class PowerManagerService extends SystemService synchronized (mLock) { mConstants.dumpProto(proto); proto.write(PowerManagerServiceDumpProto.DIRTY, mDirty); - proto.write(PowerManagerServiceDumpProto.WAKEFULNESS, getWakefulnessLocked()); + proto.write(PowerManagerServiceDumpProto.WAKEFULNESS, getGlobalWakefulnessLocked()); proto.write(PowerManagerServiceDumpProto.IS_WAKEFULNESS_CHANGING, mWakefulnessChanging); proto.write(PowerManagerServiceDumpProto.IS_POWERED, mIsPowered); proto.write(PowerManagerServiceDumpProto.PLUG_TYPE, mPlugType); @@ -4664,8 +4599,8 @@ public final class PowerManagerService extends SystemService proto.write(PowerManagerServiceDumpProto.DEVICE_IDLE_TEMP_WHITELIST, id); } - proto.write(PowerManagerServiceDumpProto.LAST_WAKE_TIME_MS, mLastWakeTime); - proto.write(PowerManagerServiceDumpProto.LAST_SLEEP_TIME_MS, mLastSleepTime); + proto.write(PowerManagerServiceDumpProto.LAST_WAKE_TIME_MS, mLastGlobalWakeTime); + proto.write(PowerManagerServiceDumpProto.LAST_SLEEP_TIME_MS, mLastGlobalSleepTime); proto.write( PowerManagerServiceDumpProto.LAST_INTERACTIVE_POWER_HINT_TIME_MS, mLastInteractivePowerHintTime); @@ -5505,8 +5440,10 @@ public final class PowerManagerService extends SystemService final int uid = Binder.getCallingUid(); final long ident = Binder.clearCallingIdentity(); try { - wakeDisplayGroup(Display.DEFAULT_DISPLAY_GROUP, eventTime, reason, details, uid, - opPackageName, uid); + synchronized (mLock) { + wakePowerGroupLocked(mPowerGroups.get(Display.DEFAULT_DISPLAY_GROUP), eventTime, + reason, details, uid, opPackageName, uid); + } } finally { Binder.restoreCallingIdentity(ident); } @@ -5524,7 +5461,14 @@ public final class PowerManagerService extends SystemService final int uid = Binder.getCallingUid(); final long ident = Binder.clearCallingIdentity(); try { - sleepDisplayGroup(Display.DEFAULT_DISPLAY_GROUP, eventTime, reason, flags, uid); + synchronized (mLock) { + PowerGroup defaultPowerGroup = mPowerGroups.get(Display.DEFAULT_DISPLAY_GROUP); + if ((flags & PowerManager.GO_TO_SLEEP_FLAG_NO_DOZE) != 0) { + sleepPowerGroupLocked(defaultPowerGroup, eventTime, reason, uid); + } else { + dozePowerGroupLocked(defaultPowerGroup, eventTime, reason, uid); + } + } } finally { Binder.restoreCallingIdentity(ident); } @@ -5542,7 +5486,10 @@ public final class PowerManagerService extends SystemService final int uid = Binder.getCallingUid(); final long ident = Binder.clearCallingIdentity(); try { - dreamDisplayGroup(Display.DEFAULT_DISPLAY_GROUP, eventTime, uid); + synchronized (mLock) { + dreamPowerGroupLocked(mPowerGroups.get(Display.DEFAULT_DISPLAY_GROUP), + eventTime, uid); + } } finally { Binder.restoreCallingIdentity(ident); } @@ -6181,13 +6128,15 @@ public final class PowerManagerService extends SystemService private int getLastSleepReasonInternal() { synchronized (mLock) { - return mLastSleepReason; + return mLastGlobalSleepReason; } } + @VisibleForTesting private PowerManager.WakeData getLastWakeupInternal() { synchronized (mLock) { - return new WakeData(mLastWakeTime, mLastWakeReason, mLastWakeTime - mLastSleepTime); + return new WakeData(mLastGlobalWakeTime, mLastGlobalWakeReason, + mLastGlobalWakeTime - mLastGlobalSleepTime); } } diff --git a/services/tests/servicestests/src/com/android/server/power/PowerGroupTest.java b/services/tests/servicestests/src/com/android/server/power/PowerGroupTest.java new file mode 100644 index 0000000000000..c59b58d5c4d29 --- /dev/null +++ b/services/tests/servicestests/src/com/android/server/power/PowerGroupTest.java @@ -0,0 +1,129 @@ +/* + * Copyright (C) 2022 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.server.power; + + +import static android.os.PowerManager.GO_TO_SLEEP_REASON_APPLICATION; +import static android.os.PowerManager.GO_TO_SLEEP_REASON_DEVICE_ADMIN; +import static android.os.PowerManager.GO_TO_SLEEP_REASON_TIMEOUT; +import static android.os.PowerManager.WAKE_REASON_GESTURE; +import static android.os.PowerManagerInternal.WAKEFULNESS_ASLEEP; +import static android.os.PowerManagerInternal.WAKEFULNESS_AWAKE; +import static android.os.PowerManagerInternal.WAKEFULNESS_DOZING; +import static android.os.PowerManagerInternal.WAKEFULNESS_DREAMING; + +import static com.google.common.truth.Truth.assertThat; + +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.ArgumentMatchers.isNull; +import static org.mockito.Mockito.verify; + +import android.hardware.display.DisplayManagerInternal.DisplayPowerRequest; + +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +/** + * Tests for {@link com.android.server.power.PowerGroup}. + * + * Build/Install/Run: + * atest FrameworksServicesTests:PowerManagerServiceTest + */ +public class PowerGroupTest { + + private static final int GROUP_ID = 0; + private static final long TIMESTAMP_CREATE = 1; + private static final long TIMESTAMP1 = 999; + private static final long TIMESTAMP2 = TIMESTAMP1 + 10; + private static final long TIMESTAMP3 = TIMESTAMP2 + 10; + private static final int UID = 11; + + private PowerGroup mPowerGroup; + @Mock + private PowerGroup.PowerGroupListener mWakefulnessCallbackMock; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + mPowerGroup = new PowerGroup(GROUP_ID, mWakefulnessCallbackMock, new DisplayPowerRequest(), + WAKEFULNESS_AWAKE, /* ready= */ true, /* supportsSandman= */true, TIMESTAMP_CREATE); + } + + @Test + public void testDreamPowerGroupTriggersOnWakefulnessChangedCallback() { + mPowerGroup.dreamLocked(TIMESTAMP1, UID); + verify(mWakefulnessCallbackMock).onWakefulnessChangedLocked(eq(GROUP_ID), + eq(WAKEFULNESS_DREAMING), eq(TIMESTAMP1), eq(GO_TO_SLEEP_REASON_APPLICATION), + eq(UID), /* opUid= */anyInt(), /* opPackageName= */ isNull(), /* details= */ + isNull()); + } + + @Test + public void testLastWakeAndSleepTimeIsUpdated() { + assertThat(mPowerGroup.getLastWakeTimeLocked()).isEqualTo(TIMESTAMP_CREATE); + assertThat(mPowerGroup.getLastSleepTimeLocked()).isEqualTo(TIMESTAMP_CREATE); + + // Verify that the transition to WAKEFULNESS_DOZING updates the last sleep time + String details = "PowerGroup1 Timeout"; + mPowerGroup.setWakefulnessLocked(WAKEFULNESS_DOZING, TIMESTAMP1, UID, + GO_TO_SLEEP_REASON_TIMEOUT, /* opUid= */ 0, /* opPackageName= */ null, details); + assertThat(mPowerGroup.getLastSleepTimeLocked()).isEqualTo(TIMESTAMP1); + assertThat(mPowerGroup.getLastWakeTimeLocked()).isEqualTo(TIMESTAMP_CREATE); + assertThat(mPowerGroup.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_DOZING); + verify(mWakefulnessCallbackMock).onWakefulnessChangedLocked(eq(GROUP_ID), + eq(WAKEFULNESS_DOZING), eq(TIMESTAMP1), eq(GO_TO_SLEEP_REASON_TIMEOUT), + eq(UID), /* opUid= */anyInt(), /* opPackageName= */ isNull(), eq(details)); + + // Verify that the transition to WAKEFULNESS_ASLEEP after dozing does not update the last + // wake or sleep time + mPowerGroup.setWakefulnessLocked(WAKEFULNESS_ASLEEP, TIMESTAMP2, UID, + GO_TO_SLEEP_REASON_DEVICE_ADMIN, /* opUid= */ 0, /* opPackageName= */ null, + details); + assertThat(mPowerGroup.getLastSleepTimeLocked()).isEqualTo(TIMESTAMP1); + assertThat(mPowerGroup.getLastWakeTimeLocked()).isEqualTo(TIMESTAMP_CREATE); + assertThat(mPowerGroup.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_ASLEEP); + verify(mWakefulnessCallbackMock).onWakefulnessChangedLocked(eq(GROUP_ID), + eq(WAKEFULNESS_ASLEEP), eq(TIMESTAMP2), eq(GO_TO_SLEEP_REASON_DEVICE_ADMIN), + eq(UID), /* opUid= */anyInt(), /* opPackageName= */ isNull(), eq(details)); + + // Verify that waking up the power group only updates the last wake time + details = "PowerGroup1 Gesture"; + mPowerGroup.setWakefulnessLocked(WAKEFULNESS_AWAKE, TIMESTAMP2, UID, + WAKE_REASON_GESTURE, /* opUid= */ 0, /* opPackageName= */ null, details); + assertThat(mPowerGroup.getLastWakeTimeLocked()).isEqualTo(TIMESTAMP2); + assertThat(mPowerGroup.getLastSleepTimeLocked()).isEqualTo(TIMESTAMP1); + assertThat(mPowerGroup.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE); + verify(mWakefulnessCallbackMock).onWakefulnessChangedLocked(eq(GROUP_ID), + eq(WAKEFULNESS_AWAKE), eq(TIMESTAMP2), eq(WAKE_REASON_GESTURE), + eq(UID), /* opUid= */ anyInt(), /* opPackageName= */ isNull(), eq(details)); + + // Verify that a transition to WAKEFULNESS_ASLEEP from an interactive state updates the last + // sleep time + mPowerGroup.setWakefulnessLocked(WAKEFULNESS_ASLEEP, TIMESTAMP3, UID, + GO_TO_SLEEP_REASON_DEVICE_ADMIN, /* opUid= */ 0, /* opPackageName= */ null, + details); + assertThat(mPowerGroup.getLastSleepTimeLocked()).isEqualTo(TIMESTAMP3); + assertThat(mPowerGroup.getLastWakeTimeLocked()).isEqualTo(TIMESTAMP2); + assertThat(mPowerGroup.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_ASLEEP); + verify(mWakefulnessCallbackMock).onWakefulnessChangedLocked(eq(GROUP_ID), + eq(WAKEFULNESS_ASLEEP), eq(TIMESTAMP3), eq(GO_TO_SLEEP_REASON_DEVICE_ADMIN), + eq(UID), /* opUid= */anyInt(), /* opPackageName= */ isNull(), eq(details)); + } +} 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 c832a3ed49b6b..d35c679c18bd4 100644 --- a/services/tests/servicestests/src/com/android/server/power/PowerManagerServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/power/PowerManagerServiceTest.java @@ -111,6 +111,7 @@ import java.util.concurrent.atomic.AtomicReference; * Build/Install/Run: * atest FrameworksServicesTests:PowerManagerServiceTest */ +@SuppressWarnings("GuardedBy") public class PowerManagerServiceTest { private static final String SYSTEM_PROPERTY_QUIESCENT = "ro.boot.quiescent"; private static final String SYSTEM_PROPERTY_REBOOT_REASON = "sys.boot.reason"; @@ -437,7 +438,7 @@ public class PowerManagerServiceTest { @Test public void testWakefulnessAwake_InitialValue() { createService(); - assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE); + assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE); } @Test @@ -445,12 +446,12 @@ public class PowerManagerServiceTest { createService(); // Start with AWAKE state startSystem(); - assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE); + assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE); // Take a nap and verify. mService.getBinderServiceInstance().goToSleep(mClock.now(), PowerManager.GO_TO_SLEEP_REASON_APPLICATION, PowerManager.GO_TO_SLEEP_FLAG_NO_DOZE); - assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_ASLEEP); + assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_ASLEEP); } @Test @@ -467,21 +468,21 @@ public class PowerManagerServiceTest { int flags = PowerManager.FULL_WAKE_LOCK; mService.getBinderServiceInstance().acquireWakeLock(token, flags, tag, packageName, null /* workSource */, null /* historyTag */, Display.INVALID_DISPLAY); - assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_ASLEEP); + assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_ASLEEP); mService.getBinderServiceInstance().releaseWakeLock(token, 0 /* flags */); // Ensure that the flag does *NOT* work with a partial wake lock. flags = PowerManager.PARTIAL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP; mService.getBinderServiceInstance().acquireWakeLock(token, flags, tag, packageName, null /* workSource */, null /* historyTag */, Display.INVALID_DISPLAY); - assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_ASLEEP); + assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_ASLEEP); mService.getBinderServiceInstance().releaseWakeLock(token, 0 /* flags */); // Verify that flag forces a wakeup when paired to a FULL_WAKE_LOCK flags = PowerManager.FULL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP; mService.getBinderServiceInstance().acquireWakeLock(token, flags, tag, packageName, null /* workSource */, null /* historyTag */, Display.INVALID_DISPLAY); - assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE); + assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE); mService.getBinderServiceInstance().releaseWakeLock(token, 0 /* flags */); } @@ -492,7 +493,7 @@ public class PowerManagerServiceTest { forceSleep(); mService.getBinderServiceInstance().wakeUp(mClock.now(), PowerManager.WAKE_REASON_UNKNOWN, "testing IPowerManager.wakeUp()", "pkg.name"); - assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE); + assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE); } /** @@ -511,7 +512,7 @@ public class PowerManagerServiceTest { .thenReturn(false); mService.readConfigurationLocked(); setPluggedIn(true); - assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_ASLEEP); + assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_ASLEEP); when(mResourcesSpy.getBoolean(com.android.internal.R.bool.config_unplugTurnsOnScreen)) .thenReturn(true); mService.readConfigurationLocked(); @@ -526,20 +527,20 @@ public class PowerManagerServiceTest { when(mWirelessChargerDetectorMock.update(true /* isPowered */, BatteryManager.BATTERY_PLUGGED_WIRELESS)).thenReturn(false); setPluggedIn(true); - assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_ASLEEP); + assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_ASLEEP); // Test 3: // Do not wake up if the phone is being REMOVED from a wireless charger when(mBatteryManagerInternalMock.getPlugType()).thenReturn(0); setPluggedIn(false); - assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_ASLEEP); + assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_ASLEEP); // Test 4: // Do not wake if we are dreaming. forceAwake(); // Needs to be awake first before it can dream. forceDream(); setPluggedIn(true); - assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_DREAMING); + assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_DREAMING); forceSleep(); // Test 5: @@ -552,7 +553,7 @@ public class PowerManagerServiceTest { com.android.internal.R.bool.config_allowTheaterModeWakeFromUnplug)) .thenReturn(false); setPluggedIn(false); - assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_ASLEEP); + assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_ASLEEP); Settings.Global.putInt( mContextSpy.getContentResolver(), Settings.Global.THEATER_MODE_ON, 0); mUserSwitchedReceiver.onReceive(mContextSpy, new Intent(Intent.ACTION_USER_SWITCHED)); @@ -565,14 +566,14 @@ public class PowerManagerServiceTest { forceAwake(); forceDozing(); setPluggedIn(true); - assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_DOZING); + assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_DOZING); // Test 7: // Finally, take away all the factors above and ensure the device wakes up! forceAwake(); forceSleep(); setPluggedIn(false); - assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE); + assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE); } @Test @@ -580,12 +581,12 @@ public class PowerManagerServiceTest { createService(); // Start with AWAKE state startSystem(); - assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE); + assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE); // Take a nap and verify. mService.getBinderServiceInstance().goToSleep(mClock.now(), PowerManager.GO_TO_SLEEP_REASON_APPLICATION, 0); - assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_DOZING); + assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_DOZING); } @Test @@ -616,12 +617,12 @@ public class PowerManagerServiceTest { mService.onBootPhase(SystemService.PHASE_BOOT_COMPLETED); // Verify that we start awake - assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE); + assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE); // Grab the wakefulness value when PowerManager finally calls into the // native component to actually perform the suspend. when(mNativeWrapperMock.nativeForceSuspend()).then(inv -> { - assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_ASLEEP); + assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_ASLEEP); return true; }); @@ -629,7 +630,7 @@ public class PowerManagerServiceTest { assertThat(retval).isTrue(); // Still asleep when the function returns. - assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_ASLEEP); + assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_ASLEEP); } @Test @@ -662,7 +663,7 @@ public class PowerManagerServiceTest { mService.onBootPhase(SystemService.PHASE_BOOT_COMPLETED); // Verify that we start awake - assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE); + assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE); // Create a wakelock mService.getBinderServiceInstance().acquireWakeLock(new Binder(), flags, tag, pkg, @@ -718,7 +719,7 @@ public class PowerManagerServiceTest { // Start with AWAKE state startSystem(); - assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE); + assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE); assertTrue(isAcquired[0]); // Take a nap and verify we no longer hold the blocker @@ -728,7 +729,7 @@ public class PowerManagerServiceTest { when(mDreamManagerInternalMock.isDreaming()).thenReturn(true); mService.getBinderServiceInstance().goToSleep(mClock.now(), PowerManager.GO_TO_SLEEP_REASON_APPLICATION, 0); - assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_DOZING); + assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_DOZING); assertFalse(isAcquired[0]); // Override the display state by DreamManager and verify is reacquires the blocker. @@ -841,9 +842,9 @@ public class PowerManagerServiceTest { verify(mInattentiveSleepWarningControllerMock, atLeastOnce()).show(); when(mInattentiveSleepWarningControllerMock.isShown()).thenReturn(true); advanceTime(70); - assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_ASLEEP); + assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_ASLEEP); forceAwake(); - assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE); + assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE); verify(mInattentiveSleepWarningControllerMock, atLeastOnce()).dismiss(false); } @@ -862,7 +863,7 @@ public class PowerManagerServiceTest { createService(); startSystem(); advanceTime(20); - assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_ASLEEP); + assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_ASLEEP); assertThat(mService.getBinderServiceInstance().getLastSleepReason()).isEqualTo( PowerManager.GO_TO_SLEEP_REASON_INATTENTIVE); } @@ -882,9 +883,9 @@ public class PowerManagerServiceTest { PowerManager.SCREEN_BRIGHT_WAKE_LOCK, tag, pkg, null /* workSource */, null /* historyTag */, Display.INVALID_DISPLAY); - assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE); + assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE); advanceTime(60); - assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_ASLEEP); + assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_ASLEEP); assertThat(mService.getBinderServiceInstance().getLastSleepReason()).isEqualTo( PowerManager.GO_TO_SLEEP_REASON_INATTENTIVE); } @@ -912,7 +913,7 @@ public class PowerManagerServiceTest { mService.getBinderServiceInstance().releaseWakeLock(token, 0 /* flags */); advanceTime(520); - assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_ASLEEP); + assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_ASLEEP); assertThat(mService.getBinderServiceInstance().getLastSleepReason()).isEqualTo( PowerManager.GO_TO_SLEEP_REASON_INATTENTIVE); } @@ -934,7 +935,7 @@ public class PowerManagerServiceTest { PowerManager.USER_ACTIVITY_FLAG_NO_CHANGE_LIGHTS); advanceTime(520); - assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_ASLEEP); + assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_ASLEEP); assertThat(mService.getBinderServiceInstance().getLastSleepReason()).isEqualTo( PowerManager.GO_TO_SLEEP_REASON_INATTENTIVE); } @@ -955,7 +956,7 @@ public class PowerManagerServiceTest { PowerManager.USER_ACTIVITY_EVENT_OTHER, 0 /* flags */); advanceTime(520); - assertThat(mService.getWakefulnessLocked()).isNotEqualTo(WAKEFULNESS_ASLEEP); + assertThat(mService.getGlobalWakefulnessLocked()).isNotEqualTo(WAKEFULNESS_ASLEEP); } @Test @@ -984,14 +985,14 @@ public class PowerManagerServiceTest { PowerManager.SCREEN_BRIGHT_WAKE_LOCK, tag, pkg, null /* workSource */, null /* historyTag */, Display.DEFAULT_DISPLAY); - assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE); + assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE); assertThat(mService.getWakefulnessLocked(Display.DEFAULT_DISPLAY_GROUP)).isEqualTo( WAKEFULNESS_AWAKE); assertThat(mService.getWakefulnessLocked(nonDefaultDisplayGroupId)).isEqualTo( WAKEFULNESS_AWAKE); advanceTime(15000); - assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE); + assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE); assertThat(mService.getWakefulnessLocked(Display.DEFAULT_DISPLAY_GROUP)).isEqualTo( WAKEFULNESS_AWAKE); assertThat(mService.getWakefulnessLocked(nonDefaultDisplayGroupId)).isEqualTo( @@ -1024,14 +1025,14 @@ public class PowerManagerServiceTest { PowerManager.SCREEN_BRIGHT_WAKE_LOCK, tag, pkg, null /* workSource */, null /* historyTag */, Display.INVALID_DISPLAY); - assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE); + assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE); assertThat(mService.getWakefulnessLocked(Display.DEFAULT_DISPLAY_GROUP)).isEqualTo( WAKEFULNESS_AWAKE); assertThat(mService.getWakefulnessLocked(nonDefaultDisplayGroupId)).isEqualTo( WAKEFULNESS_AWAKE); advanceTime(15000); - assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE); + assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE); assertThat(mService.getWakefulnessLocked(Display.DEFAULT_DISPLAY_GROUP)).isEqualTo( WAKEFULNESS_AWAKE); assertThat(mService.getWakefulnessLocked(nonDefaultDisplayGroupId)).isEqualTo( @@ -1069,14 +1070,14 @@ public class PowerManagerServiceTest { WAKEFULNESS_AWAKE); assertThat(mService.getWakefulnessLocked(nonDefaultDisplayGroupId)).isEqualTo( WAKEFULNESS_AWAKE); - assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE); + assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE); listener.get().onDisplayGroupRemoved(nonDefaultDisplayGroupId); advanceTime(15000); assertThat(mService.getWakefulnessLocked(Display.DEFAULT_DISPLAY_GROUP)).isEqualTo( WAKEFULNESS_DOZING); - assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_DOZING); + assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_DOZING); } @Test @@ -1084,7 +1085,7 @@ public class PowerManagerServiceTest { createService(); startSystem(); - assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE); + assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE); verify(mNotifierMock, never()).onWakefulnessChangeStarted(anyInt(), anyInt(), anyLong()); } @@ -1103,7 +1104,7 @@ public class PowerManagerServiceTest { createService(); startSystem(); - assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_ASLEEP); + assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_ASLEEP); verify(mNotifierMock).onWakefulnessChangeStarted(eq(WAKEFULNESS_ASLEEP), anyInt(), anyLong()); } @@ -1137,7 +1138,7 @@ public class PowerManagerServiceTest { PowerManager.WAKE_REASON_UNKNOWN, "testing IPowerManager.wakeUp()", "pkg.name"); mService.onBootPhase(SystemService.PHASE_BOOT_COMPLETED); - assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE); + assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE); assertThat(mService.getDesiredScreenPolicyLocked(Display.DEFAULT_DISPLAY_GROUP)).isEqualTo( DisplayPowerRequest.POLICY_BRIGHT); } @@ -1418,23 +1419,23 @@ public class PowerManagerServiceTest { startSystem(); listener.get().onDisplayGroupAdded(nonDefaultDisplayGroupId); - assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE); + assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE); mService.setWakefulnessLocked(Display.DEFAULT_DISPLAY_GROUP, WAKEFULNESS_ASLEEP, 0, 0, 0, 0, null, null); - assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE); + assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE); mService.setWakefulnessLocked(nonDefaultDisplayGroupId, WAKEFULNESS_ASLEEP, 0, 0, 0, 0, null, null); - assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_ASLEEP); + assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_ASLEEP); mService.setWakefulnessLocked(Display.DEFAULT_DISPLAY_GROUP, WAKEFULNESS_AWAKE, 0, 0, 0, 0, null, null); - assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE); + assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE); } @Test - public void testMultiDisplay_addDisplayGroup_preservesWakefulness() { + public void testMultiDisplay_addDisplayGroup_wakesDeviceUp() { final int nonDefaultDisplayGroupId = Display.DEFAULT_DISPLAY_GROUP + 1; final AtomicReference listener = new AtomicReference<>(); @@ -1446,15 +1447,15 @@ public class PowerManagerServiceTest { createService(); startSystem(); - assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE); + assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE); mService.setWakefulnessLocked(Display.DEFAULT_DISPLAY_GROUP, WAKEFULNESS_ASLEEP, 0, 0, 0, 0, null, null); - assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_ASLEEP); + assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_ASLEEP); listener.get().onDisplayGroupAdded(nonDefaultDisplayGroupId); - assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_ASLEEP); + assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE); } @Test @@ -1471,18 +1472,79 @@ public class PowerManagerServiceTest { startSystem(); listener.get().onDisplayGroupAdded(nonDefaultDisplayGroupId); - assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE); + assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE); mService.setWakefulnessLocked(Display.DEFAULT_DISPLAY_GROUP, WAKEFULNESS_ASLEEP, 0, 0, 0, 0, null, null); - assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE); + assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE); listener.get().onDisplayGroupRemoved(nonDefaultDisplayGroupId); - assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_ASLEEP); + assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_ASLEEP); mService.setWakefulnessLocked(Display.DEFAULT_DISPLAY_GROUP, WAKEFULNESS_AWAKE, 0, 0, 0, 0, null, null); - assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE); + assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE); + } + + @Test + public void testMultiDisplay_updatesLastGlobalWakeTime() { + final int nonDefaultPowerGroupId = Display.DEFAULT_DISPLAY_GROUP + 1; + final AtomicReference listener = + new AtomicReference<>(); + long eventTime1 = 10; + long eventTime2 = eventTime1 + 1; + long eventTime3 = eventTime2 + 1; + long eventTime4 = eventTime3 + 1; + doAnswer((Answer) invocation -> { + listener.set(invocation.getArgument(0)); + return null; + }).when(mDisplayManagerInternalMock).registerDisplayGroupListener(any()); + + createService(); + startSystem(); + listener.get().onDisplayGroupAdded(nonDefaultPowerGroupId); + + assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE); + + mService.setWakefulnessLocked(Display.DEFAULT_DISPLAY_GROUP, WAKEFULNESS_DOZING, eventTime1, + 0, PowerManager.GO_TO_SLEEP_REASON_INATTENTIVE, 0, null, null); + assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE); + + mService.setWakefulnessLocked(nonDefaultPowerGroupId, WAKEFULNESS_DOZING, eventTime2, + 0, PowerManager.GO_TO_SLEEP_REASON_APPLICATION, 0, null, null); + assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_DOZING); + assertThat(mService.getBinderServiceInstance().getLastSleepReason()).isEqualTo( + PowerManager.GO_TO_SLEEP_REASON_APPLICATION); + + mService.setWakefulnessLocked(Display.DEFAULT_DISPLAY_GROUP, WAKEFULNESS_AWAKE, + eventTime3, /* uid= */ 0, PowerManager.WAKE_REASON_PLUGGED_IN, /* opUid= */ + 0, /* opPackageName= */ null, /* details= */ null); + 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); + + // 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); + } + + @Test + public void testLastSleepTime_notUpdatedWhenDreaming() { + createService(); + startSystem(); + + assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE); + PowerManager.WakeData initialWakeData = mService.getLocalServiceInstance().getLastWakeup(); + + forceDream(); + assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_DREAMING); + assertThat(mService.getLocalServiceInstance().getLastWakeup()).isEqualTo(initialWakeData); } @Test