Skip to content

Commit 05af6ad

Browse files
author
Jeff Brown
committed
Implement auto-sleep functionality.
Added a new SLEEP_TIMEOUT setting which governs how long the device will remain awake or dreaming without user activity. By default this value is set to -1 which maintains today's existing behavior. We basically represent the time we are allowed to be dreaming as a new kind of user activity summary state called DREAM, similar to BRIGHT and DIM. When the sleep timeout expires, the state is cleared and the dream ends. Bug: 17665809 Change-Id: I59aa7648dcec215f1285464fc1134934a09230e5
1 parent 496aeb1 commit 05af6ad

4 files changed

Lines changed: 97 additions & 13 deletions

File tree

core/java/android/provider/Settings.java

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2001,7 +2001,10 @@ public static void setShowGTalkServiceStatusForUser(ContentResolver cr, boolean
20012001
public static final String DIM_SCREEN = "dim_screen";
20022002

20032003
/**
2004-
* The timeout before the screen turns off.
2004+
* The amount of time in milliseconds before the device goes to sleep or begins
2005+
* to dream after a period of inactivity. This value is also known as the
2006+
* user activity timeout period since the screen isn't necessarily turned off
2007+
* when it expires.
20052008
*/
20062009
public static final String SCREEN_OFF_TIMEOUT = "screen_off_timeout";
20072010

@@ -4816,6 +4819,20 @@ public static boolean putFloatForUser(ContentResolver cr, String name, float val
48164819
public static final String USB_AUDIO_AUTOMATIC_ROUTING_DISABLED =
48174820
"usb_audio_automatic_routing_disabled";
48184821

4822+
/**
4823+
* The timeout in milliseconds before the device fully goes to sleep after
4824+
* a period of inactivity. This value sets an upper bound on how long the device
4825+
* will stay awake or dreaming without user activity. It should generally
4826+
* be longer than {@link #SCREEN_OFF_TIMEOUT} as otherwise the device
4827+
* will sleep before it ever has a chance to dream.
4828+
* <p>
4829+
* Use -1 to disable this timeout.
4830+
* </p>
4831+
*
4832+
* @hide
4833+
*/
4834+
public static final String SLEEP_TIMEOUT = "sleep_timeout";
4835+
48194836
/**
48204837
* This are the settings to be backed up.
48214838
*
@@ -4865,7 +4882,8 @@ public static boolean putFloatForUser(ContentResolver cr, String name, float val
48654882
MOUNT_UMS_AUTOSTART,
48664883
MOUNT_UMS_PROMPT,
48674884
MOUNT_UMS_NOTIFY_ENABLED,
4868-
UI_NIGHT_MODE
4885+
UI_NIGHT_MODE,
4886+
SLEEP_TIMEOUT
48694887
};
48704888

48714889
/**

packages/SettingsProvider/res/values/defaults.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
<resources>
2020
<bool name="def_dim_screen">true</bool>
2121
<integer name="def_screen_off_timeout">60000</integer>
22+
<integer name="def_sleep_timeout">-1</integer>
2223
<bool name="def_airplane_mode_on">false</bool>
2324
<!-- Comma-separated list of bluetooth, wifi, and cell. -->
2425
<string name="def_airplane_mode_radios" translatable="false">cell,bluetooth,wifi,nfc,wimax</string>

packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ public class DatabaseHelper extends SQLiteOpenHelper {
7070
// database gets upgraded properly. At a minimum, please confirm that 'upgradeVersion'
7171
// is properly propagated through your change. Not doing so will result in a loss of user
7272
// settings.
73-
private static final int DATABASE_VERSION = 112;
73+
private static final int DATABASE_VERSION = 113;
7474

7575
private Context mContext;
7676
private int mUserHandle;
@@ -1811,6 +1811,22 @@ public void onUpgrade(SQLiteDatabase db, int oldVersion, int currentVersion) {
18111811
upgradeVersion = 112;
18121812
}
18131813

1814+
if (upgradeVersion < 113) {
1815+
db.beginTransaction();
1816+
SQLiteStatement stmt = null;
1817+
try {
1818+
stmt = db.compileStatement("INSERT OR IGNORE INTO secure(name,value)"
1819+
+ " VALUES(?,?);");
1820+
loadIntegerSetting(stmt, Settings.Secure.SLEEP_TIMEOUT,
1821+
R.integer.def_sleep_timeout);
1822+
db.setTransactionSuccessful();
1823+
} finally {
1824+
db.endTransaction();
1825+
if (stmt != null) stmt.close();
1826+
}
1827+
upgradeVersion = 113;
1828+
}
1829+
18141830
// *** Remember to update DATABASE_VERSION above!
18151831

18161832
if (upgradeVersion != currentVersion) {
@@ -2382,6 +2398,8 @@ private void loadSecureSettings(SQLiteDatabase db) {
23822398
loadBooleanSetting(stmt, Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS,
23832399
R.bool.def_lock_screen_allow_private_notifications);
23842400

2401+
loadIntegerSetting(stmt, Settings.Secure.SLEEP_TIMEOUT,
2402+
R.integer.def_sleep_timeout);
23852403
} finally {
23862404
if (stmt != null) stmt.close();
23872405
}

services/core/java/com/android/server/power/PowerManagerService.java

Lines changed: 57 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -142,10 +142,12 @@ public final class PowerManagerService extends SystemService
142142
// Summarizes the user activity state.
143143
private static final int USER_ACTIVITY_SCREEN_BRIGHT = 1 << 0;
144144
private static final int USER_ACTIVITY_SCREEN_DIM = 1 << 1;
145+
private static final int USER_ACTIVITY_SCREEN_DREAM = 1 << 2;
145146

146147
// Default timeout in milliseconds. This is only used until the settings
147148
// provider populates the actual default value (R.integer.def_screen_off_timeout).
148149
private static final int DEFAULT_SCREEN_OFF_TIMEOUT = 15 * 1000;
150+
private static final int DEFAULT_SLEEP_TIMEOUT = -1;
149151

150152
// Power hints defined in hardware/libhardware/include/hardware/power.h.
151153
private static final int POWER_HINT_INTERACTION = 2;
@@ -214,7 +216,6 @@ public final class PowerManagerService extends SystemService
214216
private long mLastInteractivePowerHintTime;
215217

216218
// A bitfield that summarizes the effect of the user activity timer.
217-
// A zero value indicates that the user activity timer has expired.
218219
private int mUserActivitySummary;
219220

220221
// The desired display power state. The actual state may lag behind the
@@ -340,6 +341,9 @@ public final class PowerManagerService extends SystemService
340341
// The screen off timeout setting value in milliseconds.
341342
private int mScreenOffTimeoutSetting;
342343

344+
// The sleep timeout setting value in milliseconds.
345+
private int mSleepTimeoutSetting;
346+
343347
// The maximum allowable screen off timeout according to the device
344348
// administration policy. Overrides other settings.
345349
private int mMaximumScreenOffTimeoutFromDeviceAdmin = Integer.MAX_VALUE;
@@ -543,6 +547,9 @@ mAppOps, createSuspendBlockerLocked("PowerManagerService.Broadcasts"),
543547
resolver.registerContentObserver(Settings.System.getUriFor(
544548
Settings.System.SCREEN_OFF_TIMEOUT),
545549
false, mSettingsObserver, UserHandle.USER_ALL);
550+
resolver.registerContentObserver(Settings.Secure.getUriFor(
551+
Settings.Secure.SLEEP_TIMEOUT),
552+
false, mSettingsObserver, UserHandle.USER_ALL);
546553
resolver.registerContentObserver(Settings.Global.getUriFor(
547554
Settings.Global.STAY_ON_WHILE_PLUGGED_IN),
548555
false, mSettingsObserver, UserHandle.USER_ALL);
@@ -624,6 +631,9 @@ private void updateSettingsLocked() {
624631
mScreenOffTimeoutSetting = Settings.System.getIntForUser(resolver,
625632
Settings.System.SCREEN_OFF_TIMEOUT, DEFAULT_SCREEN_OFF_TIMEOUT,
626633
UserHandle.USER_CURRENT);
634+
mSleepTimeoutSetting = Settings.Secure.getIntForUser(resolver,
635+
Settings.Secure.SLEEP_TIMEOUT, DEFAULT_SLEEP_TIMEOUT,
636+
UserHandle.USER_CURRENT);
627637
mStayOnWhilePluggedInSetting = Settings.Global.getInt(resolver,
628638
Settings.Global.STAY_ON_WHILE_PLUGGED_IN, BatteryManager.BATTERY_PLUGGED_AC);
629639

@@ -1431,19 +1441,20 @@ private void updateUserActivitySummaryLocked(long now, int dirty) {
14311441
if (mWakefulness == WAKEFULNESS_AWAKE
14321442
|| mWakefulness == WAKEFULNESS_DREAMING
14331443
|| mWakefulness == WAKEFULNESS_DOZING) {
1434-
final int screenOffTimeout = getScreenOffTimeoutLocked();
1444+
final int sleepTimeout = getSleepTimeoutLocked();
1445+
final int screenOffTimeout = getScreenOffTimeoutLocked(sleepTimeout);
14351446
final int screenDimDuration = getScreenDimDurationLocked(screenOffTimeout);
14361447

14371448
mUserActivitySummary = 0;
14381449
if (mLastUserActivityTime >= mLastWakeTime) {
14391450
nextTimeout = mLastUserActivityTime
14401451
+ screenOffTimeout - screenDimDuration;
14411452
if (now < nextTimeout) {
1442-
mUserActivitySummary |= USER_ACTIVITY_SCREEN_BRIGHT;
1453+
mUserActivitySummary = USER_ACTIVITY_SCREEN_BRIGHT;
14431454
} else {
14441455
nextTimeout = mLastUserActivityTime + screenOffTimeout;
14451456
if (now < nextTimeout) {
1446-
mUserActivitySummary |= USER_ACTIVITY_SCREEN_DIM;
1457+
mUserActivitySummary = USER_ACTIVITY_SCREEN_DIM;
14471458
}
14481459
}
14491460
}
@@ -1458,7 +1469,22 @@ private void updateUserActivitySummaryLocked(long now, int dirty) {
14581469
}
14591470
}
14601471
}
1461-
if (mUserActivitySummary != 0) {
1472+
if (mUserActivitySummary == 0) {
1473+
if (sleepTimeout >= 0) {
1474+
final long anyUserActivity = Math.max(mLastUserActivityTime,
1475+
mLastUserActivityTimeNoChangeLights);
1476+
if (anyUserActivity >= mLastWakeTime) {
1477+
nextTimeout = anyUserActivity + sleepTimeout;
1478+
if (now < nextTimeout) {
1479+
mUserActivitySummary = USER_ACTIVITY_SCREEN_DREAM;
1480+
}
1481+
}
1482+
} else {
1483+
mUserActivitySummary = USER_ACTIVITY_SCREEN_DREAM;
1484+
nextTimeout = -1;
1485+
}
1486+
}
1487+
if (mUserActivitySummary != 0 && nextTimeout >= 0) {
14621488
Message msg = mHandler.obtainMessage(MSG_USER_ACTIVITY_TIMEOUT);
14631489
msg.setAsynchronous(true);
14641490
mHandler.sendMessageAtTime(msg, nextTimeout);
@@ -1495,14 +1521,25 @@ private void handleUserActivityTimeout() { // runs on handler thread
14951521
}
14961522
}
14971523

1498-
private int getScreenOffTimeoutLocked() {
1524+
private int getSleepTimeoutLocked() {
1525+
int timeout = mSleepTimeoutSetting;
1526+
if (timeout <= 0) {
1527+
return -1;
1528+
}
1529+
return Math.max(timeout, mMinimumScreenOffTimeoutConfig);
1530+
}
1531+
1532+
private int getScreenOffTimeoutLocked(int sleepTimeout) {
14991533
int timeout = mScreenOffTimeoutSetting;
15001534
if (isMaximumScreenOffTimeoutFromDeviceAdminEnforcedLocked()) {
15011535
timeout = Math.min(timeout, mMaximumScreenOffTimeoutFromDeviceAdmin);
15021536
}
15031537
if (mUserActivityTimeoutOverrideFromWindowManager >= 0) {
15041538
timeout = (int)Math.min(timeout, mUserActivityTimeoutOverrideFromWindowManager);
15051539
}
1540+
if (sleepTimeout >= 0) {
1541+
timeout = Math.min(timeout, sleepTimeout);
1542+
}
15061543
return Math.max(timeout, mMinimumScreenOffTimeoutConfig);
15071544
}
15081545

@@ -1619,8 +1656,7 @@ private void handleSandman() { // runs on handler thread
16191656
mSandmanScheduled = false;
16201657
wakefulness = mWakefulness;
16211658
if (mSandmanSummoned && mDisplayReady) {
1622-
startDreaming = ((wakefulness == WAKEFULNESS_DREAMING && canDreamLocked())
1623-
|| wakefulness == WAKEFULNESS_DOZING);
1659+
startDreaming = canDreamLocked() || canDozeLocked();
16241660
mSandmanSummoned = false;
16251661
} else {
16261662
startDreaming = false;
@@ -1708,13 +1744,14 @@ private void handleSandman() { // runs on handler thread
17081744

17091745
/**
17101746
* Returns true if the device is allowed to dream in its current state.
1711-
* This function is not called when dozing.
17121747
*/
17131748
private boolean canDreamLocked() {
17141749
if (mWakefulness != WAKEFULNESS_DREAMING
17151750
|| !mDreamsSupportedConfig
17161751
|| !mDreamsEnabledSetting
17171752
|| !mDisplayPowerRequest.isBrightOrDim()
1753+
|| (mUserActivitySummary & (USER_ACTIVITY_SCREEN_BRIGHT
1754+
| USER_ACTIVITY_SCREEN_DIM | USER_ACTIVITY_SCREEN_DREAM)) == 0
17181755
|| !mBootCompleted) {
17191756
return false;
17201757
}
@@ -1736,6 +1773,13 @@ private boolean canDreamLocked() {
17361773
return true;
17371774
}
17381775

1776+
/**
1777+
* Returns true if the device is allowed to doze in its current state.
1778+
*/
1779+
private boolean canDozeLocked() {
1780+
return mWakefulness == WAKEFULNESS_DOZING;
1781+
}
1782+
17391783
/**
17401784
* Updates the display power state asynchronously.
17411785
* When the update is finished, mDisplayReady will be set to true. The display
@@ -2343,6 +2387,7 @@ private void dumpInternal(PrintWriter pw) {
23432387
pw.println(" mMaximumScreenDimDurationConfig=" + mMaximumScreenDimDurationConfig);
23442388
pw.println(" mMaximumScreenDimRatioConfig=" + mMaximumScreenDimRatioConfig);
23452389
pw.println(" mScreenOffTimeoutSetting=" + mScreenOffTimeoutSetting);
2390+
pw.println(" mSleepTimeoutSetting=" + mSleepTimeoutSetting);
23462391
pw.println(" mMaximumScreenOffTimeoutFromDeviceAdmin="
23472392
+ mMaximumScreenOffTimeoutFromDeviceAdmin + " (enforced="
23482393
+ isMaximumScreenOffTimeoutFromDeviceAdminEnforcedLocked() + ")");
@@ -2367,9 +2412,11 @@ private void dumpInternal(PrintWriter pw) {
23672412
pw.println(" mScreenBrightnessSettingMaximum=" + mScreenBrightnessSettingMaximum);
23682413
pw.println(" mScreenBrightnessSettingDefault=" + mScreenBrightnessSettingDefault);
23692414

2370-
final int screenOffTimeout = getScreenOffTimeoutLocked();
2415+
final int sleepTimeout = getSleepTimeoutLocked();
2416+
final int screenOffTimeout = getScreenOffTimeoutLocked(sleepTimeout);
23712417
final int screenDimDuration = getScreenDimDurationLocked(screenOffTimeout);
23722418
pw.println();
2419+
pw.println("Sleep timeout: " + sleepTimeout + " ms");
23732420
pw.println("Screen off timeout: " + screenOffTimeout + " ms");
23742421
pw.println("Screen dim duration: " + screenDimDuration + " ms");
23752422

0 commit comments

Comments
 (0)