Add restricted padlock support for listpreference.

Change-Id: I1f3284a474d225df803abd57dd71382cb1dfa659
This commit is contained in:
Sudheer Shanka
2016-01-13 15:16:55 +00:00
parent 20c9817713
commit 550d068abd
10 changed files with 448 additions and 116 deletions

View File

@@ -0,0 +1,44 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2016 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:paddingStart="20dp"
android:paddingEnd="?android:attr/dialogPreferredPadding"
android:minHeight="?android:attr/listPreferredItemHeightSmall">
<CheckedTextView
android:id="@+id/text1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textColor="?android:attr/textColorAlertDialogListItem"
android:gravity="center_vertical"
android:drawableStart="?android:attr/listChoiceIndicatorSingle"
android:drawablePadding="20dp"
android:ellipsize="marquee" />
<ImageView
android:id="@+id/restricted_lock_icon"
android:layout_width="@dimen/restricted_lock_icon_size"
android:layout_height="@dimen/restricted_lock_icon_size"
android:src="@drawable/ic_settings_lock_outline"
android:layout_marginLeft="@dimen/restricted_lock_icon_padding"
android:baselineAlignBottom="true"
android:scaleType="centerInside"
android:visibility="gone" />
</LinearLayout>

View File

@@ -49,7 +49,7 @@
settings:keywords="@string/keywords_display_wallpaper" settings:keywords="@string/keywords_display_wallpaper"
android:fragment="com.android.settings.WallpaperTypeSettings" /> android:fragment="com.android.settings.WallpaperTypeSettings" />
<ListPreference <com.android.settings.RestrictedListPreference
android:key="screen_timeout" android:key="screen_timeout"
android:title="@string/screen_timeout" android:title="@string/screen_timeout"
android:summary="@string/screen_timeout_summary" android:summary="@string/screen_timeout_summary"

View File

@@ -29,7 +29,7 @@
settings:keywords="@string/keywords_lockscreen" settings:keywords="@string/keywords_lockscreen"
android:persistent="false"/> android:persistent="false"/>
<ListPreference <com.android.settings.RestrictedListPreference
android:key="lock_after_timeout" android:key="lock_after_timeout"
android:title="@string/lock_after_timeout" android:title="@string/lock_after_timeout"
android:summary="@string/lock_after_timeout_summary" android:summary="@string/lock_after_timeout_summary"

View File

@@ -33,7 +33,7 @@
android:key="visiblepattern" android:key="visiblepattern"
android:title="@string/lockpattern_settings_enable_visible_pattern_title"/> android:title="@string/lockpattern_settings_enable_visible_pattern_title"/>
<ListPreference <com.android.settings.RestrictedListPreference
android:key="lock_after_timeout" android:key="lock_after_timeout"
android:title="@string/lock_after_timeout" android:title="@string/lock_after_timeout"
android:summary="@string/lock_after_timeout_summary" android:summary="@string/lock_after_timeout_summary"

View File

@@ -29,7 +29,7 @@
settings:keywords="@string/keywords_lockscreen" settings:keywords="@string/keywords_lockscreen"
android:persistent="false"/> android:persistent="false"/>
<ListPreference <com.android.settings.RestrictedListPreference
android:key="lock_after_timeout" android:key="lock_after_timeout"
android:title="@string/lock_after_timeout" android:title="@string/lock_after_timeout"
android:summary="@string/lock_after_timeout_summary" android:summary="@string/lock_after_timeout_summary"

View File

@@ -63,10 +63,13 @@ public class CustomListPreference extends ListPreference {
super.onPrepareDialogBuilder(builder); super.onPrepareDialogBuilder(builder);
mClickedDialogEntryIndex = getCustomizablePreference() mClickedDialogEntryIndex = getCustomizablePreference()
.findIndexOfValue(getCustomizablePreference().getValue()); .findIndexOfValue(getCustomizablePreference().getValue());
getCustomizablePreference().onPrepareDialogBuilder(builder, getCustomizablePreference().onPrepareDialogBuilder(builder, getOnItemClickListener());
new DialogInterface.OnClickListener() { }
protected DialogInterface.OnClickListener getOnItemClickListener() {
return new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) { public void onClick(DialogInterface dialog, int which) {
mClickedDialogEntryIndex = which; setClickedDialogEntryIndex(which);
/* /*
* Clicking on an item simulates the positive button * Clicking on an item simulates the positive button
@@ -76,7 +79,11 @@ public class CustomListPreference extends ListPreference {
DialogInterface.BUTTON_POSITIVE); DialogInterface.BUTTON_POSITIVE);
dialog.dismiss(); dialog.dismiss();
} }
}); };
}
protected void setClickedDialogEntryIndex(int which) {
mClickedDialogEntryIndex = which;
} }
@Override @Override

View File

@@ -22,6 +22,7 @@ import android.app.UiModeManager;
import android.app.admin.DevicePolicyManager; import android.app.admin.DevicePolicyManager;
import android.content.ContentResolver; import android.content.ContentResolver;
import android.content.Context; import android.content.Context;
import android.content.ComponentName;
import android.content.res.Configuration; import android.content.res.Configuration;
import android.content.res.Resources; import android.content.res.Resources;
import android.hardware.Sensor; import android.hardware.Sensor;
@@ -45,6 +46,7 @@ import com.android.internal.view.RotationPolicy;
import com.android.settings.dashboard.SummaryLoader; import com.android.settings.dashboard.SummaryLoader;
import com.android.settings.search.BaseSearchIndexProvider; import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settings.search.Indexable; import com.android.settings.search.Indexable;
import com.android.settingslib.RestrictedLockUtils;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@@ -59,6 +61,9 @@ import static android.provider.Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC;
import static android.provider.Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL; import static android.provider.Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL;
import static android.provider.Settings.System.SCREEN_OFF_TIMEOUT; import static android.provider.Settings.System.SCREEN_OFF_TIMEOUT;
import static com.android.settings.RestrictedListPreference.RestrictedItem;
import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
public class DisplaySettings extends SettingsPreferenceFragment implements public class DisplaySettings extends SettingsPreferenceFragment implements
Preference.OnPreferenceChangeListener, Indexable { Preference.OnPreferenceChangeListener, Indexable {
private static final String TAG = "DisplaySettings"; private static final String TAG = "DisplaySettings";
@@ -83,7 +88,7 @@ public class DisplaySettings extends SettingsPreferenceFragment implements
private final Configuration mCurConfig = new Configuration(); private final Configuration mCurConfig = new Configuration();
private ListPreference mScreenTimeoutPreference; private RestrictedListPreference mScreenTimeoutPreference;
private ListPreference mNightModePreference; private ListPreference mNightModePreference;
private Preference mScreenSaverPreference; private Preference mScreenSaverPreference;
private SwitchPreference mLiftToWakePreference; private SwitchPreference mLiftToWakePreference;
@@ -113,13 +118,7 @@ public class DisplaySettings extends SettingsPreferenceFragment implements
getPreferenceScreen().removePreference(mScreenSaverPreference); getPreferenceScreen().removePreference(mScreenSaverPreference);
} }
mScreenTimeoutPreference = (ListPreference) findPreference(KEY_SCREEN_TIMEOUT); mScreenTimeoutPreference = (RestrictedListPreference) findPreference(KEY_SCREEN_TIMEOUT);
final long currentTimeout = Settings.System.getLong(resolver, SCREEN_OFF_TIMEOUT,
FALLBACK_SCREEN_TIMEOUT_VALUE);
mScreenTimeoutPreference.setValue(String.valueOf(currentTimeout));
mScreenTimeoutPreference.setOnPreferenceChangeListener(this);
disableUnusableTimeouts(mScreenTimeoutPreference);
updateTimeoutPreferenceDescription(currentTimeout);
mFontSizePref = (DropDownPreference) findPreference(KEY_FONT_SIZE); mFontSizePref = (DropDownPreference) findPreference(KEY_FONT_SIZE);
mFontSizePref.setOnPreferenceChangeListener(this); mFontSizePref.setOnPreferenceChangeListener(this);
@@ -257,9 +256,11 @@ public class DisplaySettings extends SettingsPreferenceFragment implements
} }
private void updateTimeoutPreferenceDescription(long currentTimeout) { private void updateTimeoutPreferenceDescription(long currentTimeout) {
ListPreference preference = mScreenTimeoutPreference; RestrictedListPreference preference = mScreenTimeoutPreference;
String summary; String summary;
if (currentTimeout < 0) { if (preference.isDisabledByAdmin()) {
summary = getString(R.string.disabled_by_policy_title);
} else if (currentTimeout < 0) {
// Unsupported value // Unsupported value
summary = ""; summary = "";
} else { } else {
@@ -270,49 +271,65 @@ public class DisplaySettings extends SettingsPreferenceFragment implements
} else { } else {
int best = 0; int best = 0;
for (int i = 0; i < values.length; i++) { for (int i = 0; i < values.length; i++) {
if (preference.isRestrictedForEntry(entries[i])) {
break;
}
long timeout = Long.parseLong(values[i].toString()); long timeout = Long.parseLong(values[i].toString());
if (currentTimeout >= timeout) { if (currentTimeout >= timeout) {
best = i; best = i;
} }
} }
summary = preference.getContext().getString(R.string.screen_timeout_summary, summary = getString(R.string.screen_timeout_summary, entries[best]);
entries[best]);
} }
} }
preference.setSummary(summary); preference.setSummary(summary);
} }
private void disableUnusableTimeouts(ListPreference screenTimeoutPreference) { private void disableUnusableTimeouts(RestrictedListPreference screenTimeoutPreference) {
final DevicePolicyManager dpm = final EnforcedAdmin admin = RestrictedLockUtils.checkIfMaximumTimeToLockIsSet(
(DevicePolicyManager) getActivity().getSystemService( getActivity());
Context.DEVICE_POLICY_SERVICE); if (admin == null) {
final long maxTimeout = dpm != null ? dpm.getMaximumTimeToLock(null) : 0;
if (maxTimeout == 0) {
return; // policy not enforced return; // policy not enforced
} }
final DevicePolicyManager dpm = (DevicePolicyManager) getActivity().getSystemService(
Context.DEVICE_POLICY_SERVICE);
if (dpm == null) {
return;
}
final long maxTimeout = dpm.getMaximumTimeToLock(null);
final CharSequence[] entries = screenTimeoutPreference.getEntries(); final CharSequence[] entries = screenTimeoutPreference.getEntries();
final CharSequence[] values = screenTimeoutPreference.getEntryValues(); final CharSequence[] values = screenTimeoutPreference.getEntryValues();
ArrayList<CharSequence> revisedEntries = new ArrayList<CharSequence>(); long maxTimeoutSelectable = 0;
ArrayList<CharSequence> revisedValues = new ArrayList<CharSequence>(); int maxTimeoutEntryIndex = -1;
for (int i = 0; i < values.length; i++) { for (int i = 0; i < values.length; i++) {
long timeout = Long.parseLong(values[i].toString()); long timeout = Long.parseLong(values[i].toString());
if (timeout <= maxTimeout) { if (timeout > maxTimeout) {
revisedEntries.add(entries[i]); break;
revisedValues.add(values[i]);
} }
maxTimeoutSelectable = timeout;
maxTimeoutEntryIndex = i;
} }
if (revisedEntries.size() != entries.length || revisedValues.size() != values.length) { // If there are no possible options for the user, then set this preference as disabled
// by admin, otherwise remove the padlock in case it was set earlier.
if (maxTimeoutSelectable == 0) {
screenTimeoutPreference.setDisabledByAdmin(admin);
return;
} else {
screenTimeoutPreference.setDisabledByAdmin(null);
}
screenTimeoutPreference.clearRestrictedItems();
// Set all the entries after the maximum selectable timeout as disabled by admin.
for (int i = maxTimeoutEntryIndex + 1; i < values.length; i++) {
screenTimeoutPreference.addRestrictedItem(
new RestrictedItem(entries[i], values[i], admin));
}
final int userPreference = Integer.parseInt(screenTimeoutPreference.getValue()); final int userPreference = Integer.parseInt(screenTimeoutPreference.getValue());
screenTimeoutPreference.setEntries(
revisedEntries.toArray(new CharSequence[revisedEntries.size()]));
screenTimeoutPreference.setEntryValues(
revisedValues.toArray(new CharSequence[revisedValues.size()]));
if (userPreference <= maxTimeout) { if (userPreference <= maxTimeout) {
screenTimeoutPreference.setValue(String.valueOf(userPreference)); screenTimeoutPreference.setValue(String.valueOf(userPreference));
} else if (revisedValues.size() > 0 } else if (maxTimeoutSelectable == maxTimeout) {
&& Long.parseLong(revisedValues.get(revisedValues.size() - 1).toString())
== maxTimeout) {
// If the last one happens to be the same as the max timeout, select that
screenTimeoutPreference.setValue(String.valueOf(maxTimeout)); screenTimeoutPreference.setValue(String.valueOf(maxTimeout));
} else { } else {
// There will be no highlighted selection since nothing in the list matches // There will be no highlighted selection since nothing in the list matches
@@ -320,8 +337,6 @@ public class DisplaySettings extends SettingsPreferenceFragment implements
// TODO: maybe append maxTimeout to the list and mark selected. // TODO: maybe append maxTimeout to the list and mark selected.
} }
} }
screenTimeoutPreference.setEnabled(revisedEntries.size() > 0);
}
int floatToIndex(float val) { int floatToIndex(float val) {
String[] indices = getResources().getStringArray(R.array.entryvalues_font_size); String[] indices = getResources().getStringArray(R.array.entryvalues_font_size);
@@ -358,6 +373,13 @@ public class DisplaySettings extends SettingsPreferenceFragment implements
public void onResume() { public void onResume() {
super.onResume(); super.onResume();
updateState(); updateState();
final long currentTimeout = Settings.System.getLong(getActivity().getContentResolver(),
SCREEN_OFF_TIMEOUT, FALLBACK_SCREEN_TIMEOUT_VALUE);
mScreenTimeoutPreference.setValue(String.valueOf(currentTimeout));
mScreenTimeoutPreference.setOnPreferenceChangeListener(this);
disableUnusableTimeouts(mScreenTimeoutPreference);
updateTimeoutPreferenceDescription(currentTimeout);
} }
private void updateState() { private void updateState() {

View File

@@ -0,0 +1,227 @@
/*
* Copyright (C) 2016 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.os.Bundle;
import android.support.v14.preference.ListPreferenceDialogFragment;
import android.support.v7.preference.PreferenceViewHolder;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.CheckedTextView;
import android.widget.ImageView;
import android.widget.ListAdapter;
import com.android.settingslib.RestrictedLockUtils;
import com.android.settingslib.RestrictedPreferenceHelper;
import java.util.ArrayList;
import java.util.List;
import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
public class RestrictedListPreference extends CustomListPreference {
private final RestrictedPreferenceHelper mHelper;
private final List<RestrictedItem> mRestrictedItems = new ArrayList<>();
public RestrictedListPreference(Context context, AttributeSet attrs) {
super(context, attrs);
mHelper = new RestrictedPreferenceHelper(context, this, attrs);
}
public RestrictedListPreference(Context context, AttributeSet attrs,
int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
mHelper = new RestrictedPreferenceHelper(context, this, attrs);
}
@Override
public void onBindViewHolder(PreferenceViewHolder holder) {
super.onBindViewHolder(holder);
mHelper.onBindViewHolder(holder);
}
@Override
public void performClick() {
if (!mHelper.performClick()) {
super.performClick();
}
}
@Override
public void setEnabled(boolean enabled) {
if (enabled && isDisabledByAdmin()) {
mHelper.setDisabledByAdmin(null);
return;
}
super.setEnabled(enabled);
}
public void setDisabledByAdmin(EnforcedAdmin admin) {
if (mHelper.setDisabledByAdmin(admin)) {
notifyChanged();
}
}
public boolean isDisabledByAdmin() {
return mHelper.isDisabledByAdmin();
}
public boolean isRestrictedForEntry(CharSequence entry) {
if (entry == null) {
return false;
}
for (RestrictedItem item : mRestrictedItems) {
if (entry.equals(item.entry)) {
return true;
}
}
return false;
}
public void addRestrictedItem(RestrictedItem item) {
mRestrictedItems.add(item);
}
public void clearRestrictedItems() {
mRestrictedItems.clear();
}
private RestrictedItem getRestrictedItemForEntryValue(CharSequence entryValue) {
if (entryValue == null) {
return null;
}
for (RestrictedItem item : mRestrictedItems) {
if (entryValue.equals(item.entryValue)) {
return item;
}
}
return null;
}
protected ListAdapter createListAdapter() {
final String selectedValue = getValue();
final int selectedIndex =
(selectedValue == null) ? -1 : findIndexOfValue(selectedValue);
return new RestrictedArrayAdapter(getContext(), getEntries(), selectedIndex);
}
@Override
protected void onPrepareDialogBuilder(AlertDialog.Builder builder,
DialogInterface.OnClickListener listener) {
builder.setAdapter(createListAdapter(), listener);
}
public class RestrictedArrayAdapter extends ArrayAdapter<CharSequence> {
private final int mSelectedIndex;
public RestrictedArrayAdapter(Context context, CharSequence[] objects, int selectedIndex) {
super(context, R.layout.restricted_dialog_singlechoice, R.id.text1, objects);
mSelectedIndex = selectedIndex;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View root = super.getView(position, convertView, parent);
CharSequence entry = getItem(position);
CheckedTextView text = (CheckedTextView) root.findViewById(R.id.text1);
ImageView padlock = (ImageView) root.findViewById(R.id.restricted_lock_icon);
if (isRestrictedForEntry(entry)) {
text.setEnabled(false);
padlock.setVisibility(View.VISIBLE);
} else {
if (position == mSelectedIndex) {
text.setChecked(true);
}
text.setEnabled(true);
padlock.setVisibility(View.GONE);
}
return root;
}
@Override
public boolean hasStableIds() {
return true;
}
@Override
public long getItemId(int position) {
return position;
}
}
public static class RestrictedListPreferenceDialogFragment extends
CustomListPreference.CustomListPreferenceDialogFragment {
public static ListPreferenceDialogFragment newInstance(String key) {
final ListPreferenceDialogFragment fragment
= new RestrictedListPreferenceDialogFragment();
final Bundle b = new Bundle(1);
b.putString(ARG_KEY, key);
fragment.setArguments(b);
return fragment;
}
private RestrictedListPreference getCustomizablePreference() {
return (RestrictedListPreference) getPreference();
}
@Override
protected DialogInterface.OnClickListener getOnItemClickListener() {
return new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
final RestrictedListPreference preference = getCustomizablePreference();
if (which < 0 || which >= preference.getEntryValues().length) {
return;
}
String entryValue = preference.getEntryValues()[which].toString();
RestrictedItem item = preference.getRestrictedItemForEntryValue(entryValue);
if (item != null) {
RestrictedLockUtils.sendShowAdminSupportDetailsIntent(getContext(),
item.enforcedAdmin);
} else {
setClickedDialogEntryIndex(which);
}
/*
* Clicking on an item simulates the positive button
* click, and dismisses the dialog.
*/
RestrictedListPreferenceDialogFragment.this.onClick(dialog,
DialogInterface.BUTTON_POSITIVE);
dialog.dismiss();
}
};
}
}
public static class RestrictedItem {
public final CharSequence entry;
public final CharSequence entryValue;
public final EnforcedAdmin enforcedAdmin;
public RestrictedItem(CharSequence entry, CharSequence entryValue,
EnforcedAdmin enforcedAdmin) {
this.entry = entry;
this.entryValue = entryValue;
this.enforcedAdmin = enforcedAdmin;
}
}
}

View File

@@ -39,7 +39,6 @@ import android.provider.Settings;
import android.security.KeyStore; import android.security.KeyStore;
import android.service.trust.TrustAgentService; import android.service.trust.TrustAgentService;
import android.support.v14.preference.SwitchPreference; import android.support.v14.preference.SwitchPreference;
import android.support.v7.preference.ListPreference;
import android.support.v7.preference.Preference; import android.support.v7.preference.Preference;
import android.support.v7.preference.Preference.OnPreferenceChangeListener; import android.support.v7.preference.Preference.OnPreferenceChangeListener;
import android.support.v7.preference.Preference.OnPreferenceClickListener; import android.support.v7.preference.Preference.OnPreferenceClickListener;
@@ -54,6 +53,7 @@ import android.util.Log;
import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.MetricsLogger;
import com.android.internal.widget.LockPatternUtils; import com.android.internal.widget.LockPatternUtils;
import com.android.settings.RestrictedListPreference;
import com.android.settings.TrustAgentUtils.TrustAgentComponentInfo; import com.android.settings.TrustAgentUtils.TrustAgentComponentInfo;
import com.android.settings.fingerprint.FingerprintEnrollIntroduction; import com.android.settings.fingerprint.FingerprintEnrollIntroduction;
import com.android.settings.fingerprint.FingerprintSettings; import com.android.settings.fingerprint.FingerprintSettings;
@@ -61,6 +61,7 @@ import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settings.search.Index; import com.android.settings.search.Index;
import com.android.settings.search.Indexable; import com.android.settings.search.Indexable;
import com.android.settings.search.SearchIndexableRaw; import com.android.settings.search.SearchIndexableRaw;
import com.android.settingslib.RestrictedLockUtils;
import com.android.settingslib.RestrictedPreference; import com.android.settingslib.RestrictedPreference;
import com.android.settingslib.RestrictedSwitchPreference; import com.android.settingslib.RestrictedSwitchPreference;
@@ -69,6 +70,9 @@ import java.util.List;
import static android.provider.Settings.System.SCREEN_OFF_TIMEOUT; import static android.provider.Settings.System.SCREEN_OFF_TIMEOUT;
import static com.android.settings.RestrictedListPreference.RestrictedItem;
import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
/** /**
* Gesture lock pattern settings. * Gesture lock pattern settings.
*/ */
@@ -124,7 +128,7 @@ public class SecuritySettings extends SettingsPreferenceFragment
private ChooseLockSettingsHelper mChooseLockSettingsHelper; private ChooseLockSettingsHelper mChooseLockSettingsHelper;
private LockPatternUtils mLockPatternUtils; private LockPatternUtils mLockPatternUtils;
private ListPreference mLockAfter; private RestrictedListPreference mLockAfter;
private SwitchPreference mVisiblePattern; private SwitchPreference mVisiblePattern;
@@ -267,7 +271,7 @@ public class SecuritySettings extends SettingsPreferenceFragment
} }
// lock after preference // lock after preference
mLockAfter = (ListPreference) root.findPreference(KEY_LOCK_AFTER_TIMEOUT); mLockAfter = (RestrictedListPreference) root.findPreference(KEY_LOCK_AFTER_TIMEOUT);
if (mLockAfter != null) { if (mLockAfter != null) {
setupLockAfterPreference(); setupLockAfterPreference();
updateLockAfterPreferenceSummary(); updateLockAfterPreferenceSummary();
@@ -552,6 +556,9 @@ public class SecuritySettings extends SettingsPreferenceFragment
Settings.Secure.LOCK_SCREEN_LOCK_AFTER_TIMEOUT, 5000); Settings.Secure.LOCK_SCREEN_LOCK_AFTER_TIMEOUT, 5000);
mLockAfter.setValue(String.valueOf(currentTimeout)); mLockAfter.setValue(String.valueOf(currentTimeout));
mLockAfter.setOnPreferenceChangeListener(this); mLockAfter.setOnPreferenceChangeListener(this);
final EnforcedAdmin admin = RestrictedLockUtils.checkIfMaximumTimeToLockIsSet(
getActivity());
if (admin != null) {
final long adminTimeout = (mDPM != null ? mDPM.getMaximumTimeToLock(null) : 0); final long adminTimeout = (mDPM != null ? mDPM.getMaximumTimeToLock(null) : 0);
final long displayTimeout = Math.max(0, final long displayTimeout = Math.max(0,
Settings.System.getInt(getContentResolver(), SCREEN_OFF_TIMEOUT, 0)); Settings.System.getInt(getContentResolver(), SCREEN_OFF_TIMEOUT, 0));
@@ -559,11 +566,16 @@ public class SecuritySettings extends SettingsPreferenceFragment
// This setting is a slave to display timeout when a device policy is enforced. // This setting is a slave to display timeout when a device policy is enforced.
// As such, maxLockTimeout = adminTimeout - displayTimeout. // As such, maxLockTimeout = adminTimeout - displayTimeout.
// If there isn't enough time, shows "immediately" setting. // If there isn't enough time, shows "immediately" setting.
disableUnusableTimeouts(Math.max(0, adminTimeout - displayTimeout)); disableUnusableTimeouts(Math.max(0, adminTimeout - displayTimeout), admin);
}
} }
} }
private void updateLockAfterPreferenceSummary() { private void updateLockAfterPreferenceSummary() {
final String summary;
if (mLockAfter.isDisabledByAdmin()) {
summary = getString(R.string.disabled_by_policy_title);
} else {
// Update summary message with current value // Update summary message with current value
long currentTimeout = Settings.Secure.getLong(getContentResolver(), long currentTimeout = Settings.Secure.getLong(getContentResolver(),
Settings.Secure.LOCK_SCREEN_LOCK_AFTER_TIMEOUT, 5000); Settings.Secure.LOCK_SCREEN_LOCK_AFTER_TIMEOUT, 5000);
@@ -571,6 +583,9 @@ public class SecuritySettings extends SettingsPreferenceFragment
final CharSequence[] values = mLockAfter.getEntryValues(); final CharSequence[] values = mLockAfter.getEntryValues();
int best = 0; int best = 0;
for (int i = 0; i < values.length; i++) { for (int i = 0; i < values.length; i++) {
if (mLockAfter.isRestrictedForEntry(entries[i])) {
break;
}
long timeout = Long.valueOf(values[i].toString()); long timeout = Long.valueOf(values[i].toString());
if (currentTimeout >= timeout) { if (currentTimeout >= timeout) {
best = i; best = i;
@@ -580,45 +595,59 @@ public class SecuritySettings extends SettingsPreferenceFragment
Preference preference = getPreferenceScreen().findPreference(KEY_TRUST_AGENT); Preference preference = getPreferenceScreen().findPreference(KEY_TRUST_AGENT);
if (preference != null && preference.getTitle().length() > 0) { if (preference != null && preference.getTitle().length() > 0) {
if (Long.valueOf(values[best].toString()) == 0) { if (Long.valueOf(values[best].toString()) == 0) {
mLockAfter.setSummary(getString(R.string.lock_immediately_summary_with_exception, summary = getString(R.string.lock_immediately_summary_with_exception,
preference.getTitle())); preference.getTitle());
} else { } else {
mLockAfter.setSummary(getString(R.string.lock_after_timeout_summary_with_exception, summary = getString(R.string.lock_after_timeout_summary_with_exception,
entries[best], preference.getTitle())); entries[best], preference.getTitle());
} }
} else { } else {
mLockAfter.setSummary(getString(R.string.lock_after_timeout_summary, entries[best])); summary = getString(R.string.lock_after_timeout_summary, entries[best]);
} }
} }
mLockAfter.setSummary(summary);
}
private void disableUnusableTimeouts(long maxTimeout) { private void disableUnusableTimeouts(long maxTimeout, EnforcedAdmin admin) {
final CharSequence[] entries = mLockAfter.getEntries(); final CharSequence[] entries = mLockAfter.getEntries();
final CharSequence[] values = mLockAfter.getEntryValues(); final CharSequence[] values = mLockAfter.getEntryValues();
ArrayList<CharSequence> revisedEntries = new ArrayList<CharSequence>(); long maxTimeoutSelectable = 0;
ArrayList<CharSequence> revisedValues = new ArrayList<CharSequence>(); int maxTimeoutEntryIndex = -1;
for (int i = 0; i < values.length; i++) { for (int i = 0; i < values.length; i++) {
long timeout = Long.valueOf(values[i].toString()); long timeout = Long.parseLong(values[i].toString());
if (timeout <= maxTimeout) { if (timeout > maxTimeout) {
revisedEntries.add(entries[i]); break;
revisedValues.add(values[i]);
} }
maxTimeoutSelectable = timeout;
maxTimeoutEntryIndex = i;
} }
if (revisedEntries.size() != entries.length || revisedValues.size() != values.length) { // If there are no possible options for the user, then set this preference as
mLockAfter.setEntries( // disabled by admin, otherwise remove the padlock in case it was set earlier.
revisedEntries.toArray(new CharSequence[revisedEntries.size()])); if (maxTimeoutSelectable == 0) {
mLockAfter.setEntryValues( mLockAfter.setDisabledByAdmin(admin);
revisedValues.toArray(new CharSequence[revisedValues.size()])); return;
} else {
mLockAfter.setDisabledByAdmin(null);
}
mLockAfter.clearRestrictedItems();
// Set all the entries after the maximum selectable timeout as disabled by admin.
for (int i = maxTimeoutEntryIndex + 1; i < values.length; i++) {
mLockAfter.addRestrictedItem(
new RestrictedItem(entries[i], values[i], admin));
}
final int userPreference = Integer.valueOf(mLockAfter.getValue()); final int userPreference = Integer.valueOf(mLockAfter.getValue());
if (userPreference <= maxTimeout) { if (userPreference <= maxTimeout) {
mLockAfter.setValue(String.valueOf(userPreference)); mLockAfter.setValue(String.valueOf(userPreference));
} else if (maxTimeoutSelectable == maxTimeout) {
mLockAfter.setValue(String.valueOf(maxTimeout));
} else { } else {
// There will be no highlighted selection since nothing in the list matches // There will be no highlighted selection since nothing in the list matches
// maxTimeout. The user can still select anything less than maxTimeout. // maxTimeout. The user can still select anything less than maxTimeout.
// TODO: maybe append maxTimeout to the list and mark selected. // TODO: maybe append maxTimeout to the list and mark selected.
} }
} }
mLockAfter.setEnabled(revisedEntries.size() > 0);
}
@Override @Override
public void onSaveInstanceState(Bundle outState) { public void onSaveInstanceState(Bundle outState) {
@@ -651,7 +680,7 @@ public class SecuritySettings extends SettingsPreferenceFragment
Settings.System.TEXT_SHOW_PASSWORD, 1) != 0); Settings.System.TEXT_SHOW_PASSWORD, 1) != 0);
} }
if (mResetCredentials != null && !mResetCredentials.isDisabledByAdmin()) { if (mResetCredentials != null) {
mResetCredentials.setEnabled(!mKeyStore.isEmpty()); mResetCredentials.setEnabled(!mKeyStore.isEmpty());
} }

View File

@@ -476,7 +476,10 @@ public abstract class SettingsPreferenceFragment extends InstrumentedPreferenceF
preference.setKey(UUID.randomUUID().toString()); preference.setKey(UUID.randomUUID().toString());
} }
DialogFragment f = null; DialogFragment f = null;
if (preference instanceof CustomListPreference) { if (preference instanceof RestrictedListPreference) {
f = RestrictedListPreference.RestrictedListPreferenceDialogFragment
.newInstance(preference.getKey());
} else if (preference instanceof CustomListPreference) {
f = CustomListPreference.CustomListPreferenceDialogFragment f = CustomListPreference.CustomListPreferenceDialogFragment
.newInstance(preference.getKey()); .newInstance(preference.getKey());
} else if (preference instanceof CustomDialogPreference) { } else if (preference instanceof CustomDialogPreference) {