Sleep softly on device close.
Add a new flag GO_TO_SLEEP_FLAG_SOFT_SLEEP. When set, this sleeps the device only if its user activity keeping it awake. If its otherwise staying awake because an application is holding a wakelock, then the device continues to stay awake. Bug: 260705307 Test: atest PowerManagerServiceTest Test: manual Change-Id: I08b6dacf418d927b4f86816b1b6d19965e68556a
This commit is contained in:
committed by
Rupesh Bansal
parent
4ee9f703bb
commit
d7367c39c4
@@ -522,6 +522,13 @@ public final class PowerManager {
|
||||
*/
|
||||
public static final int GO_TO_SLEEP_FLAG_NO_DOZE = 1 << 0;
|
||||
|
||||
/**
|
||||
* Go to sleep flag: Sleep softly, go to sleep only if there's no wakelock explicitly keeping
|
||||
* the device awake.
|
||||
* @hide
|
||||
*/
|
||||
public static final int GO_TO_SLEEP_FLAG_SOFT_SLEEP = 1 << 1;
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
|
||||
@@ -426,7 +426,8 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener {
|
||||
// Send the device to sleep when required.
|
||||
mHandler.post(() -> {
|
||||
mPowerManager.goToSleep(SystemClock.uptimeMillis(),
|
||||
PowerManager.GO_TO_SLEEP_REASON_DEVICE_FOLD, 0);
|
||||
PowerManager.GO_TO_SLEEP_REASON_DEVICE_FOLD,
|
||||
PowerManager.GO_TO_SLEEP_FLAG_SOFT_SLEEP);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,6 +28,8 @@ import static com.android.server.power.PowerManagerService.USER_ACTIVITY_SCREEN_
|
||||
import static com.android.server.power.PowerManagerService.WAKE_LOCK_DOZE;
|
||||
import static com.android.server.power.PowerManagerService.WAKE_LOCK_DRAW;
|
||||
import static com.android.server.power.PowerManagerService.WAKE_LOCK_SCREEN_BRIGHT;
|
||||
import static com.android.server.power.PowerManagerService.WAKE_LOCK_SCREEN_DIM;
|
||||
import static com.android.server.power.PowerManagerService.WAKE_LOCK_STAY_AWAKE;
|
||||
|
||||
import android.hardware.display.DisplayManagerInternal;
|
||||
import android.hardware.display.DisplayManagerInternal.DisplayPowerRequest;
|
||||
@@ -341,6 +343,22 @@ public class PowerGroup {
|
||||
return mWakeLockSummary;
|
||||
}
|
||||
|
||||
/**
|
||||
* Query whether a wake lock is at least partially responsible for keeping the device awake.
|
||||
*
|
||||
* This does not necessarily mean the wake lock is the sole reason the device is awake; there
|
||||
* could also be user activity keeping the device awake, for example. It just means a wake lock
|
||||
* is being held that would keep the device awake even if nothing else was.
|
||||
*
|
||||
* @return whether the PowerGroup is being kept awake at least in part because a wake lock is
|
||||
* being held.
|
||||
*/
|
||||
public boolean hasWakeLockKeepingScreenOnLocked() {
|
||||
final int screenOnWakeLockMask =
|
||||
WAKE_LOCK_SCREEN_BRIGHT | WAKE_LOCK_SCREEN_DIM | WAKE_LOCK_STAY_AWAKE;
|
||||
return (mWakeLockSummary & (screenOnWakeLockMask)) != 0;
|
||||
}
|
||||
|
||||
public void setWakeLockSummaryLocked(int summary) {
|
||||
mWakeLockSummary = summary;
|
||||
}
|
||||
|
||||
@@ -5778,6 +5778,11 @@ public final class PowerManagerService extends SystemService
|
||||
try {
|
||||
synchronized (mLock) {
|
||||
PowerGroup defaultPowerGroup = mPowerGroups.get(Display.DEFAULT_DISPLAY_GROUP);
|
||||
if ((flags & PowerManager.GO_TO_SLEEP_FLAG_SOFT_SLEEP) != 0) {
|
||||
if (defaultPowerGroup.hasWakeLockKeepingScreenOnLocked()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
if ((flags & PowerManager.GO_TO_SLEEP_FLAG_NO_DOZE) != 0) {
|
||||
sleepPowerGroupLocked(defaultPowerGroup, eventTime, reason, uid);
|
||||
} else {
|
||||
|
||||
@@ -491,6 +491,111 @@ public class PowerManagerServiceTest {
|
||||
assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_ASLEEP);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWakefulnessSleep_SoftSleepFlag_NoWakelocks() {
|
||||
createService();
|
||||
// Start with AWAKE state
|
||||
startSystem();
|
||||
assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
|
||||
|
||||
// Take a nap and verify we go to sleep.
|
||||
mService.getBinderServiceInstance().goToSleep(mClock.now(),
|
||||
PowerManager.GO_TO_SLEEP_REASON_APPLICATION,
|
||||
PowerManager.GO_TO_SLEEP_FLAG_SOFT_SLEEP);
|
||||
assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_DOZING);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWakefulnessSleep_SoftSleepFlag_WithPartialWakelock() {
|
||||
createService();
|
||||
// Start with AWAKE state
|
||||
startSystem();
|
||||
assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
|
||||
|
||||
// Grab a wakelock
|
||||
final String tag = "wakelock1";
|
||||
final String packageName = "pkg.name";
|
||||
final IBinder token = new Binder();
|
||||
final int flags = PowerManager.PARTIAL_WAKE_LOCK;
|
||||
mService.getBinderServiceInstance().acquireWakeLock(token, flags, tag, packageName,
|
||||
null /* workSource */, null /* historyTag */, Display.INVALID_DISPLAY,
|
||||
null /* callback */);
|
||||
|
||||
// Take a nap and verify we stay awake.
|
||||
mService.getBinderServiceInstance().goToSleep(mClock.now(),
|
||||
PowerManager.GO_TO_SLEEP_REASON_APPLICATION,
|
||||
PowerManager.GO_TO_SLEEP_FLAG_SOFT_SLEEP);
|
||||
assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_DOZING);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWakefulnessSleep_SoftSleepFlag_WithFullWakelock() {
|
||||
createService();
|
||||
// Start with AWAKE state
|
||||
startSystem();
|
||||
assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
|
||||
|
||||
// Grab a wakelock
|
||||
final String tag = "wakelock1";
|
||||
final String packageName = "pkg.name";
|
||||
final IBinder token = new Binder();
|
||||
final int flags = PowerManager.FULL_WAKE_LOCK;
|
||||
mService.getBinderServiceInstance().acquireWakeLock(token, flags, tag, packageName,
|
||||
null /* workSource */, null /* historyTag */, Display.INVALID_DISPLAY,
|
||||
null /* callback */);
|
||||
|
||||
// Take a nap and verify we stay awake.
|
||||
mService.getBinderServiceInstance().goToSleep(mClock.now(),
|
||||
PowerManager.GO_TO_SLEEP_REASON_APPLICATION,
|
||||
PowerManager.GO_TO_SLEEP_FLAG_SOFT_SLEEP);
|
||||
assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWakefulnessSleep_SoftSleepFlag_WithScreenBrightWakelock() {
|
||||
createService();
|
||||
// Start with AWAKE state
|
||||
startSystem();
|
||||
assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
|
||||
|
||||
// Grab a wakelock
|
||||
final String tag = "wakelock1";
|
||||
final String packageName = "pkg.name";
|
||||
final IBinder token = new Binder();
|
||||
final int flags = PowerManager.SCREEN_BRIGHT_WAKE_LOCK;
|
||||
mService.getBinderServiceInstance().acquireWakeLock(token, flags, tag, packageName,
|
||||
null /* workSource */, null /* historyTag */, Display.INVALID_DISPLAY,
|
||||
null /* callback */);
|
||||
|
||||
// Take a nap and verify we stay awake.
|
||||
mService.getBinderServiceInstance().goToSleep(mClock.now(),
|
||||
PowerManager.GO_TO_SLEEP_REASON_APPLICATION,
|
||||
PowerManager.GO_TO_SLEEP_FLAG_SOFT_SLEEP);
|
||||
assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
|
||||
}
|
||||
@Test
|
||||
public void testWakefulnessSleep_SoftSleepFlag_WithScreenDimWakelock() {
|
||||
createService();
|
||||
// Start with AWAKE state
|
||||
startSystem();
|
||||
assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
|
||||
|
||||
// Grab a wakelock
|
||||
final String tag = "wakelock1";
|
||||
final String packageName = "pkg.name";
|
||||
final IBinder token = new Binder();
|
||||
final int flags = PowerManager.SCREEN_DIM_WAKE_LOCK;
|
||||
mService.getBinderServiceInstance().acquireWakeLock(token, flags, tag, packageName,
|
||||
null /* workSource */, null /* historyTag */, Display.INVALID_DISPLAY,
|
||||
null /* callback */);
|
||||
|
||||
// Take a nap and verify we stay awake.
|
||||
mService.getBinderServiceInstance().goToSleep(mClock.now(),
|
||||
PowerManager.GO_TO_SLEEP_REASON_APPLICATION,
|
||||
PowerManager.GO_TO_SLEEP_FLAG_SOFT_SLEEP);
|
||||
assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWakefulnessAwake_AcquireCausesWakeup_turnScreenOnAllowed() {
|
||||
createService();
|
||||
|
||||
Reference in New Issue
Block a user