Add internal API to PowerManager which allows napping when device is

asleep.

This allows us to enter the dream directly while the device is off, instead of needing to wake the device before entering dream.

Bug: 246472225
Test: adb shell cmd dreams start-dreaming (while device asleep)
Test: atest PowerGroupTest
Change-Id: Id4634f3d5f7c3ae324f85f11a6991f0cab068a7d
This commit is contained in:
Lucas Silva
2022-10-11 11:57:06 -04:00
parent aae9726073
commit 16d6ddde58
6 changed files with 49 additions and 22 deletions

View File

@@ -335,4 +335,10 @@ public abstract class PowerManagerInternal {
/** Allows power button to intercept a power key button press. */
public abstract boolean interceptPowerKeyDown(KeyEvent event);
/**
* Internal version of {@link android.os.PowerManager#nap} which allows for napping while the
* device is not awake.
*/
public abstract void nap(long eventTime, boolean allowWake);
}

View File

@@ -246,8 +246,8 @@ public final class DreamManagerService extends SystemService {
// Because napping could cause the screen to turn off immediately if the dream
// cannot be started, we keep one eye open and gently poke user activity.
long time = SystemClock.uptimeMillis();
mPowerManager.userActivity(time, true /*noChangeLights*/);
mPowerManager.nap(time);
mPowerManager.userActivity(time, /* noChangeLights= */ true);
mPowerManagerInternal.nap(time, /* allowWake= */ true);
}
private void requestAwakenInternal(String reason) {
@@ -637,7 +637,7 @@ public final class DreamManagerService extends SystemService {
@Nullable FileDescriptor err,
@NonNull String[] args, @Nullable ShellCallback callback,
@NonNull ResultReceiver resultReceiver) throws RemoteException {
new DreamShellCommand(DreamManagerService.this, mPowerManager)
new DreamShellCommand(DreamManagerService.this)
.exec(this, in, out, err, args, callback, resultReceiver);
}

View File

@@ -18,10 +18,8 @@ package com.android.server.dreams;
import android.annotation.NonNull;
import android.os.Binder;
import android.os.PowerManager;
import android.os.Process;
import android.os.ShellCommand;
import android.os.SystemClock;
import android.text.TextUtils;
import android.util.Slog;
@@ -34,11 +32,9 @@ public class DreamShellCommand extends ShellCommand {
private static final boolean DEBUG = true;
private static final String TAG = "DreamShellCommand";
private final @NonNull DreamManagerService mService;
private final @NonNull PowerManager mPowerManager;
DreamShellCommand(@NonNull DreamManagerService service, @NonNull PowerManager powerManager) {
DreamShellCommand(@NonNull DreamManagerService service) {
mService = service;
mPowerManager = powerManager;
}
@Override
@@ -67,8 +63,6 @@ public class DreamShellCommand extends ShellCommand {
}
private int startDreaming() {
mPowerManager.wakeUp(SystemClock.uptimeMillis(),
PowerManager.WAKE_REASON_PLUGGED_IN, "shell:cmd:android.service.dreams:DREAM");
mService.requestStartDreamFromShell();
return 0;
}

View File

@@ -229,8 +229,8 @@ public class PowerGroup {
}
}
boolean dreamLocked(long eventTime, int uid) {
if (eventTime < mLastWakeTime || mWakefulness != WAKEFULNESS_AWAKE) {
boolean dreamLocked(long eventTime, int uid, boolean allowWake) {
if (eventTime < mLastWakeTime || (!allowWake && mWakefulness != WAKEFULNESS_AWAKE)) {
return false;
}

View File

@@ -1919,6 +1919,13 @@ public final class PowerManagerService extends SystemService
}
}
private void napInternal(long eventTime, int uid, boolean allowWake) {
synchronized (mLock) {
dreamPowerGroupLocked(mPowerGroups.get(Display.DEFAULT_DISPLAY_GROUP),
eventTime, uid, allowWake);
}
}
private void onUserAttention() {
synchronized (mLock) {
if (userActivityNoUpdateLocked(mPowerGroups.get(Display.DEFAULT_DISPLAY_GROUP),
@@ -2034,7 +2041,8 @@ public final class PowerManagerService extends SystemService
}
@GuardedBy("mLock")
private boolean dreamPowerGroupLocked(PowerGroup powerGroup, long eventTime, int uid) {
private boolean dreamPowerGroupLocked(PowerGroup powerGroup, long eventTime, int uid,
boolean allowWake) {
if (DEBUG_SPEW) {
Slog.d(TAG, "dreamPowerGroup: groupId=" + powerGroup.getGroupId() + ", eventTime="
+ eventTime + ", uid=" + uid);
@@ -2042,7 +2050,7 @@ public final class PowerManagerService extends SystemService
if (!mBootCompleted || !mSystemReady) {
return false;
}
return powerGroup.dreamLocked(eventTime, uid);
return powerGroup.dreamLocked(eventTime, uid, allowWake);
}
@GuardedBy("mLock")
@@ -3086,7 +3094,8 @@ public final class PowerManagerService extends SystemService
changed = sleepPowerGroupLocked(powerGroup, time,
PowerManager.GO_TO_SLEEP_REASON_INATTENTIVE, Process.SYSTEM_UID);
} else if (shouldNapAtBedTimeLocked()) {
changed = dreamPowerGroupLocked(powerGroup, time, Process.SYSTEM_UID);
changed = dreamPowerGroupLocked(powerGroup, time,
Process.SYSTEM_UID, /* allowWake= */ false);
} else {
changed = dozePowerGroupLocked(powerGroup, time,
PowerManager.GO_TO_SLEEP_REASON_TIMEOUT, Process.SYSTEM_UID);
@@ -5701,10 +5710,7 @@ public final class PowerManagerService extends SystemService
final int uid = Binder.getCallingUid();
final long ident = Binder.clearCallingIdentity();
try {
synchronized (mLock) {
dreamPowerGroupLocked(mPowerGroups.get(Display.DEFAULT_DISPLAY_GROUP),
eventTime, uid);
}
napInternal(eventTime, uid, /* allowWake= */ false);
} finally {
Binder.restoreCallingIdentity(ident);
}
@@ -6632,6 +6638,11 @@ public final class PowerManagerService extends SystemService
public boolean interceptPowerKeyDown(KeyEvent event) {
return interceptPowerKeyDownInternal(event);
}
@Override
public void nap(long eventTime, boolean allowWake) {
napInternal(eventTime, Process.SYSTEM_UID, allowWake);
}
}
/**

View File

@@ -116,7 +116,7 @@ public class PowerGroupTest {
@Test
public void testDreamPowerGroup() {
assertThat(mPowerGroup.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
mPowerGroup.dreamLocked(TIMESTAMP1, UID);
mPowerGroup.dreamLocked(TIMESTAMP1, UID, /* allowWake= */ false);
assertThat(mPowerGroup.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_DREAMING);
assertThat(mPowerGroup.isSandmanSummonedLocked()).isTrue();
verify(mWakefulnessCallbackMock).onWakefulnessChangedLocked(eq(GROUP_ID),
@@ -172,7 +172,7 @@ public class PowerGroupTest {
eq(UID), /* opUid= */ anyInt(), /* opPackageName= */ isNull(),
/* details= */ isNull());
assertThat(mPowerGroup.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_DOZING);
assertThat(mPowerGroup.dreamLocked(TIMESTAMP2, UID)).isFalse();
assertThat(mPowerGroup.dreamLocked(TIMESTAMP2, UID, /* allowWake= */ false)).isFalse();
assertThat(mPowerGroup.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_DOZING);
verify(mWakefulnessCallbackMock, never()).onWakefulnessChangedLocked(
eq(GROUP_ID), /* wakefulness= */ eq(WAKEFULNESS_DREAMING), eq(TIMESTAMP2),
@@ -180,6 +180,22 @@ public class PowerGroupTest {
/* details= */ any());
}
@Test
public void testDreamPowerGroupWhenNotAwakeShouldWake() {
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, /* allowWake= */ true)).isTrue();
assertThat(mPowerGroup.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_DREAMING);
verify(mWakefulnessCallbackMock).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);
@@ -514,7 +530,7 @@ public class PowerGroupTest {
.setBatterySaverEnabled(batterySaverEnabled)
.setBrightnessFactor(brightnessFactor)
.build();
mPowerGroup.dreamLocked(TIMESTAMP1, UID);
mPowerGroup.dreamLocked(TIMESTAMP1, UID, /* allowWake= */ false);
assertThat(mPowerGroup.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_DREAMING);
mPowerGroup.setWakeLockSummaryLocked(WAKE_LOCK_SCREEN_BRIGHT);
mPowerGroup.updateLocked(/* screenBrightnessOverride= */ BRIGHTNESS,