Add auth challenge for increasing screen timeout.
We only require one auth after onStart(), and only for increasing the timeout. Test: atest SettingsRoboTests:com.android.settings.display.ScreenTimeoutSettingsTest Test: also manually tested Bug: 315937886 Change-Id: If4aed67736cd7545d3a518aadd8253ea6a9fae43
This commit is contained in:
@@ -37,10 +37,12 @@ import android.util.Log;
|
||||
import androidx.preference.PreferenceScreen;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.flags.Flags;
|
||||
import com.android.settings.overlay.FeatureFactory;
|
||||
import com.android.settings.search.BaseSearchIndexProvider;
|
||||
import com.android.settings.support.actionbar.HelpResourceProvider;
|
||||
import com.android.settings.widget.RadioButtonPickerFragment;
|
||||
import com.android.settings.wifi.dpp.WifiDppUtils;
|
||||
import com.android.settingslib.RestrictedLockUtils;
|
||||
import com.android.settingslib.RestrictedLockUtilsInternal;
|
||||
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
|
||||
@@ -55,13 +57,12 @@ import com.google.common.annotations.VisibleForTesting;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Fragment that is used to control screen timeout.
|
||||
*/
|
||||
/** Fragment that is used to control screen timeout. */
|
||||
@SearchIndexable(forTarget = SearchIndexable.ALL & ~SearchIndexable.ARC)
|
||||
public class ScreenTimeoutSettings extends RadioButtonPickerFragment implements
|
||||
HelpResourceProvider {
|
||||
public class ScreenTimeoutSettings extends RadioButtonPickerFragment
|
||||
implements HelpResourceProvider {
|
||||
private static final String TAG = "ScreenTimeout";
|
||||
|
||||
/** If there is no setting in the provider, use this. */
|
||||
public static final int FALLBACK_SCREEN_TIMEOUT_VALUE = 30000;
|
||||
|
||||
@@ -72,25 +73,24 @@ public class ScreenTimeoutSettings extends RadioButtonPickerFragment implements
|
||||
private FooterPreference mPrivacyPreference;
|
||||
private final MetricsFeatureProvider mMetricsFeatureProvider;
|
||||
private SensorPrivacyManager mPrivacyManager;
|
||||
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
mAdaptiveSleepBatterySaverPreferenceController.updateVisibility();
|
||||
mAdaptiveSleepController.updatePreference();
|
||||
}
|
||||
};
|
||||
private final BroadcastReceiver mReceiver =
|
||||
new BroadcastReceiver() {
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
mAdaptiveSleepBatterySaverPreferenceController.updateVisibility();
|
||||
mAdaptiveSleepController.updatePreference();
|
||||
}
|
||||
};
|
||||
|
||||
private DevicePolicyManager mDevicePolicyManager;
|
||||
private SensorPrivacyManager.OnSensorPrivacyChangedListener mPrivacyChangedListener;
|
||||
private boolean mIsUserAuthenticated = false;
|
||||
|
||||
@VisibleForTesting
|
||||
Context mContext;
|
||||
@VisibleForTesting Context mContext;
|
||||
|
||||
@VisibleForTesting
|
||||
RestrictedLockUtils.EnforcedAdmin mAdmin;
|
||||
@VisibleForTesting RestrictedLockUtils.EnforcedAdmin mAdmin;
|
||||
|
||||
@VisibleForTesting
|
||||
FooterPreference mDisableOptionsPreference;
|
||||
@VisibleForTesting FooterPreference mDisableOptionsPreference;
|
||||
|
||||
@VisibleForTesting
|
||||
FooterPreference mPowerConsumptionPreference;
|
||||
@@ -101,16 +101,14 @@ public class ScreenTimeoutSettings extends RadioButtonPickerFragment implements
|
||||
@VisibleForTesting
|
||||
AdaptiveSleepCameraStatePreferenceController mAdaptiveSleepCameraStatePreferenceController;
|
||||
|
||||
@VisibleForTesting
|
||||
AdaptiveSleepPreferenceController mAdaptiveSleepController;
|
||||
@VisibleForTesting AdaptiveSleepPreferenceController mAdaptiveSleepController;
|
||||
|
||||
@VisibleForTesting
|
||||
AdaptiveSleepBatterySaverPreferenceController mAdaptiveSleepBatterySaverPreferenceController;
|
||||
|
||||
public ScreenTimeoutSettings() {
|
||||
super();
|
||||
mMetricsFeatureProvider = FeatureFactory.getFeatureFactory()
|
||||
.getMetricsFeatureProvider();
|
||||
mMetricsFeatureProvider = FeatureFactory.getFeatureFactory().getMetricsFeatureProvider();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -121,8 +119,8 @@ public class ScreenTimeoutSettings extends RadioButtonPickerFragment implements
|
||||
mInitialEntries = getResources().getStringArray(R.array.screen_timeout_entries);
|
||||
mInitialValues = getResources().getStringArray(R.array.screen_timeout_values);
|
||||
mAdaptiveSleepController = new AdaptiveSleepPreferenceController(context);
|
||||
mAdaptiveSleepPermissionController = new AdaptiveSleepPermissionPreferenceController(
|
||||
context);
|
||||
mAdaptiveSleepPermissionController =
|
||||
new AdaptiveSleepPermissionPreferenceController(context);
|
||||
mAdaptiveSleepCameraStatePreferenceController =
|
||||
new AdaptiveSleepCameraStatePreferenceController(context, getLifecycle());
|
||||
mAdaptiveSleepBatterySaverPreferenceController =
|
||||
@@ -144,8 +142,9 @@ public class ScreenTimeoutSettings extends RadioButtonPickerFragment implements
|
||||
if (mInitialValues != null) {
|
||||
for (int i = 0; i < mInitialValues.length; ++i) {
|
||||
if (Long.parseLong(mInitialValues[i].toString()) <= maxTimeout) {
|
||||
candidates.add(new TimeoutCandidateInfo(mInitialEntries[i],
|
||||
mInitialValues[i].toString(), true));
|
||||
candidates.add(
|
||||
new TimeoutCandidateInfo(
|
||||
mInitialEntries[i], mInitialValues[i].toString(), true));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -161,9 +160,10 @@ public class ScreenTimeoutSettings extends RadioButtonPickerFragment implements
|
||||
mAdaptiveSleepCameraStatePreferenceController.updateVisibility();
|
||||
mAdaptiveSleepBatterySaverPreferenceController.updateVisibility();
|
||||
mAdaptiveSleepController.updatePreference();
|
||||
mContext.registerReceiver(mReceiver,
|
||||
new IntentFilter(PowerManager.ACTION_POWER_SAVE_MODE_CHANGED));
|
||||
mContext.registerReceiver(
|
||||
mReceiver, new IntentFilter(PowerManager.ACTION_POWER_SAVE_MODE_CHANGED));
|
||||
mPrivacyManager.addSensorPrivacyListener(CAMERA, mPrivacyChangedListener);
|
||||
mIsUserAuthenticated = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -185,19 +185,21 @@ public class ScreenTimeoutSettings extends RadioButtonPickerFragment implements
|
||||
}
|
||||
|
||||
for (CandidateInfo info : candidateList) {
|
||||
SelectorWithWidgetPreference pref =
|
||||
new SelectorWithWidgetPreference(getPrefContext());
|
||||
ProtectedSelectorWithWidgetPreference pref =
|
||||
new ProtectedSelectorWithWidgetPreference(
|
||||
getPrefContext(), info.getKey(), this);
|
||||
bindPreference(pref, info.getKey(), info, defaultKey);
|
||||
screen.addPreference(pref);
|
||||
}
|
||||
|
||||
final long selectedTimeout = Long.parseLong(defaultKey);
|
||||
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.
|
||||
final SelectorWithWidgetPreference preferenceWithLargestTimeout =
|
||||
(SelectorWithWidgetPreference) screen.getPreference(candidateList.size() - 1);
|
||||
final ProtectedSelectorWithWidgetPreference preferenceWithLargestTimeout =
|
||||
(ProtectedSelectorWithWidgetPreference)
|
||||
screen.getPreference(candidateList.size() - 1);
|
||||
preferenceWithLargestTimeout.setChecked(true);
|
||||
}
|
||||
|
||||
@@ -225,20 +227,34 @@ public class ScreenTimeoutSettings extends RadioButtonPickerFragment implements
|
||||
}
|
||||
}
|
||||
|
||||
boolean isUserAuthenticated() {
|
||||
return mIsUserAuthenticated;
|
||||
}
|
||||
|
||||
void setUserAuthenticated(boolean isUserAuthenticated) {
|
||||
mIsUserAuthenticated = isUserAuthenticated;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void setupDisabledFooterPreference() {
|
||||
final String textDisabledByAdmin = mDevicePolicyManager.getResources().getString(
|
||||
OTHER_OPTIONS_DISABLED_BY_ADMIN, () -> getResources().getString(
|
||||
R.string.admin_disabled_other_options));
|
||||
final String textDisabledByAdmin =
|
||||
mDevicePolicyManager
|
||||
.getResources()
|
||||
.getString(
|
||||
OTHER_OPTIONS_DISABLED_BY_ADMIN,
|
||||
() ->
|
||||
getResources()
|
||||
.getString(R.string.admin_disabled_other_options));
|
||||
final String textMoreDetails = getResources().getString(R.string.admin_more_details);
|
||||
|
||||
mDisableOptionsPreference = new FooterPreference(getContext());
|
||||
mDisableOptionsPreference.setTitle(textDisabledByAdmin);
|
||||
mDisableOptionsPreference.setSelectable(false);
|
||||
mDisableOptionsPreference.setLearnMoreText(textMoreDetails);
|
||||
mDisableOptionsPreference.setLearnMoreAction(v -> {
|
||||
RestrictedLockUtils.sendShowAdminSupportDetailsIntent(getContext(), mAdmin);
|
||||
});
|
||||
mDisableOptionsPreference.setLearnMoreAction(
|
||||
v -> {
|
||||
RestrictedLockUtils.sendShowAdminSupportDetailsIntent(getContext(), mAdmin);
|
||||
});
|
||||
mDisableOptionsPreference.setIcon(R.drawable.ic_info_outline_24dp);
|
||||
|
||||
// The 'disabled by admin' preference should always be at the end of the setting page.
|
||||
@@ -303,17 +319,20 @@ public class ScreenTimeoutSettings extends RadioButtonPickerFragment implements
|
||||
if (context == null) {
|
||||
return Long.toString(FALLBACK_SCREEN_TIMEOUT_VALUE);
|
||||
} else {
|
||||
return Long.toString(Settings.System.getLong(context.getContentResolver(),
|
||||
SCREEN_OFF_TIMEOUT, FALLBACK_SCREEN_TIMEOUT_VALUE));
|
||||
return Long.toString(
|
||||
Settings.System.getLong(
|
||||
context.getContentResolver(),
|
||||
SCREEN_OFF_TIMEOUT,
|
||||
FALLBACK_SCREEN_TIMEOUT_VALUE));
|
||||
}
|
||||
}
|
||||
|
||||
private void setCurrentSystemScreenTimeout(Context context, String key) {
|
||||
try {
|
||||
if (context != null) {
|
||||
final long value = Long.parseLong(key);
|
||||
mMetricsFeatureProvider.action(context, SettingsEnums.ACTION_SCREEN_TIMEOUT_CHANGED,
|
||||
(int) value);
|
||||
final long value = getTimeoutFromKey(key);
|
||||
mMetricsFeatureProvider.action(
|
||||
context, SettingsEnums.ACTION_SCREEN_TIMEOUT_CHANGED, (int) value);
|
||||
Settings.System.putLong(context.getContentResolver(), SCREEN_OFF_TIMEOUT, value);
|
||||
}
|
||||
} catch (NumberFormatException e) {
|
||||
@@ -325,7 +344,12 @@ public class ScreenTimeoutSettings extends RadioButtonPickerFragment implements
|
||||
return AdaptiveSleepPreferenceController.isAdaptiveSleepSupported(context);
|
||||
}
|
||||
|
||||
private static class TimeoutCandidateInfo extends CandidateInfo {
|
||||
private static long getTimeoutFromKey(String key) {
|
||||
return Long.parseLong(key);
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
static class TimeoutCandidateInfo extends CandidateInfo {
|
||||
private final CharSequence mLabel;
|
||||
private final String mKey;
|
||||
|
||||
@@ -351,10 +375,42 @@ public class ScreenTimeoutSettings extends RadioButtonPickerFragment implements
|
||||
}
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
static class ProtectedSelectorWithWidgetPreference
|
||||
extends SelectorWithWidgetPreference {
|
||||
|
||||
private final long mTimeoutMs;
|
||||
private final ScreenTimeoutSettings mScreenTimeoutSettings;
|
||||
|
||||
ProtectedSelectorWithWidgetPreference(
|
||||
Context context, String key, ScreenTimeoutSettings screenTimeoutSettings) {
|
||||
super(context);
|
||||
mTimeoutMs = getTimeoutFromKey(key);
|
||||
mScreenTimeoutSettings = screenTimeoutSettings;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick() {
|
||||
if (Flags.protectScreenTimeoutWithAuth()
|
||||
&& !mScreenTimeoutSettings.isUserAuthenticated()
|
||||
&& !isChecked()
|
||||
&& mTimeoutMs > getTimeoutFromKey(mScreenTimeoutSettings.getDefaultKey())) {
|
||||
WifiDppUtils.showLockScreen(
|
||||
getContext(),
|
||||
() -> {
|
||||
mScreenTimeoutSettings.setUserAuthenticated(true);
|
||||
super.onClick();
|
||||
});
|
||||
} else {
|
||||
super.onClick();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
|
||||
new BaseSearchIndexProvider(R.xml.screen_timeout_settings) {
|
||||
public List<SearchIndexableRaw> getRawDataToIndex(Context context,
|
||||
boolean enabled) {
|
||||
public List<SearchIndexableRaw> getRawDataToIndex(
|
||||
Context context, boolean enabled) {
|
||||
if (!isScreenAttentionAvailable(context)) {
|
||||
return null;
|
||||
}
|
||||
|
Reference in New Issue
Block a user