Fix 2579224: Add a separate timeout for lockscreen vs display
This change adds a second timeout to the SecuritySettings page
separate from the standard display timeout.
Change-Id: I033a3578d876148bd723dee5d1a2531be5d6b51d
diff --git a/res/values/arrays.xml b/res/values/arrays.xml
index 1a8e17b..0b44edd 100644
--- a/res/values/arrays.xml
+++ b/res/values/arrays.xml
@@ -72,7 +72,7 @@
<item>11</item>
</string-array>
- <!-- Display settings. The delay in inactivity before the screen is turned off. These are shown ain a list dialog. -->
+ <!-- Display settings. The delay in inactivity before the screen is turned off. These are shown in a list dialog. -->
<string-array name="screen_timeout_entries">
<item>15 seconds</item>
<item>30 seconds</item>
@@ -97,7 +97,40 @@
<!-- Do not translate. -->
<item>1800000</item>
</string-array>
+
+ <!-- Security settings. The delay after screen is turned off until device locks.
+ These are shown in a list dialog. -->
+ <string-array name="lock_after_timeout_entries">
+ <item>immediately</item>
+ <item>5 seconds</item>
+ <item>15 seconds</item>
+ <item>30 seconds</item>
+ <item>1 minute</item>
+ <item>2 minutes</item>
+ <item>10 minutes</item>
+ <item>30 minutes</item>
+ </string-array>
+ <!-- Do not translate. -->
+ <string-array name="lock_after_timeout_values" translatable="false">
+ <!-- Do not translate. -->
+ <item>0</item>
+ <!-- Do not translate. -->
+ <item>5000</item>
+ <!-- Do not translate. -->
+ <item>15000</item>
+ <!-- Do not translate. -->
+ <item>30000</item>
+ <!-- Do not translate. -->
+ <item>60000</item>
+ <!-- Do not translate. -->
+ <item>120000</item>
+ <!-- Do not translate. -->
+ <item>600000</item>
+ <!-- Do not translate. -->
+ <item>1800000</item>
+ </string-array>
+
<!-- TTS settings -->
<!-- Default speech rate choices -->
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 6e8082d..495608e 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -520,6 +520,11 @@
<!-- Security Settings --><skip />
+ <!-- Security settings screen, setting option name to change screen timeout -->
+ <string name="lock_after_timeout">Lock device after timeout</string>
+ <!-- Security settings screen, setting option summary to change screen timeout -->
+ <string name="lock_after_timeout_summary">Adjust the delay before the device automatically locks</string>
+
<!-- Main Settings screen setting option title for the item to take you the security and location screen -->
<string name="security_settings_title">Location & security</string>
<!-- Location & security settings screen title -->
diff --git a/res/xml/security_settings_password.xml b/res/xml/security_settings_password.xml
index ac06711..6411091 100644
--- a/res/xml/security_settings_password.xml
+++ b/res/xml/security_settings_password.xml
@@ -20,6 +20,14 @@
android:key="security_category"
android:title="@string/lock_settings_title">
+ <ListPreference
+ android:key="lock_after_timeout"
+ android:title="@string/lock_after_timeout"
+ android:summary="@string/lock_after_timeout_summary"
+ android:entries="@array/lock_after_timeout_entries"
+ android:entryValues="@array/lock_after_timeout_values"
+ android:persistent="false"/>
+
<PreferenceScreen
android:key="unlock_set_or_change"
android:title="@string/unlock_set_unlock_launch_picker_change_title"
diff --git a/res/xml/security_settings_pattern.xml b/res/xml/security_settings_pattern.xml
index 095828a..200c260 100644
--- a/res/xml/security_settings_pattern.xml
+++ b/res/xml/security_settings_pattern.xml
@@ -20,6 +20,14 @@
android:key="security_category"
android:title="@string/lock_settings_title">
+ <ListPreference
+ android:key="lock_after_timeout"
+ android:title="@string/lock_after_timeout"
+ android:summary="@string/lock_after_timeout_summary"
+ android:entries="@array/lock_after_timeout_entries"
+ android:entryValues="@array/lock_after_timeout_values"
+ android:persistent="false"/>
+
<PreferenceScreen
android:key="unlock_set_or_change"
android:title="@string/unlock_set_unlock_launch_picker_change_title"
diff --git a/res/xml/security_settings_pin.xml b/res/xml/security_settings_pin.xml
index ac06711..31fa110 100644
--- a/res/xml/security_settings_pin.xml
+++ b/res/xml/security_settings_pin.xml
@@ -20,6 +20,14 @@
android:key="security_category"
android:title="@string/lock_settings_title">
+ <ListPreference
+ android:key="lock_after_timeout"
+ android:title="@string/lock_after_timeout"
+ android:summary="@string/lock_after_timeout_summary"
+ android:entries="@array/lock_after_timeout_entries"
+ android:entryValues="@array/lock_after_timeout_values"
+ android:persistent="false"/>
+
<PreferenceScreen
android:key="unlock_set_or_change"
android:title="@string/unlock_set_unlock_launch_picker_change_title"
diff --git a/src/com/android/settings/SecuritySettings.java b/src/com/android/settings/SecuritySettings.java
index e618448..287e312 100644
--- a/src/com/android/settings/SecuritySettings.java
+++ b/src/com/android/settings/SecuritySettings.java
@@ -17,6 +17,8 @@
package com.android.settings;
+import static android.provider.Settings.System.SCREEN_OFF_TIMEOUT;
+
import com.android.internal.widget.LockPatternUtils;
import android.app.AlertDialog;
@@ -32,25 +34,30 @@
import android.os.Bundle;
import android.os.SystemProperties;
import android.preference.CheckBoxPreference;
+import android.preference.ListPreference;
import android.preference.Preference;
import android.preference.PreferenceCategory;
import android.preference.PreferenceManager;
import android.preference.PreferenceScreen;
+import android.preference.Preference.OnPreferenceChangeListener;
import android.provider.Settings;
import android.security.Credentials;
import android.security.KeyStore;
import android.telephony.TelephonyManager;
+import android.util.Log;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;
+import java.util.ArrayList;
import java.util.Observable;
import java.util.Observer;
/**
* Gesture lock pattern settings.
*/
-public class SecuritySettings extends SettingsPreferenceFragment {
+public class SecuritySettings extends SettingsPreferenceFragment
+ implements OnPreferenceChangeListener {
private static final String KEY_UNLOCK_SET_OR_CHANGE = "unlock_set_or_change";
// Lock Settings
@@ -74,7 +81,9 @@
private static final String LOCATION_NETWORK = "location_network";
private static final String LOCATION_GPS = "location_gps";
private static final String ASSISTED_GPS = "assisted_gps";
+ private static final String LOCK_AFTER_TIMEOUT_KEY = "lock_after_timeout";
private static final int SET_OR_CHANGE_LOCK_METHOD_REQUEST = 123;
+ private static final int FALLBACK_LOCK_AFTER_TIMEOUT_VALUE = 5000; // compatible with pre-Froyo
// Credential storage
private CredentialStorage mCredentialStorage = new CredentialStorage();
@@ -92,8 +101,11 @@
// This is necessary because the Network Location Provider can change settings
// if the user does not confirm enabling the provider.
private ContentQueryMap mContentQueryMap;
+
private ChooseLockSettingsHelper mChooseLockSettingsHelper;
private LockPatternUtils mLockPatternUtils;
+ private ListPreference mLockAfter;
+
private final class SettingsObserver implements Observer {
public void update(Observable o, Object arg) {
updateToggles();
@@ -156,8 +168,8 @@
}
}
- // set or change current. Should be common to all unlock preference screens
- // mSetOrChange = (PreferenceScreen) pm.findPreference(KEY_UNLOCK_SET_OR_CHANGE);
+ // lock after preference
+ mLockAfter = setupLockAfterPreference(pm);
// visible pattern
mVisiblePattern = (CheckBoxPreference) pm.findPreference(KEY_VISIBLE_PATTERN);
@@ -220,10 +232,65 @@
return root;
}
+ private ListPreference setupLockAfterPreference(PreferenceManager pm) {
+ ListPreference result = (ListPreference) pm.findPreference(LOCK_AFTER_TIMEOUT_KEY);
+ if (result != null) {
+ int lockAfterValue = Settings.Secure.getInt(getContentResolver(),
+ Settings.Secure.LOCK_SCREEN_LOCK_AFTER_TIMEOUT,
+ FALLBACK_LOCK_AFTER_TIMEOUT_VALUE);
+ result.setValue(String.valueOf(lockAfterValue));
+ result.setOnPreferenceChangeListener(this);
+ final long adminTimeout = mDPM != null ? mDPM.getMaximumTimeToLock(null) : 0;
+ final ContentResolver cr = getContentResolver();
+ final long displayTimeout = Math.max(0,
+ Settings.System.getInt(cr, SCREEN_OFF_TIMEOUT, 0));
+ if (adminTimeout > 0) {
+ // This setting is a slave to display timeout when a device policy is enforced.
+ // As such, maxLockTimeout = adminTimeout - displayTimeout.
+ // If there isn't enough time, shows "immediately" setting.
+ disableUnusableTimeouts(result, Math.max(0, adminTimeout - displayTimeout));
+ }
+ }
+ return result;
+ }
+
+ private static void disableUnusableTimeouts(ListPreference pref, long maxTimeout) {
+ final CharSequence[] entries = pref.getEntries();
+ final CharSequence[] values = pref.getEntryValues();
+ ArrayList<CharSequence> revisedEntries = new ArrayList<CharSequence>();
+ ArrayList<CharSequence> revisedValues = new ArrayList<CharSequence>();
+ for (int i = 0; i < values.length; i++) {
+ long timeout = Long.valueOf(values[i].toString());
+ if (timeout <= maxTimeout) {
+ revisedEntries.add(entries[i]);
+ revisedValues.add(values[i]);
+ }
+ }
+ if (revisedEntries.size() != entries.length || revisedValues.size() != values.length) {
+ pref.setEntries(
+ revisedEntries.toArray(new CharSequence[revisedEntries.size()]));
+ pref.setEntryValues(
+ revisedValues.toArray(new CharSequence[revisedValues.size()]));
+ final int userPreference = Integer.valueOf(pref.getValue());
+ if (userPreference <= maxTimeout) {
+ pref.setValue(String.valueOf(userPreference));
+ } else {
+ // There will be no highlighted selection since nothing in the list matches
+ // maxTimeout. The user can still select anything less than maxTimeout.
+ // TODO: maybe append maxTimeout to the list and mark selected.
+ }
+ }
+ pref.setEnabled(revisedEntries.size() > 0);
+ }
+
@Override
public void onResume() {
super.onResume();
+ // Make sure we reload the preference hierarchy since some of these settings
+ // depend on others...
+ createPreferenceHierarchy();
+
final LockPatternUtils lockPatternUtils = mChooseLockSettingsHelper.utils();
if (mVisiblePattern != null) {
mVisiblePattern.setChecked(lockPatternUtils.isVisiblePatternEnabled());
@@ -393,7 +460,7 @@
Boolean bval = (Boolean)value;
mWillEnableEncryptedFS = bval.booleanValue();
showSwitchEncryptedFSDialog();
- }
+ }
return true;
}
@@ -659,4 +726,17 @@
}
}
}
+
+ public boolean onPreferenceChange(Preference preference, Object value) {
+ if (preference == mLockAfter) {
+ int lockAfter = Integer.parseInt((String) value);
+ try {
+ Settings.Secure.putInt(getContentResolver(),
+ Settings.Secure.LOCK_SCREEN_LOCK_AFTER_TIMEOUT, lockAfter);
+ } catch (NumberFormatException e) {
+ Log.e("SecuritySettings", "could not persist lockAfter timeout setting", e);
+ }
+ }
+ return true;
+ }
}