diff --git a/core/java/com/android/internal/policy/IKeyguardService.aidl b/core/java/com/android/internal/policy/IKeyguardService.aidl index e330de24f6d60..171a264eea8b2 100644 --- a/core/java/com/android/internal/policy/IKeyguardService.aidl +++ b/core/java/com/android/internal/policy/IKeyguardService.aidl @@ -50,9 +50,12 @@ oneway interface IKeyguardService { * Called when the device has finished going to sleep. * * @param why {@link #OFF_BECAUSE_OF_USER}, {@link #OFF_BECAUSE_OF_ADMIN}, - * or {@link #OFF_BECAUSE_OF_TIMEOUT}. + * or {@link #OFF_BECAUSE_OF_TIMEOUT}. + * @param cameraGestureTriggered whether the camera gesture was triggered between + * {@link #onStartedGoingToSleep} and this method; if it's been + * triggered, we shouldn't lock the device. */ - void onFinishedGoingToSleep(int reason); + void onFinishedGoingToSleep(int reason, boolean cameraGestureTriggered); /** * Called when the device has started waking up. diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java index d2c60efd12820..84d359926c50a 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java +++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java @@ -115,9 +115,9 @@ public class KeyguardService extends Service { } @Override // Binder interface - public void onFinishedGoingToSleep(int reason) { + public void onFinishedGoingToSleep(int reason, boolean cameraGestureTriggered) { checkPermission(); - mKeyguardViewMediator.onFinishedGoingToSleep(reason); + mKeyguardViewMediator.onFinishedGoingToSleep(reason, cameraGestureTriggered); } @Override // Binder interface diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java index a5dfc4b2ad85a..e00bf6cc792d8 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java +++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java @@ -747,7 +747,7 @@ public class KeyguardViewMediator extends SystemUI { notifyStartedGoingToSleep(); } - public void onFinishedGoingToSleep(int why) { + public void onFinishedGoingToSleep(int why, boolean cameraGestureTriggered) { if (DEBUG) Log.d(TAG, "onFinishedGoingToSleep(" + why + ")"); synchronized (this) { mDeviceInteractive = false; @@ -758,6 +758,16 @@ public class KeyguardViewMediator extends SystemUI { notifyFinishedGoingToSleep(); + if (cameraGestureTriggered) { + Log.i(TAG, "Camera gesture was triggered, preventing Keyguard locking."); + + // Just to make sure, make sure the device is awake. + mContext.getSystemService(PowerManager.class).wakeUp(SystemClock.uptimeMillis(), + "com.android.systemui:CAMERA_GESTURE_PREVENT_LOCK"); + mPendingLock = false; + mPendingReset = false; + } + if (mPendingReset) { resetStateLocked(); mPendingReset = false; @@ -771,7 +781,7 @@ public class KeyguardViewMediator extends SystemUI { // We do not have timeout and power button instant lock setting for profile lock. // So we use the personal setting if there is any. But if there is no device // we need to make sure we lock it immediately when the screen is off. - if (!mLockLater) { + if (!mLockLater && !cameraGestureTriggered) { doKeyguardForChildProfilesLocked(); } diff --git a/services/core/java/com/android/server/GestureLauncherService.java b/services/core/java/com/android/server/GestureLauncherService.java index d6575e84352d7..aa986489e1c2e 100644 --- a/services/core/java/com/android/server/GestureLauncherService.java +++ b/services/core/java/com/android/server/GestureLauncherService.java @@ -34,6 +34,7 @@ import android.os.PowerManager.WakeLock; import android.os.SystemClock; import android.os.SystemProperties; import android.provider.Settings; +import android.util.MutableBoolean; import android.util.Slog; import android.view.KeyEvent; @@ -251,7 +252,8 @@ public class GestureLauncherService extends SystemService { return isCameraLaunchEnabled(resources) || isCameraDoubleTapPowerEnabled(resources); } - public boolean interceptPowerKeyDown(KeyEvent event, boolean interactive) { + public boolean interceptPowerKeyDown(KeyEvent event, boolean interactive, + MutableBoolean outLaunched) { boolean launched = false; boolean intercept = false; long doubleTapInterval; @@ -276,6 +278,7 @@ public class GestureLauncherService extends SystemService { } } MetricsLogger.histogram(mContext, "power_double_tap_interval", (int) doubleTapInterval); + outLaunched.value = launched; return intercept && launched; } diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java index 14d0457e41c10..e2225f569f13c 100644 --- a/services/core/java/com/android/server/policy/PhoneWindowManager.java +++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java @@ -107,6 +107,7 @@ import android.telecom.TelecomManager; import android.util.DisplayMetrics; import android.util.EventLog; import android.util.Log; +import android.util.MutableBoolean; import android.util.Slog; import android.util.SparseArray; import android.util.LongSparseArray; @@ -396,6 +397,8 @@ public class PhoneWindowManager implements WindowManagerPolicy { volatile boolean mBeganFromNonInteractive; volatile int mPowerKeyPressCounter; volatile boolean mEndCallKeyHandled; + volatile boolean mCameraGestureTriggeredDuringGoingToSleep; + volatile boolean mGoingToSleep; boolean mRecentsVisible; int mRecentAppsHeldModifiers; @@ -685,6 +688,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { = new LogDecelerateInterpolator(100, 0); private boolean mForceWindowDrawsStatusBarBackground; + private final MutableBoolean mTmpBoolean = new MutableBoolean(false); private static final int MSG_ENABLE_POINTER_LOCATION = 1; private static final int MSG_DISABLE_POINTER_LOCATION = 2; @@ -1032,7 +1036,11 @@ public class PhoneWindowManager implements WindowManagerPolicy { GestureLauncherService.class); boolean gesturedServiceIntercepted = false; if (gestureService != null) { - gesturedServiceIntercepted = gestureService.interceptPowerKeyDown(event, interactive); + gesturedServiceIntercepted = gestureService.interceptPowerKeyDown(event, interactive, + mTmpBoolean); + if (mTmpBoolean.value && mGoingToSleep) { + mCameraGestureTriggeredDuringGoingToSleep = true; + } } // If the power key has still not yet been handled, then detect short @@ -5948,6 +5956,8 @@ public class PhoneWindowManager implements WindowManagerPolicy { @Override public void startedGoingToSleep(int why) { if (DEBUG_WAKEUP) Slog.i(TAG, "Started going to sleep... (why=" + why + ")"); + mCameraGestureTriggeredDuringGoingToSleep = false; + mGoingToSleep = true; if (mKeyguardDelegate != null) { mKeyguardDelegate.onStartedGoingToSleep(why); } @@ -5960,6 +5970,8 @@ public class PhoneWindowManager implements WindowManagerPolicy { if (DEBUG_WAKEUP) Slog.i(TAG, "Finished going to sleep... (why=" + why + ")"); MetricsLogger.histogram(mContext, "screen_timeout", mLockScreenTimeout / 1000); + mGoingToSleep = false; + // We must get this work done here because the power manager will drop // the wake lock and let the system suspend once this function returns. synchronized (mLock) { @@ -5969,8 +5981,10 @@ public class PhoneWindowManager implements WindowManagerPolicy { updateLockScreenTimeout(); } if (mKeyguardDelegate != null) { - mKeyguardDelegate.onFinishedGoingToSleep(why); + mKeyguardDelegate.onFinishedGoingToSleep(why, + mCameraGestureTriggeredDuringGoingToSleep); } + mCameraGestureTriggeredDuringGoingToSleep = false; } // Called on the PowerManager's Notifier thread. diff --git a/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java b/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java index 8d296d505c4ce..52e5880151776 100644 --- a/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java +++ b/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java @@ -294,9 +294,9 @@ public class KeyguardServiceDelegate { mKeyguardState.interactiveState = INTERACTIVE_STATE_GOING_TO_SLEEP; } - public void onFinishedGoingToSleep(int why) { + public void onFinishedGoingToSleep(int why, boolean cameraGestureTriggered) { if (mKeyguardService != null) { - mKeyguardService.onFinishedGoingToSleep(why); + mKeyguardService.onFinishedGoingToSleep(why, cameraGestureTriggered); } mKeyguardState.interactiveState = INTERACTIVE_STATE_SLEEP; } diff --git a/services/core/java/com/android/server/policy/keyguard/KeyguardServiceWrapper.java b/services/core/java/com/android/server/policy/keyguard/KeyguardServiceWrapper.java index 429b18866a61a..dacdec042a458 100644 --- a/services/core/java/com/android/server/policy/keyguard/KeyguardServiceWrapper.java +++ b/services/core/java/com/android/server/policy/keyguard/KeyguardServiceWrapper.java @@ -117,9 +117,9 @@ public class KeyguardServiceWrapper implements IKeyguardService { } @Override - public void onFinishedGoingToSleep(int reason) { + public void onFinishedGoingToSleep(int reason, boolean cameraGestureTriggered) { try { - mService.onFinishedGoingToSleep(reason); + mService.onFinishedGoingToSleep(reason, cameraGestureTriggered); } catch (RemoteException e) { Slog.w(TAG , "Remote Exception", e); }