summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--services/core/java/com/android/server/power/PowerGroup.java30
-rw-r--r--services/core/java/com/android/server/power/PowerManagerService.java45
-rw-r--r--services/tests/servicestests/src/com/android/server/power/PowerGroupTest.java85
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);