Adding "quiescent" reboot mechanism to support STB operators
Bug: 31681185
Change-Id: Iada4dd4624f0221e5b59440da2718da980742720
Test: with SampleLeanbackDeviceAdmin. CTS test forthcoming
diff --git a/cmds/bootanimation/bootanimation_main.cpp b/cmds/bootanimation/bootanimation_main.cpp
index 48a34e7..dca7ea6 100644
--- a/cmds/bootanimation/bootanimation_main.cpp
+++ b/cmds/bootanimation/bootanimation_main.cpp
@@ -37,6 +37,10 @@
char value[PROPERTY_VALUE_MAX];
property_get("debug.sf.nobootanimation", value, "0");
int noBootAnimation = atoi(value);
+ if (!noBootAnimation) {
+ property_get("ro.boot.quiescent", value, "0");
+ noBootAnimation = atoi(value);
+ }
ALOGI_IF(noBootAnimation, "boot animation disabled");
if (!noBootAnimation) {
@@ -47,7 +51,6 @@
sp<BootAnimation> boot = new BootAnimation();
IPCThreadState::self()->joinThreadPool();
-
}
return 0;
}
diff --git a/core/java/android/os/PowerManager.java b/core/java/android/os/PowerManager.java
index 8d4d0a5..9d04929 100644
--- a/core/java/android/os/PowerManager.java
+++ b/core/java/android/os/PowerManager.java
@@ -421,6 +421,12 @@
public static final String REBOOT_SAFE_MODE = "safemode";
/**
+ * The 'reason' value used when rebooting the device without turning on the screen.
+ * @hide
+ */
+ public static final String REBOOT_QUIESCENT = "quiescent";
+
+ /**
* The value to pass as the 'reason' argument to android_reboot().
* @hide
*/
diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java
index 1790554..f2ccac5 100644
--- a/services/core/java/com/android/server/power/PowerManagerService.java
+++ b/services/core/java/com/android/server/power/PowerManagerService.java
@@ -134,6 +134,8 @@
private static final int DIRTY_DOCK_STATE = 1 << 10;
// Dirty bit: brightness boost changed
private static final int DIRTY_SCREEN_BRIGHTNESS_BOOST = 1 << 11;
+ // Dirty bit: sQuiescent changed
+ private static final int DIRTY_QUIESCENT = 1 << 12;
// Summarizes the state of all active wakelocks.
private static final int WAKE_LOCK_CPU = 1 << 0;
@@ -169,6 +171,9 @@
// Default setting for double tap to wake.
private static final int DEFAULT_DOUBLE_TAP_TO_WAKE = 0;
+ // System property indicating that the screen should remain off until an explicit user action
+ private static final String SYSTEM_PROPERTY_QUIESCENT = "ro.boot.quiescent";
+
/** Constants for {@link #shutdownOrRebootInternal} */
@Retention(RetentionPolicy.SOURCE)
@IntDef({HALT_MODE_SHUTDOWN, HALT_MODE_REBOOT, HALT_MODE_REBOOT_SAFE_MODE})
@@ -398,6 +403,9 @@
// True if the device should stay on.
private boolean mStayOn;
+ // True if the lights should stay off until an explicit user action.
+ private static boolean sQuiescent;
+
// True if the proximity sensor reads a positive result.
private boolean mProximityPositive;
@@ -530,6 +538,8 @@
mWakefulness = WAKEFULNESS_AWAKE;
+ sQuiescent = SystemProperties.get(SYSTEM_PROPERTY_QUIESCENT, "0").equals("1");
+
nativeInit();
nativeSetAutoSuspend(false);
nativeSetInteractive(true);
@@ -1190,12 +1200,19 @@
&& eventTime > mLastUserActivityTime) {
mLastUserActivityTimeNoChangeLights = eventTime;
mDirty |= DIRTY_USER_ACTIVITY;
+ if (event == PowerManager.USER_ACTIVITY_EVENT_BUTTON) {
+ mDirty |= DIRTY_QUIESCENT;
+ }
+
return true;
}
} else {
if (eventTime > mLastUserActivityTime) {
mLastUserActivityTime = eventTime;
mDirty |= DIRTY_USER_ACTIVITY;
+ if (event == PowerManager.USER_ACTIVITY_EVENT_BUTTON) {
+ mDirty |= DIRTY_QUIESCENT;
+ }
return true;
}
}
@@ -2096,7 +2113,7 @@
final boolean oldDisplayReady = mDisplayReady;
if ((dirty & (DIRTY_WAKE_LOCKS | DIRTY_USER_ACTIVITY | DIRTY_WAKEFULNESS
| DIRTY_ACTUAL_DISPLAY_POWER_STATE_UPDATED | DIRTY_BOOT_COMPLETED
- | DIRTY_SETTINGS | DIRTY_SCREEN_BRIGHTNESS_BOOST)) != 0) {
+ | DIRTY_SETTINGS | DIRTY_SCREEN_BRIGHTNESS_BOOST | DIRTY_QUIESCENT)) != 0) {
mDisplayPowerRequest.policy = getDesiredScreenPolicyLocked();
// Determine appropriate screen brightness and auto-brightness adjustments.
@@ -2163,6 +2180,9 @@
mRequestWaitForNegativeProximity);
mRequestWaitForNegativeProximity = false;
+ if ((dirty & DIRTY_QUIESCENT) != 0) {
+ sQuiescent = false;
+ }
if (DEBUG_SPEW) {
Slog.d(TAG, "updateDisplayPowerStateLocked: mDisplayReady=" + mDisplayReady
+ ", policy=" + mDisplayPowerRequest.policy
@@ -2170,8 +2190,8 @@
+ ", mWakeLockSummary=0x" + Integer.toHexString(mWakeLockSummary)
+ ", mUserActivitySummary=0x" + Integer.toHexString(mUserActivitySummary)
+ ", mBootCompleted=" + mBootCompleted
- + ", mScreenBrightnessBoostInProgress="
- + mScreenBrightnessBoostInProgress);
+ + ", mScreenBrightnessBoostInProgress=" + mScreenBrightnessBoostInProgress
+ + ", sQuiescent=" + sQuiescent);
}
}
return mDisplayReady && !oldDisplayReady;
@@ -2210,7 +2230,7 @@
}
private int getDesiredScreenPolicyLocked() {
- if (mWakefulness == WAKEFULNESS_ASLEEP) {
+ if (mWakefulness == WAKEFULNESS_ASLEEP || sQuiescent) {
return DisplayPowerRequest.POLICY_OFF;
}
@@ -2899,10 +2919,25 @@
}
if (reason.equals(PowerManager.REBOOT_RECOVERY)
|| reason.equals(PowerManager.REBOOT_RECOVERY_UPDATE)) {
- SystemProperties.set("sys.powerctl", "reboot,recovery");
- } else {
- SystemProperties.set("sys.powerctl", "reboot," + reason);
+ reason = "recovery";
}
+
+ // If the reason is "quiescent", it means that the boot process should proceed
+ // without turning on the screen/lights.
+ // The "quiescent" property is sticky, meaning that any number
+ // of subsequent reboots should honor the property until it is reset.
+ if (reason.equals(PowerManager.REBOOT_QUIESCENT)) {
+ sQuiescent = true;
+ reason = "";
+ }
+
+ if (sQuiescent) {
+ // Pass the optional "quiescent" argument to the bootloader to let it know
+ // that it should not turn the screen/lights on.
+ reason = reason + ",quiescent";
+ }
+
+ SystemProperties.set("sys.powerctl", "reboot," + reason);
try {
Thread.sleep(20 * 1000L);
} catch (InterruptedException e) {