diff options
3 files changed, 124 insertions, 36 deletions
diff --git a/services/core/java/com/android/server/power/PowerGroup.java b/services/core/java/com/android/server/power/PowerGroup.java index 8b3d82a508d7..fec61ac8f2cf 100644 --- a/services/core/java/com/android/server/power/PowerGroup.java +++ b/services/core/java/com/android/server/power/PowerGroup.java @@ -22,6 +22,8 @@ import static android.os.PowerManagerInternal.WAKEFULNESS_DOZING; import static android.os.PowerManagerInternal.WAKEFULNESS_DREAMING; import static android.os.PowerManagerInternal.isInteractive; +import static com.android.internal.util.LatencyTracker.ACTION_TURN_ON_SCREEN; +import static com.android.server.power.PowerManagerService.TRACE_SCREEN_ON; import static com.android.server.power.PowerManagerService.USER_ACTIVITY_SCREEN_BRIGHT; import static com.android.server.power.PowerManagerService.WAKE_LOCK_DOZE; import static com.android.server.power.PowerManagerService.WAKE_LOCK_DRAW; @@ -30,12 +32,14 @@ import static com.android.server.power.PowerManagerService.WAKE_LOCK_SCREEN_BRIG import android.hardware.display.DisplayManagerInternal; import android.hardware.display.DisplayManagerInternal.DisplayPowerRequest; import android.os.PowerManager; +import android.os.PowerManagerInternal; import android.os.PowerSaveState; import android.os.Trace; import android.util.Slog; import android.view.Display; import com.android.internal.annotations.VisibleForTesting; +import com.android.internal.util.LatencyTracker; /** * Used to store power related requests to every display in a @@ -197,6 +201,32 @@ public class PowerGroup { mIsSandmanSummoned = isSandmanSummoned; } + void wakeUpLocked(long eventTime, @PowerManager.WakeReason int reason, String details, int uid, + String opPackageName, int opUid, LatencyTracker latencyTracker) { + if (eventTime < mLastSleepTime || mWakefulness == WAKEFULNESS_AWAKE) { + return; + } + + Trace.traceBegin(Trace.TRACE_TAG_POWER, "wakePowerGroup" + mGroupId); + try { + Slog.i(TAG, "Waking up power group from " + + PowerManagerInternal.wakefulnessToString(mWakefulness) + + " (groupId=" + mGroupId + + ", uid=" + uid + + ", reason=" + PowerManager.wakeReasonToString(reason) + + ", details=" + details + + ")..."); + Trace.asyncTraceBegin(Trace.TRACE_TAG_POWER, TRACE_SCREEN_ON, mGroupId); + // The instrument will be timed out automatically after 2 seconds. + latencyTracker.onActionStart(ACTION_TURN_ON_SCREEN, String.valueOf(mGroupId)); + + setWakefulnessLocked(WAKEFULNESS_AWAKE, eventTime, uid, reason, opUid, + opPackageName, details); + } finally { + Trace.traceEnd(Trace.TRACE_TAG_POWER); + } + } + boolean dreamLocked(long eventTime, int uid) { if (eventTime < mLastWakeTime || mWakefulness != WAKEFULNESS_AWAKE) { return false; diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java index 1032ca660f14..048f8d6a04fa 100644 --- a/services/core/java/com/android/server/power/PowerManagerService.java +++ b/services/core/java/com/android/server/power/PowerManagerService.java @@ -246,7 +246,7 @@ public final class PowerManagerService extends SystemService private static final String REASON_LOW_BATTERY = "shutdown,battery"; private static final String REASON_BATTERY_THERMAL_STATE = "shutdown,thermal,battery"; - private static final String TRACE_SCREEN_ON = "Screen turning on"; + static final String TRACE_SCREEN_ON = "Screen turning on"; /** If turning screen on takes more than this long, we show a warning on logcat. */ private static final int SCREEN_ON_LATENCY_WARNING_MS = 200; @@ -1945,45 +1945,15 @@ public final class PowerManagerService extends SystemService @GuardedBy("mLock") 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, "wakePowerGroupLocked: eventTime=" + eventTime - + ", groupId=" + groupId + ", uid=" + uid); - } - - if (eventTime < powerGroup.getLastSleepTimeLocked() || mForceSuspendActive - || !mSystemReady) { - return; + + ", groupId=" + powerGroup.getGroupId() + ", uid=" + uid); } - - final int currentWakefulness = powerGroup.getWakefulnessLocked(); - if (currentWakefulness == WAKEFULNESS_AWAKE) { - if (!mBootCompleted && sQuiescent) { - mDirty |= DIRTY_QUIESCENT; - updatePowerStateLocked(); - } + if (mForceSuspendActive || !mSystemReady) { return; } - - Trace.traceBegin(Trace.TRACE_TAG_POWER, "powerOnDisplay"); - try { - Slog.i(TAG, "Waking up power group from " - + PowerManagerInternal.wakefulnessToString(currentWakefulness) - + " (groupId=" + groupId - + ", uid=" + uid - + ", reason=" + PowerManager.wakeReasonToString(reason) - + ", details=" + details - + ")..."); - Trace.asyncTraceBegin(Trace.TRACE_TAG_POWER, TRACE_SCREEN_ON, groupId); - // The instrument will be timed out automatically after 2 seconds. - LatencyTracker.getInstance(mContext) - .onActionStart(ACTION_TURN_ON_SCREEN, String.valueOf(groupId)); - - powerGroup.setWakefulnessLocked(WAKEFULNESS_AWAKE, eventTime, uid, reason, opUid, - opPackageName, details); - } finally { - Trace.traceEnd(Trace.TRACE_TAG_POWER); - } + powerGroup.wakeUpLocked(eventTime, reason, details, uid, opPackageName, opUid, + LatencyTracker.getInstance(mContext)); } @GuardedBy("mLock") @@ -5531,6 +5501,11 @@ public final class PowerManagerService extends SystemService final long ident = Binder.clearCallingIdentity(); try { synchronized (mLock) { + if (!mBootCompleted && sQuiescent) { + mDirty |= DIRTY_QUIESCENT; + updatePowerStateLocked(); + return; + } wakePowerGroupLocked(mPowerGroups.get(Display.DEFAULT_DISPLAY_GROUP), eventTime, reason, details, uid, opPackageName, uid); } diff --git a/services/tests/servicestests/src/com/android/server/power/PowerGroupTest.java b/services/tests/servicestests/src/com/android/server/power/PowerGroupTest.java index bc996d6789aa..d8c9c3433313 100644 --- a/services/tests/servicestests/src/com/android/server/power/PowerGroupTest.java +++ b/services/tests/servicestests/src/com/android/server/power/PowerGroupTest.java @@ -24,8 +24,10 @@ import static android.hardware.display.DisplayManagerInternal.DisplayPowerReques import static android.hardware.display.DisplayManagerInternal.DisplayPowerRequest.POLICY_VR; 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_DEVICE_FOLD; import static android.os.PowerManager.GO_TO_SLEEP_REASON_TIMEOUT; import static android.os.PowerManager.WAKE_REASON_GESTURE; +import static android.os.PowerManager.WAKE_REASON_PLUGGED_IN; import static android.os.PowerManagerInternal.WAKEFULNESS_ASLEEP; import static android.os.PowerManagerInternal.WAKEFULNESS_AWAKE; import static android.os.PowerManagerInternal.WAKEFULNESS_DOZING; @@ -37,9 +39,11 @@ import static com.android.server.power.PowerManagerService.WAKE_LOCK_SCREEN_BRIG import static com.google.common.truth.Truth.assertThat; +import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.ArgumentMatchers.isNull; +import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; import android.hardware.display.DisplayManagerInternal; @@ -47,6 +51,10 @@ import android.os.PowerManager; import android.os.PowerSaveState; import android.view.Display; +import androidx.test.platform.app.InstrumentationRegistry; + +import com.android.internal.util.LatencyTracker; + import org.junit.Before; import org.junit.Test; import org.mockito.Mock; @@ -89,8 +97,28 @@ public class PowerGroupTest { } @Test - public void testDreamPowerGroupTriggersOnWakefulnessChangedCallback() { + public void testWakePowerGroup() { + mPowerGroup.sleepLocked(TIMESTAMP1, UID, GO_TO_SLEEP_REASON_APPLICATION); + verify(mWakefulnessCallbackMock).onWakefulnessChangedLocked(eq(GROUP_ID), + eq(WAKEFULNESS_ASLEEP), eq(TIMESTAMP1), eq(GO_TO_SLEEP_REASON_APPLICATION), + eq(UID), /* opUid= */anyInt(), /* opPackageName= */ isNull(), /* details= */ + isNull()); + String details = "wake PowerGroup1"; + LatencyTracker latencyTracker = LatencyTracker.getInstance( + InstrumentationRegistry.getInstrumentation().getContext()); + mPowerGroup.wakeUpLocked(TIMESTAMP2, WAKE_REASON_PLUGGED_IN, details, UID, + /* opPackageName= */ null, /* opUid= */ 0, latencyTracker); + verify(mWakefulnessCallbackMock).onWakefulnessChangedLocked(eq(GROUP_ID), + eq(WAKEFULNESS_AWAKE), eq(TIMESTAMP2), eq(WAKE_REASON_PLUGGED_IN), eq(UID), + /* opUid= */ anyInt(), /* opPackageName= */ isNull(), eq(details)); + } + + @Test + public void testDreamPowerGroup() { + assertThat(mPowerGroup.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE); mPowerGroup.dreamLocked(TIMESTAMP1, UID); + assertThat(mPowerGroup.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_DREAMING); + assertThat(mPowerGroup.isSandmanSummonedLocked()).isTrue(); verify(mWakefulnessCallbackMock).onWakefulnessChangedLocked(eq(GROUP_ID), eq(WAKEFULNESS_DREAMING), eq(TIMESTAMP1), eq(GO_TO_SLEEP_REASON_APPLICATION), eq(UID), /* opUid= */anyInt(), /* opPackageName= */ isNull(), /* details= */ @@ -98,6 +126,61 @@ public class PowerGroupTest { } @Test + public void testDozePowerGroup() { + assertThat(mPowerGroup.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE); + mPowerGroup.dozeLocked(TIMESTAMP1, UID, GO_TO_SLEEP_REASON_TIMEOUT); + assertThat(mPowerGroup.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_DOZING); + assertThat(mPowerGroup.isSandmanSummonedLocked()).isTrue(); + verify(mWakefulnessCallbackMock).onWakefulnessChangedLocked(eq(GROUP_ID), + eq(WAKEFULNESS_DOZING), eq(TIMESTAMP1), eq(GO_TO_SLEEP_REASON_TIMEOUT), + eq(UID), /* opUid= */ anyInt(), /* opPackageName= */ isNull(), + /* details= */ isNull()); + } + + @Test + public void testDozePowerGroupWhenNonInteractiveHasNoEffect() { + mPowerGroup.sleepLocked(TIMESTAMP1, UID, GO_TO_SLEEP_REASON_TIMEOUT); + verify(mWakefulnessCallbackMock).onWakefulnessChangedLocked(eq(GROUP_ID), + eq(WAKEFULNESS_ASLEEP), eq(TIMESTAMP1), eq(GO_TO_SLEEP_REASON_TIMEOUT), + eq(UID), /* opUid= */ anyInt(), /* opPackageName= */ isNull(), + /* details= */ isNull()); + assertThat(mPowerGroup.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_ASLEEP); + assertThat(mPowerGroup.dozeLocked(TIMESTAMP2, UID, GO_TO_SLEEP_REASON_TIMEOUT)).isFalse(); + assertThat(mPowerGroup.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_ASLEEP); + verify(mWakefulnessCallbackMock, never()).onWakefulnessChangedLocked( + eq(GROUP_ID), eq(WAKEFULNESS_DOZING), eq(TIMESTAMP2), /* reason= */ anyInt(), + eq(UID), /* opUid= */ anyInt(), /* opPackageName= */ any(), /* details= */ any()); + } + + @Test + public void testSleepPowerGroup() { + assertThat(mPowerGroup.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE); + mPowerGroup.sleepLocked(TIMESTAMP1, UID, GO_TO_SLEEP_REASON_DEVICE_FOLD); + assertThat(mPowerGroup.isSandmanSummonedLocked()).isTrue(); + assertThat(mPowerGroup.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_ASLEEP); + verify(mWakefulnessCallbackMock).onWakefulnessChangedLocked(eq(GROUP_ID), + eq(WAKEFULNESS_ASLEEP), eq(TIMESTAMP1), eq(GO_TO_SLEEP_REASON_DEVICE_FOLD), + eq(UID), /* opUid= */ anyInt(), /* opPackageName= */ isNull(), + /* details= */ isNull()); + } + + @Test + public void testDreamPowerGroupWhenNotAwakeHasNoEffect() { + mPowerGroup.dozeLocked(TIMESTAMP1, UID, GO_TO_SLEEP_REASON_TIMEOUT); + verify(mWakefulnessCallbackMock).onWakefulnessChangedLocked(eq(GROUP_ID), + eq(WAKEFULNESS_DOZING), eq(TIMESTAMP1), eq(GO_TO_SLEEP_REASON_TIMEOUT), + eq(UID), /* opUid= */ anyInt(), /* opPackageName= */ isNull(), + /* details= */ isNull()); + assertThat(mPowerGroup.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_DOZING); + assertThat(mPowerGroup.dreamLocked(TIMESTAMP2, UID)).isFalse(); + assertThat(mPowerGroup.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_DOZING); + verify(mWakefulnessCallbackMock, never()).onWakefulnessChangedLocked( + eq(GROUP_ID), /* wakefulness= */ eq(WAKEFULNESS_DREAMING), eq(TIMESTAMP2), + /* reason= */ anyInt(), eq(UID), /* opUid= */ anyInt(), /* opPackageName= */ any(), + /* details= */ any()); + } + + @Test public void testLastWakeAndSleepTimeIsUpdated() { assertThat(mPowerGroup.getLastWakeTimeLocked()).isEqualTo(TIMESTAMP_CREATE); assertThat(mPowerGroup.getLastSleepTimeLocked()).isEqualTo(TIMESTAMP_CREATE); |