Fix 4560303: Add setting to lock later when power button pressed

This adds a feature to delay locking the device when the power button
is pressed.  This fixes a use case where the user wants to turn off
the display (e.g. to save power) but doesn't want to lock the device.

For the case of a secure device (user has a pin/password/pattern),
this will lock the device immediately or not based on the setting.

For the non-secure case, this always "locks" the device to provide easy
access to the camera while preventing unwanted input.

Change-Id: Ie328485c3f7559e26896d761cbf0e69d3f4df4e2
diff --git a/core/java/com/android/internal/widget/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java
index 89f9d4e..76d161d 100644
--- a/core/java/com/android/internal/widget/LockPatternUtils.java
+++ b/core/java/com/android/internal/widget/LockPatternUtils.java
@@ -117,6 +117,8 @@
             = "lockscreen.biometric_weak_fallback";
     public final static String BIOMETRIC_WEAK_EVER_CHOSEN_KEY
             = "lockscreen.biometricweakeverchosen";
+    public final static String LOCKSCREEN_POWER_BUTTON_INSTANTLY_LOCKS
+            = "lockscreen.power_button_instantly_locks";
 
     private final static String PASSWORD_HISTORY_KEY = "lockscreen.passwordhistory";
 
@@ -335,7 +337,7 @@
      * @return True if the user has ever chosen a pattern.
      */
     public boolean isPatternEverChosen() {
-        return getBoolean(PATTERN_EVER_CHOSEN_KEY);
+        return getBoolean(PATTERN_EVER_CHOSEN_KEY, false);
     }
 
     /**
@@ -345,7 +347,7 @@
      * @return True if the user has ever chosen biometric weak.
      */
     public boolean isBiometricWeakEverChosen() {
-        return getBoolean(BIOMETRIC_WEAK_EVER_CHOSEN_KEY);
+        return getBoolean(BIOMETRIC_WEAK_EVER_CHOSEN_KEY, false);
     }
 
     /**
@@ -838,7 +840,7 @@
                 getLong(PASSWORD_TYPE_ALTERNATE_KEY, DevicePolicyManager.PASSWORD_QUALITY_SOMETHING)
                 == DevicePolicyManager.PASSWORD_QUALITY_SOMETHING;
 
-        return getBoolean(Settings.Secure.LOCK_PATTERN_ENABLED)
+        return getBoolean(Settings.Secure.LOCK_PATTERN_ENABLED, false)
                 && (getLong(PASSWORD_TYPE_KEY, DevicePolicyManager.PASSWORD_QUALITY_SOMETHING)
                         == DevicePolicyManager.PASSWORD_QUALITY_SOMETHING ||
                         (usingBiometricWeak() && backupEnabled));
@@ -884,7 +886,7 @@
      * @return Whether the visible pattern is enabled.
      */
     public boolean isVisiblePatternEnabled() {
-        return getBoolean(Settings.Secure.LOCK_PATTERN_VISIBLE);
+        return getBoolean(Settings.Secure.LOCK_PATTERN_VISIBLE, false);
     }
 
     /**
@@ -898,7 +900,7 @@
      * @return Whether tactile feedback for the pattern is enabled.
      */
     public boolean isTactileFeedbackEnabled() {
-        return getBoolean(Settings.Secure.LOCK_PATTERN_TACTILE_FEEDBACK_ENABLED);
+        return getBoolean(Settings.Secure.LOCK_PATTERN_TACTILE_FEEDBACK_ENABLED, false);
     }
 
     /**
@@ -939,7 +941,7 @@
      *   attempts.
      */
     public boolean isPermanentlyLocked() {
-        return getBoolean(LOCKOUT_PERMANENT_KEY);
+        return getBoolean(LOCKOUT_PERMANENT_KEY, false);
     }
 
     /**
@@ -982,9 +984,10 @@
         return nextAlarm;
     }
 
-    private boolean getBoolean(String secureSettingKey) {
+    private boolean getBoolean(String secureSettingKey, boolean defaultValue) {
         return 1 ==
-                android.provider.Settings.Secure.getInt(mContentResolver, secureSettingKey, 0);
+                android.provider.Settings.Secure.getInt(mContentResolver, secureSettingKey,
+                        defaultValue ? 1 : 0);
     }
 
     private void setBoolean(String secureSettingKey, boolean enabled) {
@@ -1085,4 +1088,12 @@
         mContext.startActivity(intent);
     }
 
+    public void setPowerButtonInstantlyLocks(boolean enabled) {
+        setBoolean(LOCKSCREEN_POWER_BUTTON_INSTANTLY_LOCKS, enabled);
+    }
+
+    public boolean getPowerButtonInstantlyLocks() {
+        return getBoolean(LOCKSCREEN_POWER_BUTTON_INSTANTLY_LOCKS, true);
+    }
+
 }
diff --git a/policy/src/com/android/internal/policy/impl/KeyguardViewMediator.java b/policy/src/com/android/internal/policy/impl/KeyguardViewMediator.java
index b514689..52d6d24 100644
--- a/policy/src/com/android/internal/policy/impl/KeyguardViewMediator.java
+++ b/policy/src/com/android/internal/policy/impl/KeyguardViewMediator.java
@@ -350,6 +350,12 @@
             mScreenOn = false;
             if (DEBUG) Log.d(TAG, "onScreenTurnedOff(" + why + ")");
 
+            // Lock immediately based on setting if secure (user has a pin/pattern/password).
+            // This also "locks" the device when not secure to provide easy access to the
+            // camera while preventing unwanted input.
+            final boolean lockImmediately =
+                mLockPatternUtils.getPowerButtonInstantlyLocks() || !mLockPatternUtils.isSecure();
+
             if (mExitSecureCallback != null) {
                 if (DEBUG) Log.d(TAG, "pending exit secure callback cancelled");
                 mExitSecureCallback.onKeyguardExitResult(false);
@@ -360,8 +366,10 @@
             } else if (mShowing) {
                 notifyScreenOffLocked();
                 resetStateLocked();
-            } else if (why == WindowManagerPolicy.OFF_BECAUSE_OF_TIMEOUT) {
-                // if the screen turned off because of timeout, set an alarm
+            } else if (why == WindowManagerPolicy.OFF_BECAUSE_OF_TIMEOUT
+                   || (why == WindowManagerPolicy.OFF_BECAUSE_OF_USER && !lockImmediately)) {
+                // if the screen turned off because of timeout or the user hit the power button
+                // and we don't need to lock immediately, set an alarm
                 // to enable it a little bit later (i.e, give the user a chance
                 // to turn the screen back on within a certain window without
                 // having to unlock the screen)
@@ -400,8 +408,7 @@
                     intent.putExtra("seq", mDelayedShowingSequence);
                     PendingIntent sender = PendingIntent.getBroadcast(mContext,
                             0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
-                    mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, when,
-                            sender);
+                    mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, when, sender);
                     if (DEBUG) Log.d(TAG, "setting alarm to turn off keyguard, seq = "
                                      + mDelayedShowingSequence);
                 }