diff --git a/res/xml/date_time_prefs.xml b/res/xml/date_time_prefs.xml index d359d840882..0aec43f35b1 100644 --- a/res/xml/date_time_prefs.xml +++ b/res/xml/date_time_prefs.xml @@ -19,7 +19,7 @@ android:title="@string/date_and_time" settings:keywords="@string/keywords_date_and_time"> - - - @@ -91,9 +89,9 @@ android:targetPackage="com.android.certinstaller" android:targetClass="com.android.certinstaller.CertInstallerMain"/> - + - @@ -102,7 +100,7 @@ android:targetPackage="com.android.settings" android:targetClass="com.android.settings.CredentialStorage"/> - + diff --git a/res/xml/security_settings_picker.xml b/res/xml/security_settings_picker.xml index e0c518577a5..3a456973de3 100644 --- a/res/xml/security_settings_picker.xml +++ b/res/xml/security_settings_picker.xml @@ -18,27 +18,27 @@ android:title="@string/lock_settings_picker_title" android:key="lock_settings_picker"> - - - - - diff --git a/src/com/android/settings/ChooseLockGeneric.java b/src/com/android/settings/ChooseLockGeneric.java index 65e6c2768e6..972c29c0fa6 100644 --- a/src/com/android/settings/ChooseLockGeneric.java +++ b/src/com/android/settings/ChooseLockGeneric.java @@ -45,6 +45,10 @@ import android.widget.Toast; import com.android.internal.logging.MetricsLogger; import com.android.internal.widget.LockPatternUtils; +import com.android.settingslib.RestrictedLockUtils; +import com.android.settingslib.RestrictedPreference; + +import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin; public class ChooseLockGeneric extends SettingsActivity { public static final String CONFIRM_CREDENTIALS = "confirm_credentials"; @@ -355,39 +359,60 @@ public class ChooseLockGeneric extends SettingsActivity { boolean hideDisabled) { final PreferenceScreen entries = getPreferenceScreen(); + int adminEnforcedQuality = mDPM.getPasswordQuality(null); + EnforcedAdmin enforcedAdmin = RestrictedLockUtils.checkIfPasswordQualityIsSet( + getActivity()); for (int i = entries.getPreferenceCount() - 1; i >= 0; --i) { Preference pref = entries.getPreference(i); - if (pref instanceof PreferenceScreen) { + if (pref instanceof RestrictedPreference) { final String key = pref.getKey(); boolean enabled = true; boolean visible = true; + boolean disabledByAdmin = false; if (KEY_UNLOCK_SET_OFF.equals(key)) { enabled = quality <= DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED; if (getResources().getBoolean(R.bool.config_hide_none_security_option)) { enabled = false; visible = false; } + disabledByAdmin = adminEnforcedQuality + > DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED; } else if (KEY_UNLOCK_SET_NONE.equals(key)) { if (mUserId != UserHandle.myUserId()) { // Swipe doesn't make sense for profiles. visible = false; } enabled = quality <= DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED; + disabledByAdmin = adminEnforcedQuality + > DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED; } else if (KEY_UNLOCK_SET_PATTERN.equals(key)) { enabled = quality <= DevicePolicyManager.PASSWORD_QUALITY_SOMETHING; + disabledByAdmin = adminEnforcedQuality + > DevicePolicyManager.PASSWORD_QUALITY_SOMETHING; } else if (KEY_UNLOCK_SET_PIN.equals(key)) { enabled = quality <= DevicePolicyManager.PASSWORD_QUALITY_NUMERIC_COMPLEX; + disabledByAdmin = adminEnforcedQuality + > DevicePolicyManager.PASSWORD_QUALITY_NUMERIC_COMPLEX; } else if (KEY_UNLOCK_SET_PASSWORD.equals(key)) { enabled = quality <= DevicePolicyManager.PASSWORD_QUALITY_COMPLEX; + disabledByAdmin = adminEnforcedQuality + > DevicePolicyManager.PASSWORD_QUALITY_COMPLEX; } if (hideDisabled) { visible = enabled; } if (!visible) { entries.removePreference(pref); + } else if (disabledByAdmin && enforcedAdmin != null) { + ((RestrictedPreference) pref).setDisabledByAdmin(enforcedAdmin); } else if (!enabled) { + // we need to setDisabledByAdmin to null first to disable the padlock + // in case it was set earlier. + ((RestrictedPreference) pref).setDisabledByAdmin(null); pref.setSummary(R.string.unlock_set_unlock_disabled_summary); pref.setEnabled(false); + } else { + ((RestrictedPreference) pref).setDisabledByAdmin(null); } } } diff --git a/src/com/android/settings/DateTimeSettings.java b/src/com/android/settings/DateTimeSettings.java index d92d6108ce6..6602c3e4e1e 100644 --- a/src/com/android/settings/DateTimeSettings.java +++ b/src/com/android/settings/DateTimeSettings.java @@ -39,11 +39,15 @@ import android.widget.TimePicker; import com.android.internal.logging.MetricsLogger; import com.android.settings.dashboard.SummaryLoader; +import com.android.settingslib.RestrictedLockUtils; +import com.android.settingslib.RestrictedSwitchPreference; import com.android.settingslib.datetime.ZoneGetter; import java.util.Calendar; import java.util.Date; +import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin; + public class DateTimeSettings extends SettingsPreferenceFragment implements OnSharedPreferenceChangeListener, TimePickerDialog.OnTimeSetListener, DatePickerDialog.OnDateSetListener { @@ -64,7 +68,7 @@ public class DateTimeSettings extends SettingsPreferenceFragment // have we been launched from the setup wizard? protected static final String EXTRA_IS_FIRST_RUN = "firstRun"; - private SwitchPreference mAutoTimePref; + private RestrictedSwitchPreference mAutoTimePref; private Preference mTimePref; private Preference mTime24Pref; private SwitchPreference mAutoTimeZonePref; @@ -89,23 +93,17 @@ public class DateTimeSettings extends SettingsPreferenceFragment boolean autoTimeEnabled = getAutoState(Settings.Global.AUTO_TIME); boolean autoTimeZoneEnabled = getAutoState(Settings.Global.AUTO_TIME_ZONE); - mAutoTimePref = (SwitchPreference) findPreference(KEY_AUTO_TIME); - - DevicePolicyManager dpm = (DevicePolicyManager) getSystemService(Context - .DEVICE_POLICY_SERVICE); - if (dpm.getAutoTimeRequired()) { - mAutoTimePref.setEnabled(false); - - // If Settings.Global.AUTO_TIME is false it will be set to true - // by the device policy manager very soon. - // Note that this app listens to that change. - } + mAutoTimePref = (RestrictedSwitchPreference) findPreference(KEY_AUTO_TIME); + EnforcedAdmin admin = RestrictedLockUtils.checkIfAutoTimeRequired(getActivity()); + mAutoTimePref.setDisabledByAdmin(admin); Intent intent = getActivity().getIntent(); boolean isFirstRun = intent.getBooleanExtra(EXTRA_IS_FIRST_RUN, false); mDummyDate = Calendar.getInstance(); + // If device admin requires auto time device policy manager will set + // Settings.Global.AUTO_TIME to true. Note that this app listens to that change. mAutoTimePref.setChecked(autoTimeEnabled); mAutoTimeZonePref = (SwitchPreference) findPreference(KEY_AUTO_TIME_ZONE); // Override auto-timezone if it's a wifi-only device or if we're still in setup wizard. diff --git a/src/com/android/settings/SecuritySettings.java b/src/com/android/settings/SecuritySettings.java index 12216247d96..d39203d6250 100644 --- a/src/com/android/settings/SecuritySettings.java +++ b/src/com/android/settings/SecuritySettings.java @@ -61,6 +61,7 @@ import com.android.settings.search.BaseSearchIndexProvider; import com.android.settings.search.Index; import com.android.settings.search.Indexable; import com.android.settings.search.SearchIndexableRaw; +import com.android.settingslib.RestrictedPreference; import com.android.settingslib.RestrictedSwitchPreference; import java.util.ArrayList; @@ -130,7 +131,7 @@ public class SecuritySettings extends SettingsPreferenceFragment private SwitchPreference mShowPassword; private KeyStore mKeyStore; - private Preference mResetCredentials; + private RestrictedPreference mResetCredentials; private RestrictedSwitchPreference mToggleAppInstallation; private DialogInterface mWarnInstallApps; @@ -310,25 +311,26 @@ public class SecuritySettings extends SettingsPreferenceFragment // Show password mShowPassword = (SwitchPreference) root.findPreference(KEY_SHOW_PASSWORD); - mResetCredentials = root.findPreference(KEY_RESET_CREDENTIALS); + mResetCredentials = (RestrictedPreference) root.findPreference(KEY_RESET_CREDENTIALS); // Credential storage final UserManager um = (UserManager) getActivity().getSystemService(Context.USER_SERVICE); mKeyStore = KeyStore.getInstance(); // needs to be initialized for onResume() - if (!um.hasUserRestriction(UserManager.DISALLOW_CONFIG_CREDENTIALS)) { - Preference credentialStorageType = root.findPreference(KEY_CREDENTIAL_STORAGE_TYPE); - final int storageSummaryRes = + RestrictedPreference credentialStorageType = (RestrictedPreference) root.findPreference( + KEY_CREDENTIAL_STORAGE_TYPE); + credentialStorageType.checkRestrictionAndSetDisabled( + UserManager.DISALLOW_CONFIG_CREDENTIALS); + RestrictedPreference installCredentials = (RestrictedPreference) root.findPreference( + KEY_CREDENTIALS_INSTALL); + installCredentials.checkRestrictionAndSetDisabled(UserManager.DISALLOW_CONFIG_CREDENTIALS); + mResetCredentials.checkRestrictionAndSetDisabled(UserManager.DISALLOW_CONFIG_CREDENTIALS); + + final int storageSummaryRes = mKeyStore.isHardwareBacked() ? R.string.credential_storage_type_hardware : R.string.credential_storage_type_software; - credentialStorageType.setSummary(storageSummaryRes); - } else { - PreferenceGroup credentialsManager = (PreferenceGroup) - root.findPreference(KEY_CREDENTIALS_MANAGER); - credentialsManager.removePreference(root.findPreference(KEY_RESET_CREDENTIALS)); - credentialsManager.removePreference(root.findPreference(KEY_CREDENTIALS_INSTALL)); - credentialsManager.removePreference(root.findPreference(KEY_CREDENTIAL_STORAGE_TYPE)); - } + credentialStorageType.setSummary(storageSummaryRes); + // Application install PreferenceGroup deviceAdminCategory = (PreferenceGroup) @@ -649,7 +651,7 @@ public class SecuritySettings extends SettingsPreferenceFragment Settings.System.TEXT_SHOW_PASSWORD, 1) != 0); } - if (mResetCredentials != null) { + if (mResetCredentials != null && !mResetCredentials.isDisabledByAdmin()) { mResetCredentials.setEnabled(!mKeyStore.isEmpty()); } diff --git a/src/com/android/settings/accessibility/AccessibilitySettings.java b/src/com/android/settings/accessibility/AccessibilitySettings.java index fdf01e9c7bd..238c0c1dde4 100644 --- a/src/com/android/settings/accessibility/AccessibilitySettings.java +++ b/src/com/android/settings/accessibility/AccessibilitySettings.java @@ -51,6 +51,8 @@ import com.android.settings.Utils; import com.android.settings.search.BaseSearchIndexProvider; import com.android.settings.search.Indexable; import com.android.settings.search.SearchIndexableRaw; +import com.android.settingslib.RestrictedPreference; +import com.android.settingslib.RestrictedLockUtils; import com.android.settingslib.accessibility.AccessibilityUtils; import java.util.ArrayList; @@ -60,6 +62,8 @@ import java.util.List; import java.util.Map; import java.util.Set; +import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin; + /** * Activity with the accessibility settings. */ @@ -468,8 +472,7 @@ public class AccessibilitySettings extends SettingsPreferenceFragment implements for (int i = 0, count = installedServices.size(); i < count; ++i) { AccessibilityServiceInfo info = installedServices.get(i); - PreferenceScreen preference = getPreferenceManager().createPreferenceScreen( - getActivity()); + RestrictedPreference preference = new RestrictedPreference(getActivity()); String title = info.getResolveInfo().loadLabel(getPackageManager()).toString(); ServiceInfo serviceInfo = info.getResolveInfo().serviceInfo; @@ -492,7 +495,17 @@ public class AccessibilitySettings extends SettingsPreferenceFragment implements String packageName = serviceInfo.packageName; boolean serviceAllowed = permittedServices == null || permittedServices.contains(packageName); - preference.setEnabled(serviceAllowed || serviceEnabled); + if (!serviceAllowed && !serviceEnabled) { + EnforcedAdmin admin = + RestrictedLockUtils.getProfileOrDeviceOwnerOnCallingUser(getActivity()); + if (admin != null) { + preference.setDisabledByAdmin(admin); + } else { + preference.setEnabled(false); + } + } else { + preference.setEnabled(true); + } String summaryString; if (serviceAllowed) { diff --git a/src/com/android/settings/accounts/ChooseAccountActivity.java b/src/com/android/settings/accounts/ChooseAccountActivity.java index f2f1f861f35..489a165b0e9 100644 --- a/src/com/android/settings/accounts/ChooseAccountActivity.java +++ b/src/com/android/settings/accounts/ChooseAccountActivity.java @@ -169,6 +169,7 @@ public class ChooseAccountActivity extends InstrumentedPreferenceActivity { Drawable drawable = getDrawableForType(pref.type); ProviderPreference p = new ProviderPreference(getPreferenceScreen().getContext(), pref.type, drawable, pref.name); + p.checkAccountManagementAndSetDisabled(); mAddAccountGroup.addPreference(p); } } else { diff --git a/src/com/android/settings/accounts/ProviderPreference.java b/src/com/android/settings/accounts/ProviderPreference.java index 9a63062ed2c..863fef46bf2 100644 --- a/src/com/android/settings/accounts/ProviderPreference.java +++ b/src/com/android/settings/accounts/ProviderPreference.java @@ -20,11 +20,16 @@ import android.content.Context; import android.graphics.drawable.Drawable; import android.support.v7.preference.Preference; +import com.android.settingslib.RestrictedLockUtils; +import com.android.settingslib.RestrictedPreference; + +import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin; + /** * ProviderPreference is used to display an image to the left of a provider name. * The preference ultimately calls AccountManager.addAccount() for the account type. */ -public class ProviderPreference extends Preference { +public class ProviderPreference extends RestrictedPreference { private String mAccountType; public ProviderPreference( @@ -39,4 +44,10 @@ public class ProviderPreference extends Preference { public String getAccountType() { return mAccountType; } + + public void checkAccountManagementAndSetDisabled() { + EnforcedAdmin admin = RestrictedLockUtils.checkIfAccountManagementDisabled( + getContext(), getAccountType()); + setDisabledByAdmin(admin); + } } diff --git a/src/com/android/settings/inputmethod/InputMethodPreference.java b/src/com/android/settings/inputmethod/InputMethodPreference.java index 0d812e5c34c..8c870800398 100755 --- a/src/com/android/settings/inputmethod/InputMethodPreference.java +++ b/src/com/android/settings/inputmethod/InputMethodPreference.java @@ -34,11 +34,15 @@ import android.widget.Toast; import com.android.internal.inputmethod.InputMethodUtils; import com.android.settings.R; +import com.android.settingslib.RestrictedLockUtils; +import com.android.settingslib.RestrictedSwitchPreference; import java.text.Collator; import java.util.ArrayList; import java.util.List; +import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin; + /** * Input method preference. * @@ -46,7 +50,7 @@ import java.util.List; * is used to enable or disable the IME. 2) An instance without a switch is used to invoke the * setting activity of the IME. */ -class InputMethodPreference extends SwitchPreference implements OnPreferenceClickListener, +class InputMethodPreference extends RestrictedSwitchPreference implements OnPreferenceClickListener, OnPreferenceChangeListener { private static final String TAG = InputMethodPreference.class.getSimpleName(); private static final String EMPTY_TEXT = ""; @@ -80,7 +84,7 @@ class InputMethodPreference extends SwitchPreference implements OnPreferenceClic * @param isImeEnabler true if this preference is the IME enabler that has enable/disable * switches for all available IMEs, not the list of enabled IMEs. * @param isAllowedByOrganization false if the IME has been disabled by a device or profile - owner. + * owner. * @param onSaveListener The listener called when this preference has been changed and needs * to save the state to shared preference. */ @@ -115,6 +119,11 @@ class InputMethodPreference extends SwitchPreference implements OnPreferenceClic && mInputMethodSettingValues.isValidSystemNonAuxAsciiCapableIme(imi, context); setOnPreferenceClickListener(this); setOnPreferenceChangeListener(this); + if (!isAllowedByOrganization) { + EnforcedAdmin admin = + RestrictedLockUtils.getProfileOrDeviceOwnerOnCallingUser(context); + setDisabledByAdmin(admin); + } } public InputMethodInfo getInputMethodInfo() { diff --git a/src/com/android/settings/location/LocationSettings.java b/src/com/android/settings/location/LocationSettings.java index 9974e89e8d9..047fcbb671e 100644 --- a/src/com/android/settings/location/LocationSettings.java +++ b/src/com/android/settings/location/LocationSettings.java @@ -46,6 +46,7 @@ import com.android.settings.Utils; import com.android.settings.applications.InstalledAppDetails; import com.android.settings.dashboard.SummaryLoader; import com.android.settings.widget.SwitchBar; +import com.android.settingslib.RestrictedLockUtils; import com.android.settingslib.location.RecentLocationApps; import java.util.ArrayList; @@ -53,6 +54,8 @@ import java.util.Collections; import java.util.Comparator; import java.util.List; +import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin; + /** * System location settings (Settings > Location). The screen has three parts: *
    @@ -373,9 +376,15 @@ public class LocationSettings extends LocationSettingsBase // corner cases, the location might still be enabled. In such case the master switch should // be disabled but checked. final boolean enabled = (mode != android.provider.Settings.Secure.LOCATION_MODE_OFF); + EnforcedAdmin admin = RestrictedLockUtils.checkIfRestrictionEnforced(getActivity(), + UserManager.DISALLOW_SHARE_LOCATION, UserHandle.myUserId()); // Disable the whole switch bar instead of the switch itself. If we disabled the switch // only, it would be re-enabled again if the switch bar is not disabled. - mSwitchBar.setEnabled(!restricted); + if (admin != null) { + mSwitchBar.setDisabledByAdmin(admin); + } else { + mSwitchBar.setEnabled(!restricted); + } mLocationMode.setEnabled(enabled && !restricted); mCategoryRecentLocationRequests.setEnabled(enabled); diff --git a/src/com/android/settings/widget/SwitchBar.java b/src/com/android/settings/widget/SwitchBar.java index d5f469c6c46..b096cc401a6 100644 --- a/src/com/android/settings/widget/SwitchBar.java +++ b/src/com/android/settings/widget/SwitchBar.java @@ -35,6 +35,9 @@ import android.widget.Switch; import android.widget.TextView; import com.android.settings.R; +import com.android.settingslib.RestrictedLockUtils; + +import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin; import java.util.ArrayList; @@ -58,6 +61,9 @@ public class SwitchBar extends LinearLayout implements CompoundButton.OnCheckedC private String mLabel; private String mSummary; + private boolean mDisabledByAdmin = false; + private EnforcedAdmin mEnforcedAdmin = null; + private ArrayList mSwitchChangeListeners = new ArrayList(); @@ -153,11 +159,35 @@ public class SwitchBar extends LinearLayout implements CompoundButton.OnCheckedC } public void setEnabled(boolean enabled) { + if (enabled && mDisabledByAdmin) { + setDisabledByAdmin(null); + return; + } super.setEnabled(enabled); mTextView.setEnabled(enabled); mSwitch.setEnabled(enabled); } + /** + * If admin is not null, disables the text and switch but keeps the view clickable. + * Otherwise, calls setEnabled which will enables the entire view including + * the text and switch. + */ + public void setDisabledByAdmin(EnforcedAdmin admin) { + mEnforcedAdmin = admin; + if (admin != null) { + super.setEnabled(true); + mDisabledByAdmin = true; + RestrictedLockUtils.setTextViewPadlock(mContext, mTextView, true); + mTextView.setEnabled(false); + mSwitch.setEnabled(false); + } else { + mDisabledByAdmin = false; + RestrictedLockUtils.setTextViewPadlock(mContext, mTextView, false); + setEnabled(true); + } + } + public final ToggleSwitch getSwitch() { return mSwitch; } @@ -182,8 +212,12 @@ public class SwitchBar extends LinearLayout implements CompoundButton.OnCheckedC @Override public void onClick(View v) { - final boolean isChecked = !mSwitch.isChecked(); - setChecked(isChecked); + if (mDisabledByAdmin) { + RestrictedLockUtils.sendShowAdminSupportDetailsIntent(mContext, mEnforcedAdmin); + } else { + final boolean isChecked = !mSwitch.isChecked(); + setChecked(isChecked); + } } public void propagateChecked(boolean isChecked) {