diff options
| -rw-r--r-- | services/core/java/com/android/server/GestureLauncherService.java | 33 | ||||
| -rw-r--r-- | services/tests/servicestests/src/com/android/server/GestureLauncherServiceTest.java | 58 |
2 files changed, 79 insertions, 12 deletions
diff --git a/services/core/java/com/android/server/GestureLauncherService.java b/services/core/java/com/android/server/GestureLauncherService.java index 95a7a221697a..20f68da1592e 100644 --- a/services/core/java/com/android/server/GestureLauncherService.java +++ b/services/core/java/com/android/server/GestureLauncherService.java @@ -428,11 +428,18 @@ public class GestureLauncherService extends SystemService { mPowerButtonConsecutiveTaps++; mPowerButtonSlowConsecutiveTaps++; } - if (mPanicButtonGestureEnabled - && mPowerButtonConsecutiveTaps == PANIC_POWER_TAP_COUNT_THRESHOLD) { - launchPanic = true; - intercept = interactive; - } else if (mCameraDoubleTapPowerEnabled + // Check if we need to launch camera or panic flows + if (mPanicButtonGestureEnabled) { + // Commit to intercepting the powerkey event after the second "quick" tap to avoid + // lockscreen changes between launching camera and the panic flow. + if (mPowerButtonConsecutiveTaps > 1) { + intercept = interactive; + } + if (mPowerButtonConsecutiveTaps == PANIC_POWER_TAP_COUNT_THRESHOLD) { + launchPanic = true; + } + } + if (mCameraDoubleTapPowerEnabled && powerTapInterval < CAMERA_POWER_DOUBLE_TAP_MAX_TIME_MS && mPowerButtonConsecutiveTaps == CAMERA_POWER_TAP_COUNT_THRESHOLD) { launchCamera = true; @@ -462,8 +469,11 @@ public class GestureLauncherService extends SystemService { mMetricsLogger.histogram("power_consecutive_short_tap_count", mPowerButtonSlowConsecutiveTaps); mMetricsLogger.histogram("power_double_tap_interval", (int) powerTapInterval); + outLaunched.value = launchCamera || launchPanic; - return intercept && (launchCamera || launchPanic); + // Intercept power key event if the press is part of a gesture (camera, panic) and the user + // has completed setup. + return intercept && isUserSetupComplete(); } /** @@ -473,8 +483,7 @@ public class GestureLauncherService extends SystemService { boolean handleCameraGesture(boolean useWakelock, int source) { Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "GestureLauncher:handleCameraGesture"); try { - boolean userSetupComplete = Settings.Secure.getIntForUser(mContext.getContentResolver(), - Settings.Secure.USER_SETUP_COMPLETE, 0, UserHandle.USER_CURRENT) != 0; + boolean userSetupComplete = isUserSetupComplete(); if (!userSetupComplete) { if (DBG) { Slog.d(TAG, String.format( @@ -512,8 +521,7 @@ public class GestureLauncherService extends SystemService { Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "GestureLauncher:handlePanicButtonGesture"); try { - boolean userSetupComplete = Settings.Secure.getIntForUser(mContext.getContentResolver(), - Settings.Secure.USER_SETUP_COMPLETE, 0, UserHandle.USER_CURRENT) != 0; + boolean userSetupComplete = isUserSetupComplete(); if (!userSetupComplete) { if (DBG) { Slog.d(TAG, String.format( @@ -536,6 +544,11 @@ public class GestureLauncherService extends SystemService { } } + private boolean isUserSetupComplete() { + return Settings.Secure.getIntForUser(mContext.getContentResolver(), + Settings.Secure.USER_SETUP_COMPLETE, 0, UserHandle.USER_CURRENT) != 0; + } + private final BroadcastReceiver mUserReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { diff --git a/services/tests/servicestests/src/com/android/server/GestureLauncherServiceTest.java b/services/tests/servicestests/src/com/android/server/GestureLauncherServiceTest.java index 9a2ce3c598a4..d2d85c860cd5 100644 --- a/services/tests/servicestests/src/com/android/server/GestureLauncherServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/GestureLauncherServiceTest.java @@ -486,7 +486,7 @@ public class GestureLauncherServiceTest { outLaunched.value = false; intercepted = mGestureLauncherService.interceptPowerKeyDown(keyEvent, interactive, outLaunched); - assertFalse(intercepted); + assertTrue(intercepted); assertFalse(outLaunched.value); } @@ -538,7 +538,7 @@ public class GestureLauncherServiceTest { outLaunched.value = false; intercepted = mGestureLauncherService.interceptPowerKeyDown(keyEvent, interactive, outLaunched); - assertFalse(intercepted); + assertTrue(intercepted); assertFalse(outLaunched.value); } @@ -564,6 +564,60 @@ public class GestureLauncherServiceTest { } @Test + public void + testInterceptPowerKeyDown_tenInboundPresses_panicGestureEnabled_pressesIntercepted() { + withPanicGestureEnabledSettingValue(true); + mGestureLauncherService.updatePanicButtonGestureEnabled(); + withUserSetupCompleteValue(true); + + // First button press does nothing + long eventTime = INITIAL_EVENT_TIME_MILLIS; + KeyEvent keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE, + IGNORED_REPEAT); + boolean interactive = true; + MutableBoolean outLaunched = new MutableBoolean(true); + boolean intercepted = mGestureLauncherService.interceptPowerKeyDown(keyEvent, interactive, + outLaunched); + assertFalse(intercepted); + assertFalse(outLaunched.value); + + final long interval = GestureLauncherService.CAMERA_POWER_DOUBLE_TAP_MAX_TIME_MS - 1; + // 3 more button presses which should not trigger any gesture, but intercepts action. + for (int i = 0; i < 3; i++) { + eventTime += interval; + keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE, + IGNORED_REPEAT); + outLaunched.value = false; + intercepted = mGestureLauncherService.interceptPowerKeyDown(keyEvent, interactive, + outLaunched); + assertTrue(intercepted); + assertFalse(outLaunched.value); + } + + // Fifth button press should trigger the panic flow + eventTime += interval; + keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE, + IGNORED_REPEAT); + outLaunched.value = false; + intercepted = mGestureLauncherService.interceptPowerKeyDown(keyEvent, interactive, + outLaunched); + assertTrue(outLaunched.value); + assertTrue(intercepted); + + // 5 more button presses which should not trigger any gesture, but intercepts action. + for (int i = 0; i < 5; i++) { + eventTime += interval; + keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE, + IGNORED_REPEAT); + outLaunched.value = false; + intercepted = mGestureLauncherService.interceptPowerKeyDown(keyEvent, interactive, + outLaunched); + assertTrue(intercepted); + assertFalse(outLaunched.value); + } + } + + @Test public void testInterceptPowerKeyDown_longpress() { withCameraDoubleTapPowerEnableConfigValue(true); withCameraDoubleTapPowerDisableSettingValue(0); |