diff --git a/res/values/config.xml b/res/values/config.xml
index 9d2e43df985..ea16af46e11 100644
--- a/res/values/config.xml
+++ b/res/values/config.xml
@@ -859,6 +859,11 @@
false
+
+
+
false
diff --git a/src/com/android/settings/display/ScreenTimeoutSettings.java b/src/com/android/settings/display/ScreenTimeoutSettings.java
index d4ca48ebfb7..b00dfec4d9d 100644
--- a/src/com/android/settings/display/ScreenTimeoutSettings.java
+++ b/src/com/android/settings/display/ScreenTimeoutSettings.java
@@ -127,8 +127,6 @@ public class ScreenTimeoutSettings extends RadioButtonPickerFragment
super.onAttach(context);
mContext = context;
mDevicePolicyManager = mContext.getSystemService(DevicePolicyManager.class);
- mInitialEntries = getResources().getStringArray(R.array.screen_timeout_entries);
- mInitialValues = getResources().getStringArray(R.array.screen_timeout_values);
mAdaptiveSleepPermissionController =
new AdaptiveSleepPermissionPreferenceController(context);
mAdaptiveSleepCameraStatePreferenceController =
@@ -153,10 +151,14 @@ public class ScreenTimeoutSettings extends RadioButtonPickerFragment
@Override
protected List extends CandidateInfo> getCandidates() {
+ mInitialEntries = getResources().getStringArray(R.array.screen_timeout_entries);
+ mInitialValues = getResources().getStringArray(R.array.screen_timeout_values);
+
final List candidates = new ArrayList<>();
final long maxTimeout = getMaxScreenTimeout(getContext());
if (mInitialValues != null) {
for (int i = 0; i < mInitialValues.length; ++i) {
+ // Truncate mInitialEntries/Values so that they do not exceed maxTimeout
if (Long.parseLong(mInitialValues[i].toString()) <= maxTimeout) {
candidates.add(
new TimeoutCandidateInfo(
@@ -211,7 +213,7 @@ public class ScreenTimeoutSettings extends RadioButtonPickerFragment
for (CandidateInfo info : candidateList) {
ProtectedSelectorWithWidgetPreference pref =
new ProtectedSelectorWithWidgetPreference(
- getPrefContext(), info.getKey(), this);
+ getContext(), info.getKey(), this);
bindPreference(pref, info.getKey(), info, defaultKey);
screen.addPreference(pref);
}
@@ -219,12 +221,17 @@ public class ScreenTimeoutSettings extends RadioButtonPickerFragment
final long selectedTimeout = getTimeoutFromKey(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.
+ // The selected time out value is longer than the max timeout allowed by the
+ // admin/configuration. The list of candidates is already truncated so that
+ // no value exceeds the max timeout value.
+ // Select the largest value from the candidates list by default.
+ int lastIndex = candidateList.size() - 1;
final ProtectedSelectorWithWidgetPreference preferenceWithLargestTimeout =
(ProtectedSelectorWithWidgetPreference)
- screen.getPreference(candidateList.size() - 1);
+ screen.getPreference(lastIndex);
preferenceWithLargestTimeout.setChecked(true);
+ // Update the system screen timeout setting to match the UI
+ setCurrentSystemScreenTimeout(getContext(), candidateList.get(lastIndex).getKey());
}
mPrivacyPreference = new FooterPreference(mContext);
@@ -338,7 +345,11 @@ public class ScreenTimeoutSettings extends RadioButtonPickerFragment
return R.string.help_url_adaptive_sleep;
}
+ // Get the maximum screen timeout as governed by admin and/or configuration.
+ // Returns the lowest timeout (admin/config) or Long.MAX_VALUE.
private Long getMaxScreenTimeout(Context context) {
+ Long adminMaxTimeout = Long.MAX_VALUE;
+ Long configMaxTimeout = Long.MAX_VALUE;
if (context == null) {
return Long.MAX_VALUE;
}
@@ -346,11 +357,21 @@ public class ScreenTimeoutSettings extends RadioButtonPickerFragment
if (dpm == null) {
return Long.MAX_VALUE;
}
- mAdmin = RestrictedLockUtilsInternal.checkIfMaximumTimeToLockIsSet(context);
- if (mAdmin != null) {
- return dpm.getMaximumTimeToLock(null /* admin */, UserHandle.myUserId());
+ if (mAdmin == null) { // Don't overwrite mocked mAdmin
+ mAdmin = RestrictedLockUtilsInternal.checkIfMaximumTimeToLockIsSet(context);
}
- return Long.MAX_VALUE;
+ if (mAdmin != null) {
+ // Get the admin max screen timeout
+ adminMaxTimeout = dpm.getMaximumTimeToLock(null /* admin */, UserHandle.myUserId());
+ }
+ try {
+ // Get the configurable max screen timeout
+ configMaxTimeout = Long.valueOf(
+ context.getResources().getInteger(R.integer.config_max_screen_timeout));
+ } catch (Resources.NotFoundException e) {
+ // Do nothing
+ }
+ return Math.min(adminMaxTimeout, configMaxTimeout);
}
private String getCurrentSystemScreenTimeout(Context context) {
diff --git a/tests/robotests/src/com/android/settings/display/ScreenTimeoutSettingsTest.java b/tests/robotests/src/com/android/settings/display/ScreenTimeoutSettingsTest.java
index 1a6a1128068..c50547dbb0b 100644
--- a/tests/robotests/src/com/android/settings/display/ScreenTimeoutSettingsTest.java
+++ b/tests/robotests/src/com/android/settings/display/ScreenTimeoutSettingsTest.java
@@ -28,6 +28,7 @@ import static org.mockito.ArgumentMatchers.isA;
import static org.mockito.Mockito.atLeast;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
@@ -80,8 +81,10 @@ public class ScreenTimeoutSettingsTest {
@Rule
public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule();
- private static final String[] TIMEOUT_ENTRIES = new String[]{"15 secs", "30 secs"};
- private static final String[] TIMEOUT_VALUES = new String[]{"15000", "30000"};
+ private static final String[] TIMEOUT_ENTRIES =
+ new String[]{"15 secs", "30 secs", "1 min", "2 min", "5 min"};
+ private static final String[] TIMEOUT_VALUES =
+ new String[]{"15000", "30000", "60000", "120000", "300000"};
private ScreenTimeoutSettings mSettings;
private Context mContext;
@@ -109,6 +112,9 @@ public class ScreenTimeoutSettingsTest {
@Mock
FooterPreference mPowerConsumptionPreference;
+ @Mock
+ DevicePolicyManager mDevicePolicyManager;
+
@Mock
private PackageManager mPackageManager;
@@ -132,7 +138,7 @@ public class ScreenTimeoutSettingsTest {
attentionServiceResolveInfo);
doReturn(TIMEOUT_ENTRIES).when(mResources).getStringArray(R.array.screen_timeout_entries);
- doReturn(TIMEOUT_VALUES).when(mResources).getStringArray(R.array.screen_timeout_entries);
+ doReturn(TIMEOUT_VALUES).when(mResources).getStringArray(R.array.screen_timeout_values);
doReturn(true).when(mResources).getBoolean(
com.android.internal.R.bool.config_adaptive_sleep_available);
@@ -223,6 +229,79 @@ public class ScreenTimeoutSettingsTest {
verify(mPreferenceScreen, atLeast(1)).addPreference(mPowerConsumptionPreference);
}
+ @Test
+ public void getCandidates_enforcedAdmin_timeoutIsLimited() {
+ mSettings.mAdmin = new RestrictedLockUtils.EnforcedAdmin();
+ mSettings.mDisableOptionsPreference = mDisableOptionsPreference;
+ doNothing().when(mSettings).setupDisabledFooterPreference();
+ doReturn(mDevicePolicyManager).when(mContext).getSystemService(DevicePolicyManager.class);
+ // Admin-enforced max timeout of 30000
+ when(mDevicePolicyManager.getMaximumTimeToLock(any(), anyInt())).thenReturn(30000L);
+ // No configured max timeout
+ doThrow(new Resources.NotFoundException("Invalid resource")).when(mResources)
+ .getInteger(R.integer.config_max_screen_timeout);
+
+ List extends CandidateInfo> candidates = mSettings.getCandidates();
+
+ // Assert that candidates are truncated at the admin-controlled timeout
+ assertThat(candidates.size()).isEqualTo(2);
+ assertThat(candidates.get(candidates.size() - 1).getKey()).isEqualTo(TIMEOUT_VALUES[1]);
+ }
+
+ @Test
+ public void getCandidates_configuredMaxTimeout_65000_timeoutIsLimited() {
+ when(mContext.getSystemService(DevicePolicyManager.class)).thenCallRealMethod();
+ doReturn(65000).when(mResources).getInteger(R.integer.config_max_screen_timeout);
+
+ List extends CandidateInfo> candidates = mSettings.getCandidates();
+
+ // Assert that candidates are truncated at the highest timeout that is below the max timeout
+ assertThat(candidates.size()).isEqualTo(3);
+ assertThat(candidates.get(candidates.size() - 1).getKey()).isEqualTo(TIMEOUT_VALUES[2]);
+ }
+
+ @Test
+ public void getCandidates_configuredAndAdminEnforcedMaxTimeout_lowestTimeoutIsApplied() {
+ mSettings.mAdmin = new RestrictedLockUtils.EnforcedAdmin();
+ mSettings.mDisableOptionsPreference = mDisableOptionsPreference;
+ doNothing().when(mSettings).setupDisabledFooterPreference();
+ doReturn(mDevicePolicyManager).when(mContext).getSystemService(DevicePolicyManager.class);
+ // Admin-enforced max timeout of 30000
+ when(mDevicePolicyManager.getMaximumTimeToLock(any(), anyInt())).thenReturn(30000L);
+ // Configured max timeout of 120000
+ doReturn(120000).when(mResources).getInteger(R.integer.config_max_screen_timeout);
+
+ List extends CandidateInfo> candidates = mSettings.getCandidates();
+
+ // Assert that candidates are truncated at the lowest of the two timeouts
+ assertThat(candidates.size()).isEqualTo(2);
+ assertThat(candidates.get(candidates.size() - 1).getKey()).isEqualTo(TIMEOUT_VALUES[1]);
+ }
+
+ @Test
+ public void getCandidates_configuredMaxTimeout_300000_timeoutIsNotLimited() {
+ when(mContext.getSystemService(DevicePolicyManager.class)).thenCallRealMethod();
+ doReturn(300000).when(mResources).getInteger(R.integer.config_max_screen_timeout);
+
+ List extends CandidateInfo> candidates = mSettings.getCandidates();
+
+ // Assert that candidates are not truncated if configured max timeout is higher than the
+ // highest available timeout
+ assertThat(candidates.size()).isEqualTo(TIMEOUT_VALUES.length);
+ }
+
+ @Test
+ public void getCandidates_configuredMaxTimeout_notSet_timeoutIsNotLimited() {
+ when(mContext.getSystemService(DevicePolicyManager.class)).thenCallRealMethod();
+ doThrow(new Resources.NotFoundException("Invalid resource")).when(mResources)
+ .getInteger(R.integer.config_max_screen_timeout);
+
+ List extends CandidateInfo> candidates = mSettings.getCandidates();
+
+ // Assert that candidates are not truncated if there is no configured max timeout
+ assertThat(candidates.size()).isEqualTo(TIMEOUT_VALUES.length);
+ }
+
@Test
public void setDefaultKey_controlCurrentScreenTimeout() {
mSettings.setDefaultKey(TIMEOUT_VALUES[0]);