diff options
| author | 2019-04-09 17:02:38 +0100 | |
|---|---|---|
| committer | 2019-04-23 11:55:29 +0100 | |
| commit | 623526b4b37f2fd2c364ad75dacf09a99cbc02cb (patch) | |
| tree | 9c56b11f4f60a6fdf45620f72fd435f1cf5a640b | |
| parent | ec4c269f94c8278ddb1c5a48f62525a460bd038a (diff) | |
Add delay to power-button power-off after gesture wakeup.
Adds a small delay to avoid turning off the device if the user
hits the power button right after the device wakes up via a gesture.
Bug: 126560003
Test: Manual
Change-Id: I3116ce98f244e5660573d5fa764a77083aee7fc5
6 files changed, 84 insertions, 6 deletions
diff --git a/core/java/android/os/PowerManager.java b/core/java/android/os/PowerManager.java index 7d61bf6f3986..2fff595d7150 100644 --- a/core/java/android/os/PowerManager.java +++ b/core/java/android/os/PowerManager.java @@ -555,6 +555,18 @@ public final class PowerManager { } /** + * @hide + */ + public static class WakeData { + public WakeData(long wakeTime, @WakeReason int wakeReason) { + this.wakeTime = wakeTime; + this.wakeReason = wakeReason; + } + public long wakeTime; + public @WakeReason int wakeReason; + } + + /** * The value to pass as the 'reason' argument to reboot() to reboot into * recovery mode for tasks other than applying system updates, such as * doing factory resets. diff --git a/core/java/android/os/PowerManagerInternal.java b/core/java/android/os/PowerManagerInternal.java index d55489a08136..9661a08464dd 100644 --- a/core/java/android/os/PowerManagerInternal.java +++ b/core/java/android/os/PowerManagerInternal.java @@ -203,4 +203,7 @@ public abstract class PowerManagerInternal { /** Returns whether there hasn't been a user activity event for the given number of ms. */ public abstract boolean wasDeviceIdleFor(long ms); + + /** Returns information about the last wakeup event. */ + public abstract PowerManager.WakeData getLastWakeup(); } diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index ac59101d4090..58b70a7fa05b 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -14712,6 +14712,18 @@ public final class Settings { public static final String TEXT_CLASSIFIER_ACTION_MODEL_PARAMS = "text_classifier_action_model_params"; + /** + * The amount of time to suppress "power-off" from the power button after the device has + * woken due to a gesture (lifting the phone). Since users have learned to hit the power + * button immediately when lifting their device, it can cause the device to turn off if a + * gesture has just woken the device. This value tells us the milliseconds to wait after + * a gesture before "power-off" via power-button is functional again. A value of 0 is no + * delay, and reverts to the old behavior. + * + * @hide + */ + public static final String POWER_BUTTON_SUPPRESSION_DELAY_AFTER_GESTURE_WAKE = + "power_button_suppression_delay_after_gesture_wake"; } /** diff --git a/core/tests/coretests/src/android/provider/SettingsBackupTest.java b/core/tests/coretests/src/android/provider/SettingsBackupTest.java index a853121bac4e..f4d3c8163e9c 100644 --- a/core/tests/coretests/src/android/provider/SettingsBackupTest.java +++ b/core/tests/coretests/src/android/provider/SettingsBackupTest.java @@ -392,6 +392,7 @@ public class SettingsBackupTest { Settings.Global.PDP_WATCHDOG_POLL_INTERVAL_MS, Settings.Global.PDP_WATCHDOG_TRIGGER_PACKET_COUNT, Settings.Global.POLICY_CONTROL, + Settings.Global.POWER_BUTTON_SUPPRESSION_DELAY_AFTER_GESTURE_WAKE, Settings.Global.POWER_MANAGER_CONSTANTS, Settings.Global.PREFERRED_NETWORK_MODE, Settings.Global.PRIVATE_DNS_DEFAULT_MODE, diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java index 9b4293d484bc..3eb7f9591169 100644 --- a/services/core/java/com/android/server/policy/PhoneWindowManager.java +++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java @@ -310,6 +310,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { static public final String SYSTEM_DIALOG_REASON_ASSIST = "assist"; static public final String SYSTEM_DIALOG_REASON_SCREENSHOT = "screenshot"; + private static final int POWER_BUTTON_SUPPRESSION_DELAY_DEFAULT_MILLIS = 800; private static final AudioAttributes VIBRATION_ATTRIBUTES = new AudioAttributes.Builder() .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION) .setUsage(AudioAttributes.USAGE_ASSISTANCE_SONIFICATION) @@ -615,6 +616,8 @@ public class PhoneWindowManager implements WindowManagerPolicy { private boolean mPerDisplayFocusEnabled = false; private volatile int mTopFocusedDisplayId = INVALID_DISPLAY; + private int mPowerButtonSuppressionDelayMillis = POWER_BUTTON_SUPPRESSION_DELAY_DEFAULT_MILLIS; + private static final int MSG_DISPATCH_MEDIA_KEY_WITH_WAKE_LOCK = 3; private static final int MSG_DISPATCH_MEDIA_KEY_REPEAT_WITH_WAKE_LOCK = 4; private static final int MSG_KEYGUARD_DRAWN_COMPLETE = 5; @@ -782,6 +785,9 @@ public class PhoneWindowManager implements WindowManagerPolicy { resolver.registerContentObserver(Settings.Global.getUriFor( Settings.Global.POWER_BUTTON_VERY_LONG_PRESS), false, this, UserHandle.USER_ALL); + resolver.registerContentObserver(Settings.Global.getUriFor( + Settings.Global.POWER_BUTTON_SUPPRESSION_DELAY_AFTER_GESTURE_WAKE), false, this, + UserHandle.USER_ALL); updateSettings(); } @@ -1105,16 +1111,16 @@ public class PhoneWindowManager implements WindowManagerPolicy { case SHORT_PRESS_POWER_NOTHING: break; case SHORT_PRESS_POWER_GO_TO_SLEEP: - goToSleep(eventTime, PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON, 0); + goToSleepFromPowerButton(eventTime, 0); break; case SHORT_PRESS_POWER_REALLY_GO_TO_SLEEP: - goToSleep(eventTime, PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON, - PowerManager.GO_TO_SLEEP_FLAG_NO_DOZE); + goToSleepFromPowerButton(eventTime, PowerManager.GO_TO_SLEEP_FLAG_NO_DOZE); break; case SHORT_PRESS_POWER_REALLY_GO_TO_SLEEP_AND_GO_HOME: - goToSleep(eventTime, PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON, - PowerManager.GO_TO_SLEEP_FLAG_NO_DOZE); - launchHomeFromHotKey(DEFAULT_DISPLAY); + if (goToSleepFromPowerButton(eventTime, + PowerManager.GO_TO_SLEEP_FLAG_NO_DOZE)) { + launchHomeFromHotKey(DEFAULT_DISPLAY); + } break; case SHORT_PRESS_POWER_GO_HOME: shortPressPowerGoHome(); @@ -1137,6 +1143,35 @@ public class PhoneWindowManager implements WindowManagerPolicy { } } + /** + * Sends the device to sleep as a result of a power button press. + * + * @return True if the was device was sent to sleep, false if sleep was suppressed. + */ + private boolean goToSleepFromPowerButton(long eventTime, int flags) { + // Before we actually go to sleep, we check the last wakeup reason. + // If the device very recently woke up from a gesture (like user lifting their device) + // then ignore the sleep instruction. This is because users have developed + // a tendency to hit the power button immediately when they pick up their device, and we + // don't want to put the device back to sleep in those cases. + final PowerManager.WakeData lastWakeUp = mPowerManagerInternal.getLastWakeup(); + if (lastWakeUp != null && lastWakeUp.wakeReason == PowerManager.WAKE_REASON_GESTURE) { + final int gestureDelayMillis = Settings.Global.getInt(mContext.getContentResolver(), + Settings.Global.POWER_BUTTON_SUPPRESSION_DELAY_AFTER_GESTURE_WAKE, + POWER_BUTTON_SUPPRESSION_DELAY_DEFAULT_MILLIS); + final long now = SystemClock.uptimeMillis(); + if (mPowerButtonSuppressionDelayMillis > 0 + && (now < lastWakeUp.wakeTime + mPowerButtonSuppressionDelayMillis)) { + Slog.i(TAG, "Sleep from power button suppressed. Time since gesture: " + + (now - lastWakeUp.wakeTime) + "ms"); + return false; + } + } + + goToSleep(eventTime, PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON, flags); + return true; + } + private void goToSleep(long eventTime, int reason, int flags) { mRequestedOrGoingToSleep = true; mPowerManager.goToSleep(eventTime, reason, flags); @@ -1981,6 +2016,9 @@ public class PhoneWindowManager implements WindowManagerPolicy { mRingerToggleChord = Settings.Secure.getIntForUser(resolver, Settings.Secure.VOLUME_HUSH_GESTURE, VOLUME_HUSH_OFF, UserHandle.USER_CURRENT); + mPowerButtonSuppressionDelayMillis = Settings.Global.getInt(resolver, + Settings.Global.POWER_BUTTON_SUPPRESSION_DELAY_AFTER_GESTURE_WAKE, + POWER_BUTTON_SUPPRESSION_DELAY_DEFAULT_MILLIS); if (!mContext.getResources() .getBoolean(com.android.internal.R.bool.config_volumeHushGestureEnabled)) { mRingerToggleChord = Settings.Secure.VOLUME_HUSH_OFF; diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java index cfe11bfb4347..e2bbb2dc2dc5 100644 --- a/services/core/java/com/android/server/power/PowerManagerService.java +++ b/services/core/java/com/android/server/power/PowerManagerService.java @@ -52,6 +52,7 @@ import android.os.Looper; import android.os.Message; import android.os.PowerManager; import android.os.PowerManager.ServiceType; +import android.os.PowerManager.WakeData; import android.os.PowerManager.WakeReason; import android.os.PowerManagerInternal; import android.os.PowerSaveState; @@ -4850,6 +4851,12 @@ public final class PowerManagerService extends SystemService } } + private PowerManager.WakeData getLastWakeupInternal() { + synchronized (mLock) { + return new WakeData(mLastWakeTime, mLastWakeReason); + } + } + private final class LocalService extends PowerManagerInternal { @Override public void setScreenBrightnessOverrideFromWindowManager(int screenBrightness) { @@ -4971,5 +4978,10 @@ public final class PowerManagerService extends SystemService public boolean wasDeviceIdleFor(long ms) { return wasDeviceIdleForInternal(ms); } + + @Override + public WakeData getLastWakeup() { + return getLastWakeupInternal(); + } } } |