Merge "Fix maximum time to lock" into sc-dev
diff --git a/src/com/android/settings/display/ScreenTimeoutPreferenceController.java b/src/com/android/settings/display/ScreenTimeoutPreferenceController.java
index c44376c..2a3359a 100644
--- a/src/com/android/settings/display/ScreenTimeoutPreferenceController.java
+++ b/src/com/android/settings/display/ScreenTimeoutPreferenceController.java
@@ -40,8 +40,13 @@
 public class ScreenTimeoutPreferenceController extends BasePreferenceController {
     public static String PREF_NAME = "screen_timeout";
 
+    private final CharSequence[] mTimeoutEntries;
+    private final CharSequence[] mTimeoutValues;
+
     public ScreenTimeoutPreferenceController(Context context, String key) {
         super(context, key);
+        mTimeoutEntries = context.getResources().getStringArray(R.array.screen_timeout_entries);
+        mTimeoutValues = context.getResources().getStringArray(R.array.screen_timeout_values);
     }
 
     @Override
@@ -51,33 +56,51 @@
 
     @Override
     public void updateState(Preference preference) {
-        final RestrictedLockUtils.EnforcedAdmin admin = getEnforcedAdmin();
+        final long maxTimeout = getMaxScreenTimeout();
+        final RestrictedLockUtils.EnforcedAdmin admin = getPreferenceDisablingAdmin(maxTimeout);
         if (admin != null) {
             preference.setEnabled(false);
+            preference.setSummary(mContext.getText(R.string.disabled_by_policy_title));
             ((RestrictedPreference) preference).setDisabledByAdmin(admin);
+        } else {
+            preference.setSummary(getTimeoutSummary(maxTimeout));
         }
-        preference.setSummary(getTimeoutSummary());
     }
 
-    private CharSequence getTimeoutSummary() {
+    private CharSequence getTimeoutSummary(long maxTimeout) {
         final long currentTimeout = getCurrentScreenTimeout();
-        final CharSequence[] timeoutEntries = mContext.getResources().getStringArray(
-                R.array.screen_timeout_entries);
-        final CharSequence[] timeoutValues = mContext.getResources().getStringArray(
-                R.array.screen_timeout_values);
-        final CharSequence description = getTimeoutDescription(
-                currentTimeout, timeoutEntries, timeoutValues);
+        final CharSequence description = getTimeoutDescription(currentTimeout, maxTimeout);
         return mContext.getString(R.string.screen_timeout_summary, description);
     }
 
-    private RestrictedLockUtils.EnforcedAdmin getEnforcedAdmin() {
+    private Long getMaxScreenTimeout() {
+        if (RestrictedLockUtilsInternal.checkIfMaximumTimeToLockIsSet(mContext) != null) {
+            final DevicePolicyManager dpm = mContext.getSystemService(DevicePolicyManager.class);
+            if (dpm != null) {
+                return dpm.getMaximumTimeToLock(null /* admin */, UserHandle.myUserId());
+            }
+        }
+        return Long.MAX_VALUE;
+    }
+
+    /**
+     * Returns the admin that causes the preference to be disabled completely. This could be due to
+     * either an admin that has set the {@link UserManager.DISALLOW_CONFIG_SCREEN_TIMEOUT}
+     * restriction, or an admin that has set a very small MaximumTimeToLock timeout resulting in
+     * no possible options for the user.
+     */
+    private RestrictedLockUtils.EnforcedAdmin getPreferenceDisablingAdmin(long maxTimeout) {
         final DevicePolicyManager dpm = mContext.getSystemService(DevicePolicyManager.class);
+        RestrictedLockUtils.EnforcedAdmin admin = null;
         if (dpm != null) {
-            return RestrictedLockUtilsInternal.checkIfRestrictionEnforced(
+            admin = RestrictedLockUtilsInternal.checkIfRestrictionEnforced(
                     mContext, UserManager.DISALLOW_CONFIG_SCREEN_TIMEOUT,
                     UserHandle.myUserId());
+            if (admin == null && getLargestTimeout(maxTimeout) == null) {
+                admin = RestrictedLockUtilsInternal.checkIfMaximumTimeToLockIsSet(mContext);
+            }
         }
-        return null;
+        return admin;
     }
 
     private long getCurrentScreenTimeout() {
@@ -85,19 +108,38 @@
                 SCREEN_OFF_TIMEOUT, FALLBACK_SCREEN_TIMEOUT_VALUE);
     }
 
-    private static CharSequence getTimeoutDescription(
-            long currentTimeout, CharSequence[] entries, CharSequence[] values) {
-        if (currentTimeout < 0 || entries == null || values == null
-                || values.length != entries.length) {
+    private CharSequence getTimeoutDescription(long currentTimeout, long maxTimeout) {
+        if (currentTimeout < 0 || mTimeoutEntries == null || mTimeoutValues == null
+                || mTimeoutValues.length != mTimeoutEntries.length) {
             return null;
         }
 
-        for (int i = 0; i < values.length; i++) {
-            long timeout = Long.parseLong(values[i].toString());
-            if (currentTimeout == timeout) {
-                return entries[i];
+        if (currentTimeout > maxTimeout) {
+            // The selected time out value is longer than the max timeout allowed by the admin.
+            // Select the largest value from the list by default.
+            return getLargestTimeout(maxTimeout);
+        } else {
+            return getCurrentTimeout(currentTimeout);
+        }
+    }
+
+    private CharSequence getCurrentTimeout(long currentTimeout) {
+        for (int i = 0; i < mTimeoutValues.length; i++) {
+            if (currentTimeout == Long.parseLong(mTimeoutValues[i].toString())) {
+                return mTimeoutEntries[i];
             }
         }
         return null;
     }
+
+    private CharSequence getLargestTimeout(long maxTimeout) {
+        CharSequence largestTimeout = null;
+        // The list of timeouts is sorted
+        for (int i = 0; i < mTimeoutValues.length; ++i) {
+            if (Long.parseLong(mTimeoutValues[i].toString()) <= maxTimeout) {
+                largestTimeout = mTimeoutEntries[i];
+            }
+        }
+        return largestTimeout;
+    }
 }
diff --git a/src/com/android/settings/display/ScreenTimeoutSettings.java b/src/com/android/settings/display/ScreenTimeoutSettings.java
index 3c2a4f1..444f8ef8 100644
--- a/src/com/android/settings/display/ScreenTimeoutSettings.java
+++ b/src/com/android/settings/display/ScreenTimeoutSettings.java
@@ -159,6 +159,16 @@
             screen.addPreference(pref);
         }
 
+        final long selectedTimeout = Long.parseLong(defaultKey);
+        final long maxTimeout = getMaxScreenTimeout(getContext());
+        if (!candidateList.isEmpty() && (selectedTimeout > maxTimeout)) {
+            // The selected time out value is longer than the max timeout allowed by the admin.
+            // Select the largest value from the list by default.
+            final RadioButtonPreference preferenceWithLargestTimeout =
+                    (RadioButtonPreference) screen.getPreference(candidateList.size() - 1);
+            preferenceWithLargestTimeout.setChecked(true);
+        }
+
         if (isScreenAttentionAvailable(getContext())) {
             mAdaptiveSleepPermissionController.addToScreen(screen);
             mAdaptiveSleepCameraStatePreferenceController.addToScreen(screen);