Merge "Customize Max Screen Timeout" into main
This commit is contained in:
committed by
Android (Google) Code Review
commit
b09e60e9bd
@@ -859,6 +859,11 @@
|
|||||||
<!-- Disable the Testing Setting Menu for user builds, i.e only display the menu on userdebug/eng builds -->
|
<!-- Disable the Testing Setting Menu for user builds, i.e only display the menu on userdebug/eng builds -->
|
||||||
<bool name="config_hide_testing_settings_menu_for_user_builds">false</bool>
|
<bool name="config_hide_testing_settings_menu_for_user_builds">false</bool>
|
||||||
|
|
||||||
|
<!-- Configurable maximum screen timeout value shown in Screen timeout settings. Any timeout
|
||||||
|
values in R.arrays.screen_timeout_values that exceed this maximum will be hidden.
|
||||||
|
Leave empty to disable configuration and keep the default behavior. -->
|
||||||
|
<integer name="config_max_screen_timeout"></integer>
|
||||||
|
|
||||||
<!-- Whether the Gaze is enabled -->
|
<!-- Whether the Gaze is enabled -->
|
||||||
<bool name="config_gazeEnabled">false</bool>
|
<bool name="config_gazeEnabled">false</bool>
|
||||||
</resources>
|
</resources>
|
||||||
|
@@ -127,8 +127,6 @@ public class ScreenTimeoutSettings extends RadioButtonPickerFragment
|
|||||||
super.onAttach(context);
|
super.onAttach(context);
|
||||||
mContext = context;
|
mContext = context;
|
||||||
mDevicePolicyManager = mContext.getSystemService(DevicePolicyManager.class);
|
mDevicePolicyManager = mContext.getSystemService(DevicePolicyManager.class);
|
||||||
mInitialEntries = getResources().getStringArray(R.array.screen_timeout_entries);
|
|
||||||
mInitialValues = getResources().getStringArray(R.array.screen_timeout_values);
|
|
||||||
mAdaptiveSleepPermissionController =
|
mAdaptiveSleepPermissionController =
|
||||||
new AdaptiveSleepPermissionPreferenceController(context);
|
new AdaptiveSleepPermissionPreferenceController(context);
|
||||||
mAdaptiveSleepCameraStatePreferenceController =
|
mAdaptiveSleepCameraStatePreferenceController =
|
||||||
@@ -153,10 +151,14 @@ public class ScreenTimeoutSettings extends RadioButtonPickerFragment
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected List<? extends CandidateInfo> getCandidates() {
|
protected List<? extends CandidateInfo> getCandidates() {
|
||||||
|
mInitialEntries = getResources().getStringArray(R.array.screen_timeout_entries);
|
||||||
|
mInitialValues = getResources().getStringArray(R.array.screen_timeout_values);
|
||||||
|
|
||||||
final List<CandidateInfo> candidates = new ArrayList<>();
|
final List<CandidateInfo> candidates = new ArrayList<>();
|
||||||
final long maxTimeout = getMaxScreenTimeout(getContext());
|
final long maxTimeout = getMaxScreenTimeout(getContext());
|
||||||
if (mInitialValues != null) {
|
if (mInitialValues != null) {
|
||||||
for (int i = 0; i < mInitialValues.length; ++i) {
|
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) {
|
if (Long.parseLong(mInitialValues[i].toString()) <= maxTimeout) {
|
||||||
candidates.add(
|
candidates.add(
|
||||||
new TimeoutCandidateInfo(
|
new TimeoutCandidateInfo(
|
||||||
@@ -211,7 +213,7 @@ public class ScreenTimeoutSettings extends RadioButtonPickerFragment
|
|||||||
for (CandidateInfo info : candidateList) {
|
for (CandidateInfo info : candidateList) {
|
||||||
ProtectedSelectorWithWidgetPreference pref =
|
ProtectedSelectorWithWidgetPreference pref =
|
||||||
new ProtectedSelectorWithWidgetPreference(
|
new ProtectedSelectorWithWidgetPreference(
|
||||||
getPrefContext(), info.getKey(), this);
|
getContext(), info.getKey(), this);
|
||||||
bindPreference(pref, info.getKey(), info, defaultKey);
|
bindPreference(pref, info.getKey(), info, defaultKey);
|
||||||
screen.addPreference(pref);
|
screen.addPreference(pref);
|
||||||
}
|
}
|
||||||
@@ -219,12 +221,17 @@ public class ScreenTimeoutSettings extends RadioButtonPickerFragment
|
|||||||
final long selectedTimeout = getTimeoutFromKey(defaultKey);
|
final long selectedTimeout = getTimeoutFromKey(defaultKey);
|
||||||
final long maxTimeout = getMaxScreenTimeout(getContext());
|
final long maxTimeout = getMaxScreenTimeout(getContext());
|
||||||
if (!candidateList.isEmpty() && (selectedTimeout > maxTimeout)) {
|
if (!candidateList.isEmpty() && (selectedTimeout > maxTimeout)) {
|
||||||
// The selected time out value is longer than the max timeout allowed by the admin.
|
// The selected time out value is longer than the max timeout allowed by the
|
||||||
// Select the largest value from the list by default.
|
// 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 =
|
final ProtectedSelectorWithWidgetPreference preferenceWithLargestTimeout =
|
||||||
(ProtectedSelectorWithWidgetPreference)
|
(ProtectedSelectorWithWidgetPreference)
|
||||||
screen.getPreference(candidateList.size() - 1);
|
screen.getPreference(lastIndex);
|
||||||
preferenceWithLargestTimeout.setChecked(true);
|
preferenceWithLargestTimeout.setChecked(true);
|
||||||
|
// Update the system screen timeout setting to match the UI
|
||||||
|
setCurrentSystemScreenTimeout(getContext(), candidateList.get(lastIndex).getKey());
|
||||||
}
|
}
|
||||||
|
|
||||||
mPrivacyPreference = new FooterPreference(mContext);
|
mPrivacyPreference = new FooterPreference(mContext);
|
||||||
@@ -338,7 +345,11 @@ public class ScreenTimeoutSettings extends RadioButtonPickerFragment
|
|||||||
return R.string.help_url_adaptive_sleep;
|
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) {
|
private Long getMaxScreenTimeout(Context context) {
|
||||||
|
Long adminMaxTimeout = Long.MAX_VALUE;
|
||||||
|
Long configMaxTimeout = Long.MAX_VALUE;
|
||||||
if (context == null) {
|
if (context == null) {
|
||||||
return Long.MAX_VALUE;
|
return Long.MAX_VALUE;
|
||||||
}
|
}
|
||||||
@@ -346,11 +357,21 @@ public class ScreenTimeoutSettings extends RadioButtonPickerFragment
|
|||||||
if (dpm == null) {
|
if (dpm == null) {
|
||||||
return Long.MAX_VALUE;
|
return Long.MAX_VALUE;
|
||||||
}
|
}
|
||||||
mAdmin = RestrictedLockUtilsInternal.checkIfMaximumTimeToLockIsSet(context);
|
if (mAdmin == null) { // Don't overwrite mocked mAdmin
|
||||||
if (mAdmin != null) {
|
mAdmin = RestrictedLockUtilsInternal.checkIfMaximumTimeToLockIsSet(context);
|
||||||
return dpm.getMaximumTimeToLock(null /* admin */, UserHandle.myUserId());
|
|
||||||
}
|
}
|
||||||
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) {
|
private String getCurrentSystemScreenTimeout(Context context) {
|
||||||
|
@@ -28,6 +28,7 @@ import static org.mockito.ArgumentMatchers.isA;
|
|||||||
import static org.mockito.Mockito.atLeast;
|
import static org.mockito.Mockito.atLeast;
|
||||||
import static org.mockito.Mockito.doNothing;
|
import static org.mockito.Mockito.doNothing;
|
||||||
import static org.mockito.Mockito.doReturn;
|
import static org.mockito.Mockito.doReturn;
|
||||||
|
import static org.mockito.Mockito.doThrow;
|
||||||
import static org.mockito.Mockito.never;
|
import static org.mockito.Mockito.never;
|
||||||
import static org.mockito.Mockito.spy;
|
import static org.mockito.Mockito.spy;
|
||||||
import static org.mockito.Mockito.verify;
|
import static org.mockito.Mockito.verify;
|
||||||
@@ -80,8 +81,10 @@ public class ScreenTimeoutSettingsTest {
|
|||||||
@Rule
|
@Rule
|
||||||
public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule();
|
public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule();
|
||||||
|
|
||||||
private static final String[] TIMEOUT_ENTRIES = new String[]{"15 secs", "30 secs"};
|
private static final String[] TIMEOUT_ENTRIES =
|
||||||
private static final String[] TIMEOUT_VALUES = new String[]{"15000", "30000"};
|
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 ScreenTimeoutSettings mSettings;
|
||||||
private Context mContext;
|
private Context mContext;
|
||||||
@@ -109,6 +112,9 @@ public class ScreenTimeoutSettingsTest {
|
|||||||
@Mock
|
@Mock
|
||||||
FooterPreference mPowerConsumptionPreference;
|
FooterPreference mPowerConsumptionPreference;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
DevicePolicyManager mDevicePolicyManager;
|
||||||
|
|
||||||
@Mock
|
@Mock
|
||||||
private PackageManager mPackageManager;
|
private PackageManager mPackageManager;
|
||||||
|
|
||||||
@@ -132,7 +138,7 @@ public class ScreenTimeoutSettingsTest {
|
|||||||
attentionServiceResolveInfo);
|
attentionServiceResolveInfo);
|
||||||
|
|
||||||
doReturn(TIMEOUT_ENTRIES).when(mResources).getStringArray(R.array.screen_timeout_entries);
|
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(
|
doReturn(true).when(mResources).getBoolean(
|
||||||
com.android.internal.R.bool.config_adaptive_sleep_available);
|
com.android.internal.R.bool.config_adaptive_sleep_available);
|
||||||
|
|
||||||
@@ -223,6 +229,79 @@ public class ScreenTimeoutSettingsTest {
|
|||||||
verify(mPreferenceScreen, atLeast(1)).addPreference(mPowerConsumptionPreference);
|
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
|
@Test
|
||||||
public void setDefaultKey_controlCurrentScreenTimeout() {
|
public void setDefaultKey_controlCurrentScreenTimeout() {
|
||||||
mSettings.setDefaultKey(TIMEOUT_VALUES[0]);
|
mSettings.setDefaultKey(TIMEOUT_VALUES[0]);
|
||||||
|
Reference in New Issue
Block a user