Add setting for device docked screen timeout.

This new timeout will only apply when the device is docked, while still honoring any maximum timeouts set by DevicePolicyManager or WM.

Test: atest PowerManagerServiceTest
Test: locally on device, modifying the setting manually via adb
Bug: 213908097
Change-Id: I3d992154723fa8871f7c1c24607b16a35c42fb87
This commit is contained in:
Lucas Silva
2022-01-20 20:39:57 +00:00
parent d478d792e0
commit 3048dbaac5
5 changed files with 108 additions and 2 deletions

View File

@@ -4500,6 +4500,13 @@ public final class Settings {
@Readable
public static final String SCREEN_OFF_TIMEOUT = "screen_off_timeout";
/**
* The amount of time in milliseconds before the device goes to sleep or begins to dream
* after a period of inactivity while it is docked.
* @hide
*/
public static final String SCREEN_OFF_TIMEOUT_DOCKED = "screen_off_timeout_docked";
/**
* The screen backlight brightness between 0 and 255.
*/

View File

@@ -43,6 +43,7 @@ public class SystemSettings {
Settings.System.FONT_SCALE,
Settings.System.DIM_SCREEN,
Settings.System.SCREEN_OFF_TIMEOUT,
Settings.System.SCREEN_OFF_TIMEOUT_DOCKED,
Settings.System.SCREEN_BRIGHTNESS_MODE,
Settings.System.SCREEN_AUTO_BRIGHTNESS_ADJ,
Settings.System.SCREEN_BRIGHTNESS_FOR_VR,

View File

@@ -111,6 +111,7 @@ public class SystemSettingsValidators {
});
VALIDATORS.put(System.DISPLAY_COLOR_MODE_VENDOR_HINT, ANY_STRING_VALIDATOR);
VALIDATORS.put(System.SCREEN_OFF_TIMEOUT, NON_NEGATIVE_INTEGER_VALIDATOR);
VALIDATORS.put(System.SCREEN_OFF_TIMEOUT_DOCKED, NON_NEGATIVE_INTEGER_VALIDATOR);
VALIDATORS.put(System.SCREEN_BRIGHTNESS_FOR_VR, new InclusiveIntegerRangeValidator(0, 255));
VALIDATORS.put(System.SCREEN_BRIGHTNESS_MODE, BOOLEAN_VALIDATOR);
VALIDATORS.put(System.ADAPTIVE_SLEEP, BOOLEAN_VALIDATOR);

View File

@@ -521,6 +521,9 @@ public final class PowerManagerService extends SystemService
// The screen off timeout setting value in milliseconds.
private long mScreenOffTimeoutSetting;
// The screen off timeout setting value in milliseconds to apply while device is docked.
private long mScreenOffTimeoutDockedSetting;
// Default for attentive warning duration.
private long mAttentiveWarningDurationConfig;
@@ -1272,6 +1275,9 @@ public final class PowerManagerService extends SystemService
resolver.registerContentObserver(Settings.System.getUriFor(
Settings.System.SCREEN_OFF_TIMEOUT),
false, mSettingsObserver, UserHandle.USER_ALL);
resolver.registerContentObserver(Settings.System.getUriFor(
Settings.System.SCREEN_OFF_TIMEOUT_DOCKED),
false, mSettingsObserver, UserHandle.USER_ALL);
resolver.registerContentObserver(Settings.Secure.getUriFor(
Settings.Secure.SLEEP_TIMEOUT),
false, mSettingsObserver, UserHandle.USER_ALL);
@@ -1394,6 +1400,9 @@ public final class PowerManagerService extends SystemService
mScreenOffTimeoutSetting = Settings.System.getIntForUser(resolver,
Settings.System.SCREEN_OFF_TIMEOUT, DEFAULT_SCREEN_OFF_TIMEOUT,
UserHandle.USER_CURRENT);
mScreenOffTimeoutDockedSetting = Settings.System.getLongForUser(resolver,
Settings.System.SCREEN_OFF_TIMEOUT_DOCKED, mScreenOffTimeoutSetting,
UserHandle.USER_CURRENT);
mSleepTimeoutSetting = Settings.Secure.getIntForUser(resolver,
Settings.Secure.SLEEP_TIMEOUT, DEFAULT_SLEEP_TIMEOUT,
UserHandle.USER_CURRENT);
@@ -2946,7 +2955,9 @@ public final class PowerManagerService extends SystemService
@GuardedBy("mLock")
private long getScreenOffTimeoutLocked(long sleepTimeout, long attentiveTimeout) {
long timeout = mScreenOffTimeoutSetting;
long timeout = mDockState == Intent.EXTRA_DOCK_STATE_UNDOCKED
? mScreenOffTimeoutSetting
: mScreenOffTimeoutDockedSetting;
if (isMaximumScreenOffTimeoutFromDeviceAdminEnforcedLocked()) {
timeout = Math.min(timeout, mMaximumScreenOffTimeoutFromDeviceAdmin);
}
@@ -4974,7 +4985,8 @@ public final class PowerManagerService extends SystemService
}
}
private final class DockReceiver extends BroadcastReceiver {
@VisibleForTesting
final class DockReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
synchronized (mLock) {

View File

@@ -87,6 +87,7 @@ import com.android.server.lights.LightsManager;
import com.android.server.policy.WindowManagerPolicy;
import com.android.server.power.PowerManagerService.BatteryReceiver;
import com.android.server.power.PowerManagerService.BinderService;
import com.android.server.power.PowerManagerService.DockReceiver;
import com.android.server.power.PowerManagerService.Injector;
import com.android.server.power.PowerManagerService.NativeWrapper;
import com.android.server.power.PowerManagerService.UserSwitchedReceiver;
@@ -152,6 +153,7 @@ public class PowerManagerServiceTest {
private Resources mResourcesSpy;
private OffsettableClock mClock;
private TestLooper mTestLooper;
private DockReceiver mDockReceiver;
private static class IntentFilterMatcher implements ArgumentMatcher<IntentFilter> {
private final IntentFilter mFilter;
@@ -337,6 +339,14 @@ public class PowerManagerServiceTest {
argThat(new IntentFilterMatcher(usFilter)), isNull(), isA(Handler.class));
mUserSwitchedReceiver = userSwitchedCaptor.getValue();
// Grab the DockReceiver
ArgumentCaptor<DockReceiver> dockReceiverCaptor =
ArgumentCaptor.forClass(DockReceiver.class);
IntentFilter dockFilter = new IntentFilter(Intent.ACTION_DOCK_EVENT);
verify(mContextSpy).registerReceiver(dockReceiverCaptor.capture(),
argThat(new IntentFilterMatcher(dockFilter)), isNull(), isA(Handler.class));
mDockReceiver = dockReceiverCaptor.getValue();
mService.onBootPhase(SystemService.PHASE_BOOT_COMPLETED);
}
@@ -385,6 +395,16 @@ public class PowerManagerServiceTest {
.thenReturn(minimumScreenOffTimeoutConfigMillis);
}
private void setScreenOffTimeout(int screenOffTimeoutMillis) {
Settings.System.putInt(mContextSpy.getContentResolver(), Settings.System.SCREEN_OFF_TIMEOUT,
screenOffTimeoutMillis);
}
private void setScreenOffTimeoutDocked(int screenOffTimeoutMillis) {
Settings.System.putInt(mContextSpy.getContentResolver(),
Settings.System.SCREEN_OFF_TIMEOUT_DOCKED, screenOffTimeoutMillis);
}
private void advanceTime(long timeMs) {
mClock.fastForward(timeMs);
mTestLooper.dispatchAll();
@@ -882,6 +902,71 @@ public class PowerManagerServiceTest {
PowerManager.GO_TO_SLEEP_REASON_INATTENTIVE);
}
@Test
public void testScreenOffTimeout_goesToSleepAfterTimeout() {
final DisplayInfo info = new DisplayInfo();
info.displayGroupId = Display.DEFAULT_DISPLAY_GROUP;
when(mDisplayManagerInternalMock.getDisplayInfo(Display.DEFAULT_DISPLAY)).thenReturn(info);
setMinimumScreenOffTimeoutConfig(10);
setScreenOffTimeout(10);
createService();
startSystem();
mService.getBinderServiceInstance().userActivity(Display.DEFAULT_DISPLAY, mClock.now(),
PowerManager.USER_ACTIVITY_EVENT_TOUCH, 0);
assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
advanceTime(15);
assertThat(mService.getGlobalWakefulnessLocked()).isNotEqualTo(WAKEFULNESS_AWAKE);
}
@Test
public void testScreenOffTimeout_usesRegularTimeoutWhenNotDocked() {
final DisplayInfo info = new DisplayInfo();
info.displayGroupId = Display.DEFAULT_DISPLAY_GROUP;
when(mDisplayManagerInternalMock.getDisplayInfo(Display.DEFAULT_DISPLAY)).thenReturn(info);
setMinimumScreenOffTimeoutConfig(10);
setScreenOffTimeout(10);
setScreenOffTimeoutDocked(30);
createService();
startSystem();
mService.getBinderServiceInstance().userActivity(Display.DEFAULT_DISPLAY, mClock.now(),
PowerManager.USER_ACTIVITY_EVENT_TOUCH, 0);
assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
advanceTime(15);
assertThat(mService.getGlobalWakefulnessLocked()).isNotEqualTo(WAKEFULNESS_AWAKE);
}
@Test
public void testScreenOffTimeout_usesDockedTimeoutWhenDocked() {
final DisplayInfo info = new DisplayInfo();
info.displayGroupId = Display.DEFAULT_DISPLAY_GROUP;
when(mDisplayManagerInternalMock.getDisplayInfo(Display.DEFAULT_DISPLAY)).thenReturn(info);
setMinimumScreenOffTimeoutConfig(10);
setScreenOffTimeout(10);
setScreenOffTimeoutDocked(30);
createService();
startSystem();
mService.getBinderServiceInstance().userActivity(Display.DEFAULT_DISPLAY, mClock.now(),
PowerManager.USER_ACTIVITY_EVENT_TOUCH, 0);
mDockReceiver.onReceive(mContextSpy,
new Intent(Intent.ACTION_DOCK_EVENT).putExtra(Intent.EXTRA_DOCK_STATE,
Intent.EXTRA_DOCK_STATE_DESK));
assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
advanceTime(15);
assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
advanceTime(20);
assertThat(mService.getGlobalWakefulnessLocked()).isNotEqualTo(WAKEFULNESS_AWAKE);
}
@Test
public void testInattentiveSleep_goesToSleepWithWakeLock() {
final String pkg = mContextSpy.getOpPackageName();