diff --git a/res/drawable/ic_settings_lock_outline.xml b/res/drawable/ic_settings_lock_outline.xml index 1c4202c0844..a13700b9013 100644 --- a/res/drawable/ic_settings_lock_outline.xml +++ b/res/drawable/ic_settings_lock_outline.xml @@ -16,12 +16,12 @@ --> + android:pathData="M8,16c1.1,0,2-0.9,2-2s-0.9-2-2-2s-2,0.9-2,2S6.9,16,8,16zM14,7h-1V5c0-2.8-2.2-5-5-5S3,2.2,3,5v2H2C0.9,7,0,7.9,0,9v10c0,1.1,0.9,2,2,2h12c1.1,0,2-0.9,2-2V9C16,7.9,15.1,7,14,7z M4.9,5c0-1.7,1.4-3.1,3.1-3.1s3.1,1.4,3.1,3.1v2H4.9V5z M14,19H2V9h12V19z" /> diff --git a/res/layout/spinner_dropdown_restricted_item.xml b/res/layout/spinner_dropdown_restricted_item.xml new file mode 100644 index 00000000000..a965ad8e67b --- /dev/null +++ b/res/layout/spinner_dropdown_restricted_item.xml @@ -0,0 +1,22 @@ + + + \ No newline at end of file diff --git a/res/values/colors.xml b/res/values/colors.xml index f3fea105b1e..5cf98fe38ef 100644 --- a/res/values/colors.xml +++ b/res/values/colors.xml @@ -102,4 +102,6 @@ #ffabffec + #66000000 + diff --git a/res/xml/configure_notification_settings.xml b/res/xml/configure_notification_settings.xml index d64132a3078..f9980ddb391 100644 --- a/res/xml/configure_notification_settings.xml +++ b/res/xml/configure_notification_settings.xml @@ -26,7 +26,7 @@ android:persistent="false" /> - mRestrictedItems = new ArrayList<>(); + + public RestrictedDropDownPreference(Context context) { + this(context, null); + } + + public RestrictedDropDownPreference(Context context, AttributeSet attrs) { + super(context, attrs); + + mRestrictedPadlock = RestrictedLockUtils.getRestrictedPadlock(context); + mRestrictedPadlockPadding = context.getResources().getDimensionPixelSize( + R.dimen.restricted_lock_icon_padding); + } + + private final OnItemSelectedListener mItemSelectedListener = new OnItemSelectedListener() { + @Override + public void onItemSelected(AdapterView parent, View v, int position, long id) { + if (position >= 0) { + String value = getEntryValues()[position].toString(); + RestrictedItem item = getRestrictedItemForEntryValue(value); + if (item != null) { + RestrictedLockUtils.sendShowAdminSupportDetailsIntent(getContext(), + item.enforcedAdmin); + mSpinner.setSelection(findIndexOfValue(getValue())); + } else if (!value.equals(getValue()) && callChangeListener(value)) { + setValue(value); + } + } + } + + @Override + public void onNothingSelected(AdapterView parent) { + // noop + } + }; + + @Override + protected ArrayAdapter createAdapter() { + return new RestrictedArrayItemAdapter(getContext()); + } + + @Override + public void setValue(String value) { + if (getRestrictedItemForEntryValue(value) != null) { + return; + } + super.setValue(value); + } + + @Override + public void onBindViewHolder(PreferenceViewHolder view) { + super.onBindViewHolder(view); + mSpinner = (Spinner) view.itemView.findViewById(R.id.spinner); + mSpinner.setOnItemSelectedListener(mItemSelectedListener); + } + + private class RestrictedArrayItemAdapter extends ArrayAdapter { + public RestrictedArrayItemAdapter(Context context) { + super(context, R.layout.spinner_dropdown_restricted_item); + } + + @Override + public View getDropDownView(int position, View convertView, ViewGroup parent) { + TextView view = (TextView) super.getView(position, convertView, parent); + CharSequence entry = getItem(position); + boolean isEntryRestricted = isRestrictedForEntry(entry); + RestrictedLockUtils.setTextViewPadlock(getContext(), view, isEntryRestricted); + view.setEnabled(!isEntryRestricted); + return view; + } + } + + private boolean isRestrictedForEntry(CharSequence entry) { + if (entry == null) { + return false; + } + for (RestrictedItem item : mRestrictedItems) { + if (entry.equals(item.entry)) { + return true; + } + } + return false; + } + + private RestrictedItem getRestrictedItemForEntryValue(CharSequence entryValue) { + if (entryValue == null) { + return null; + } + for (RestrictedItem item : mRestrictedItems) { + if (entryValue.equals(item.entryValue)) { + return item; + } + } + return null; + } + + public void addRestrictedItem(RestrictedItem item) { + mRestrictedItems.add(item); + } + + public static class RestrictedItem { + public CharSequence entry; + public CharSequence entryValue; + public EnforcedAdmin enforcedAdmin; + + public RestrictedItem(CharSequence entry, CharSequence entryValue, + EnforcedAdmin enforcedAdmin) { + this.entry = entry; + this.entryValue = entryValue; + this.enforcedAdmin = enforcedAdmin; + } + } +} \ No newline at end of file diff --git a/src/com/android/settings/RestrictedLockImageSpan.java b/src/com/android/settings/RestrictedLockImageSpan.java new file mode 100644 index 00000000000..66c60cbaae3 --- /dev/null +++ b/src/com/android/settings/RestrictedLockImageSpan.java @@ -0,0 +1,72 @@ +/* + * 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.content.Context; +import android.graphics.Canvas; +import android.graphics.Paint; +import android.graphics.drawable.Drawable; +import android.text.style.ImageSpan; + +import java.lang.ref.WeakReference; + +/** + * An extension of ImageSpan which adds a padding before the image. + */ +public class RestrictedLockImageSpan extends ImageSpan { + private Context mContext; + private final float mExtraPadding; + private final Drawable mRestrictedPadlock; + + public RestrictedLockImageSpan(Context context) { + // we are overriding getDrawable, so passing null to super class here. + super((Drawable) null); + + mContext = context; + mExtraPadding = mContext.getResources().getDimensionPixelSize( + R.dimen.restricted_lock_icon_padding); + mRestrictedPadlock = RestrictedLockUtils.getRestrictedPadlock(mContext); + } + + @Override + public Drawable getDrawable() { + return mRestrictedPadlock; + } + + @Override + public void draw(Canvas canvas, CharSequence text, int start, int end, float x, int top, int y, + int bottom, Paint paint) { + Drawable drawable = getDrawable(); + canvas.save(); + + // Add extra padding before the padlock. + float transX = x + mExtraPadding; + float transY = bottom - drawable.getBounds().bottom - paint.getFontMetricsInt().descent; + + canvas.translate(transX, transY); + drawable.draw(canvas); + canvas.restore(); + } + + @Override + public int getSize(Paint paint, CharSequence text, int start, int end, + Paint.FontMetricsInt fontMetrics) { + int size = super.getSize(paint, text, start, end, fontMetrics); + size += 2 * mExtraPadding; + return size; + } +} \ No newline at end of file diff --git a/src/com/android/settings/RestrictedLockUtils.java b/src/com/android/settings/RestrictedLockUtils.java new file mode 100644 index 00000000000..1a387632dde --- /dev/null +++ b/src/com/android/settings/RestrictedLockUtils.java @@ -0,0 +1,228 @@ +/* + * 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.admin.DevicePolicyManager; +import android.content.ComponentName; +import android.content.Context; +import android.content.Intent; +import android.graphics.Color; +import android.graphics.drawable.Drawable; +import android.os.Bundle; +import android.os.UserHandle; +import android.text.Spanned; +import android.text.SpannableStringBuilder; +import android.text.style.ForegroundColorSpan; +import android.text.style.ImageSpan; +import android.view.MenuItem; +import android.widget.TextView; + +import java.util.List; + +/** + * Utility class to host methods usable in adding a restricted padlock icon and showing admin + * support message dialog. + */ +public class RestrictedLockUtils { + /** + * @return drawables for displaying with settings that are locked by a device admin. + */ + public static Drawable getRestrictedPadlock(Context context) { + Drawable restrictedPadlock = context.getDrawable(R.drawable.ic_settings_lock_outline); + final int iconSize = context.getResources().getDimensionPixelSize( + R.dimen.restricted_lock_icon_size); + restrictedPadlock.setBounds(0, 0, iconSize, iconSize); + return restrictedPadlock; + } + + /** + * Checks if a restriction is enforced on a user and returns the enforced admin and + * admin userId. + * + * @param userRestriction Restriction to check + * @param userId User which we need to check if restriction is enforced on. + * @return EnforcedAdmin Object containing the enforce admin and admin user details, or + * {@code null} If the restriction is not set. If the restriction is set by both device owner + * and profile owner, then the admin will be set to {@code null} and userId to + * {@link UserHandle#USER_NULL}. + */ + public static EnforcedAdmin checkIfRestrictionEnforced(Context context, + String userRestriction, int userId) { + DevicePolicyManager dpm = (DevicePolicyManager) context.getSystemService( + Context.DEVICE_POLICY_SERVICE); + ComponentName deviceOwner = dpm.getDeviceOwnerComponentOnAnyUser(); + int deviceOwnerUserId = dpm.getDeviceOwnerUserId(); + boolean enforcedByDeviceOwner = false; + if (deviceOwner != null && deviceOwnerUserId != UserHandle.USER_NULL) { + Bundle enforcedRestrictions = dpm.getUserRestrictions(deviceOwner, deviceOwnerUserId); + if (enforcedRestrictions != null + && enforcedRestrictions.getBoolean(userRestriction, false)) { + enforcedByDeviceOwner = true; + } + } + + ComponentName profileOwner = null; + boolean enforcedByProfileOwner = false; + if (userId != UserHandle.USER_NULL) { + profileOwner = dpm.getProfileOwnerAsUser(userId); + if (profileOwner != null) { + Bundle enforcedRestrictions = dpm.getUserRestrictions(profileOwner, userId); + if (enforcedRestrictions != null + && enforcedRestrictions.getBoolean(userRestriction, false)) { + enforcedByProfileOwner = true; + } + } + } + + if (!enforcedByDeviceOwner && !enforcedByProfileOwner) { + return null; + } + + EnforcedAdmin admin = null; + if (enforcedByDeviceOwner && enforcedByProfileOwner) { + admin = new EnforcedAdmin(); + } else if (enforcedByDeviceOwner) { + admin = new EnforcedAdmin(deviceOwner, deviceOwnerUserId); + } else { + admin = new EnforcedAdmin(profileOwner, userId); + } + return admin; + } + + /** + * Checks if lock screen notification features are disabled by policy. This should be + * only used for keyguard notification features but not the keyguard features + * (e.g. KEYGUARD_DISABLE_FINGERPRINT) where a profile owner can set them on the parent user + * as it won't work for that case. + * + * @param keyguardNotificationFeatures Could be any of notification features that can be + * disabled by {@link android.app.admin.DevicePolicyManager#setKeyguardDisabledFeatures}. + * @return EnforcedAdmin Object containing the enforce admin and admin user details, or + * {@code null} If the notification features are not disabled. If the restriction is set by + * multiple admins, then the admin will be set to {@code null} and userId to + * {@link UserHandle#USER_NULL}. + */ + public static EnforcedAdmin checkIfKeyguardNotificationFeaturesDisabled(Context context, + int keyguardNotificationFeatures) { + final DevicePolicyManager dpm = (DevicePolicyManager) context.getSystemService( + Context.DEVICE_POLICY_SERVICE); + boolean isDisabledByMultipleAdmins = false; + ComponentName adminComponent = null; + List admins = dpm.getActiveAdmins(); + int disabledKeyguardFeatures; + for (ComponentName admin : admins) { + disabledKeyguardFeatures = dpm.getKeyguardDisabledFeatures(admin); + if ((disabledKeyguardFeatures & keyguardNotificationFeatures) != 0) { + if (adminComponent == null) { + adminComponent = admin; + } else { + isDisabledByMultipleAdmins = true; + break; + } + } + } + EnforcedAdmin enforcedAdmin = null; + if (adminComponent != null) { + if (!isDisabledByMultipleAdmins) { + enforcedAdmin = new EnforcedAdmin(adminComponent, UserHandle.myUserId()); + } else { + enforcedAdmin = new EnforcedAdmin(); + } + } + return enforcedAdmin; + } + + /** + * Set the menu item as disabled by admin by adding a restricted padlock at the end of the + * text and set the click listener which will send an intent to show the admin support details + * dialog. + */ + public static void setMenuItemAsDisabledByAdmin(final Context context, + final MenuItem item, final EnforcedAdmin admin) { + SpannableStringBuilder sb = new SpannableStringBuilder(item.getTitle()); + removeExistingRestrictedSpans(sb); + + final int disabledColor = context.getColor(R.color.disabled_text_color); + sb.setSpan(new ForegroundColorSpan(disabledColor), 0, sb.length(), + Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); + ImageSpan image = new RestrictedLockImageSpan(context); + sb.append(" ", image, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); + item.setTitle(sb); + + item.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() { + @Override + public boolean onMenuItemClick(MenuItem item) { + sendShowAdminSupportDetailsIntent(context, admin); + return true; + } + }); + } + + private static void removeExistingRestrictedSpans(SpannableStringBuilder sb) { + final int length = sb.length(); + RestrictedLockImageSpan[] imageSpans = sb.getSpans(length - 1, length, + RestrictedLockImageSpan.class); + for (ImageSpan span : imageSpans) { + sb.removeSpan(span); + } + ForegroundColorSpan[] colorSpans = sb.getSpans(0, length, ForegroundColorSpan.class); + for (ForegroundColorSpan span : colorSpans) { + sb.removeSpan(span); + } + } + + /** + * Send the intent to trigger the {@link android.settings.ShowAdminSupportDetailsDialog}. + */ + public static void sendShowAdminSupportDetailsIntent(Context context, EnforcedAdmin admin) { + Intent intent = new Intent(context, ShowAdminSupportDetailsDialog.class); + int adminUserId = UserHandle.myUserId(); + if (admin != null) { + if (admin.component != null) { + intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN, admin.component); + } + if (admin.userId != UserHandle.USER_NULL) { + adminUserId = admin.userId; + } + intent.putExtra(Intent.EXTRA_USER_ID, adminUserId); + } + context.startActivityAsUser(intent, new UserHandle(adminUserId)); + } + + public static void setTextViewPadlock(Context context, + TextView textView, boolean showPadlock) { + final SpannableStringBuilder sb = new SpannableStringBuilder(textView.getText()); + removeExistingRestrictedSpans(sb); + if (showPadlock) { + final ImageSpan image = new RestrictedLockImageSpan(context); + sb.append(" ", image, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); + } + textView.setText(sb); + } + + public static class EnforcedAdmin { + public ComponentName component = null; + public int userId = UserHandle.USER_NULL; + + public EnforcedAdmin(ComponentName component, int userId) { + this.component = component; + this.userId = userId; + } + + public EnforcedAdmin() {} + } +} \ No newline at end of file diff --git a/src/com/android/settings/RestrictedPreference.java b/src/com/android/settings/RestrictedPreference.java index 7903f930951..5ac52cba25f 100644 --- a/src/com/android/settings/RestrictedPreference.java +++ b/src/com/android/settings/RestrictedPreference.java @@ -16,7 +16,6 @@ package com.android.settings; -import android.content.ComponentName; import android.content.Context; import android.os.UserHandle; import android.support.v4.content.res.TypedArrayUtils; @@ -25,6 +24,8 @@ import android.support.v7.preference.PreferenceManager; import android.support.v7.preference.PreferenceViewHolder; import android.util.AttributeSet; +import static com.android.settings.RestrictedLockUtils.EnforcedAdmin; + /** * Preference class that supports being disabled by a user restriction * set by a device admin. @@ -78,12 +79,8 @@ public class RestrictedPreference extends Preference { mHelper.checkRestrictionAndSetDisabled(userRestriction, userId); } - public void setDisabledByAdmin(boolean disabled) { - mHelper.setDisabledByAdmin(disabled, null, UserHandle.USER_NULL); - } - - public void setDisabledByAdmin(boolean disabled, ComponentName admin, int userId) { - if (mHelper.setDisabledByAdmin(disabled, admin, userId)) { + public void setDisabledByAdmin(EnforcedAdmin admin) { + if (mHelper.setDisabledByAdmin(admin)) { notifyChanged(); } } diff --git a/src/com/android/settings/RestrictedPreferenceHelper.java b/src/com/android/settings/RestrictedPreferenceHelper.java index 385a8a2bb9b..f0c0bf7bf2b 100644 --- a/src/com/android/settings/RestrictedPreferenceHelper.java +++ b/src/com/android/settings/RestrictedPreferenceHelper.java @@ -16,36 +16,33 @@ package com.android.settings; -import android.app.admin.DevicePolicyManager; -import android.content.ComponentName; import android.content.Context; -import android.content.Intent; import android.content.res.TypedArray; import android.graphics.drawable.Drawable; -import android.os.Bundle; import android.os.UserHandle; import android.support.v7.preference.Preference; import android.support.v7.preference.PreferenceViewHolder; +import android.text.Spanned; +import android.text.SpannableStringBuilder; +import android.text.style.ImageSpan; import android.util.AttributeSet; import android.util.TypedValue; -import android.view.View; import android.widget.TextView; +import static com.android.settings.RestrictedLockUtils.EnforcedAdmin; + /** * Helper class for managing settings preferences that can be disabled * by device admins via user restrictions. - * - **/ + */ public class RestrictedPreferenceHelper { private final Context mContext; private final Preference mPreference; private final Drawable mRestrictedPadlock; private final int mRestrictedPadlockPadding; - private final DevicePolicyManager mDevicePolicyManager; private boolean mDisabledByAdmin; - private ComponentName mEnforcedAdmin; - private int mUserId = UserHandle.USER_NULL; + private EnforcedAdmin mEnforcedAdmin; private String mAttrUserRestriction = null; RestrictedPreferenceHelper(Context context, Preference preference, @@ -53,13 +50,10 @@ public class RestrictedPreferenceHelper { mContext = context; mPreference = preference; - mRestrictedPadlock = getRestrictedPadlock(mContext); + mRestrictedPadlock = RestrictedLockUtils.getRestrictedPadlock(mContext); mRestrictedPadlockPadding = mContext.getResources().getDimensionPixelSize( R.dimen.restricted_lock_icon_padding); - mDevicePolicyManager = (DevicePolicyManager) mContext.getSystemService( - Context.DEVICE_POLICY_SERVICE); - mAttrUserRestriction = attrs.getAttributeValue( R.styleable.RestrictedPreference_userRestriction); final TypedArray attributes = context.obtainStyledAttributes(attrs, @@ -83,12 +77,9 @@ public class RestrictedPreferenceHelper { public void onBindViewHolder(PreferenceViewHolder holder) { final TextView titleView = (TextView) holder.findViewById(android.R.id.title); if (titleView != null) { + RestrictedLockUtils.setTextViewPadlock(mContext, titleView, mDisabledByAdmin); if (mDisabledByAdmin) { - titleView.setCompoundDrawablesRelative(null, null, mRestrictedPadlock, null); - titleView.setCompoundDrawablePadding(mRestrictedPadlockPadding); holder.itemView.setEnabled(true); - } else { - titleView.setCompoundDrawablesRelative(null, null, null, null); } } } @@ -100,14 +91,7 @@ public class RestrictedPreferenceHelper { */ public boolean performClick() { if (mDisabledByAdmin) { - Intent intent = new Intent(mContext, ShowAdminSupportDetailsDialog.class); - if (mEnforcedAdmin != null) { - intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN, mEnforcedAdmin); - } - if (mUserId != UserHandle.USER_NULL) { - intent.putExtra(Intent.EXTRA_USER_ID, mUserId); - } - mContext.startActivity(intent); + RestrictedLockUtils.sendShowAdminSupportDetailsIntent(mContext, mEnforcedAdmin); return true; } return false; @@ -129,57 +113,23 @@ public class RestrictedPreferenceHelper { * @param userId user to check the restriction for. */ public void checkRestrictionAndSetDisabled(String userRestriction, int userId) { - ComponentName deviceOwner = mDevicePolicyManager.getDeviceOwnerComponentOnAnyUser(); - int deviceOwnerUserId = mDevicePolicyManager.getDeviceOwnerUserId(); - boolean enforcedByDeviceOwner = false; - if (deviceOwner != null && deviceOwnerUserId != UserHandle.USER_NULL) { - enforcedByDeviceOwner = isEnforcedByAdmin( - deviceOwner, userRestriction, deviceOwnerUserId); - } - - ComponentName profileOwner = mDevicePolicyManager.getProfileOwnerAsUser(userId); - boolean enforcedByProfileOwner = false; - if (profileOwner != null && userId != UserHandle.USER_NULL) { - enforcedByProfileOwner = isEnforcedByAdmin( - profileOwner, userRestriction, userId); - } - - if (!enforcedByDeviceOwner && !enforcedByProfileOwner) { - setDisabledByAdmin(false, null, UserHandle.USER_NULL); - return; - } - - if (enforcedByDeviceOwner && enforcedByProfileOwner) { - setDisabledByAdmin(true, null, UserHandle.USER_NULL); - } else if (enforcedByDeviceOwner) { - setDisabledByAdmin(true, deviceOwner, deviceOwnerUserId); - } else { - setDisabledByAdmin(true, profileOwner, userId); - } - } - - private boolean isEnforcedByAdmin(ComponentName admin, String userRestriction, int userId) { - Bundle enforcedRestrictions = mDevicePolicyManager.getUserRestrictions(admin, userId); - if (enforcedRestrictions != null - && enforcedRestrictions.getBoolean(userRestriction, false)) { - return true; - } - return false; + EnforcedAdmin admin = RestrictedLockUtils.checkIfRestrictionEnforced(mContext, + userRestriction, userId); + setDisabledByAdmin(admin); } /** - * Disable this preference. + * Disable this preference based on the enforce admin. * - * @param disabled true if preference should be disabled. - * @param admin Device admin that disabled the preference. - * @param userId userId the device admin is installed for. + * @param EnforcedAdmin Details of the admin who enforced the restriction. If it + * is {@code null}, then this preference will be enabled. Otherwise, it will be disabled. * @return true if the disabled state was changed. */ - public boolean setDisabledByAdmin(boolean disabled, ComponentName admin, int userId) { + public boolean setDisabledByAdmin(EnforcedAdmin admin) { + final boolean disabled = (admin != null ? true : false); + mEnforcedAdmin = (disabled ? admin : null); if (mDisabledByAdmin != disabled) { mDisabledByAdmin = disabled; - mEnforcedAdmin = admin; - mUserId = userId; mPreference.setEnabled(!disabled); return true; } @@ -189,15 +139,4 @@ public class RestrictedPreferenceHelper { public boolean isDisabledByAdmin() { return mDisabledByAdmin; } - - /** - * @return drawables for displaying with settings that are locked by a device admin. - */ - public static Drawable getRestrictedPadlock(Context context) { - Drawable restrictedPadlock = context.getDrawable(R.drawable.ic_settings_lock_outline); - final int iconSize = context.getResources().getDimensionPixelSize( - R.dimen.restricted_lock_icon_size); - restrictedPadlock.setBounds(0, 0, iconSize, iconSize); - return restrictedPadlock; - } } diff --git a/src/com/android/settings/RestrictedSwitchPreference.java b/src/com/android/settings/RestrictedSwitchPreference.java index 526bd42b339..f0c3315f743 100644 --- a/src/com/android/settings/RestrictedSwitchPreference.java +++ b/src/com/android/settings/RestrictedSwitchPreference.java @@ -16,7 +16,6 @@ package com.android.settings; -import android.content.ComponentName; import android.content.Context; import android.os.UserHandle; import android.support.v4.content.res.TypedArrayUtils; @@ -25,6 +24,8 @@ import android.support.v7.preference.PreferenceViewHolder; import android.support.v14.preference.SwitchPreference; import android.util.AttributeSet; +import static com.android.settings.RestrictedLockUtils.EnforcedAdmin; + /** * Version of SwitchPreference that can be disabled by a device admin * using a user restriction. @@ -78,12 +79,8 @@ public class RestrictedSwitchPreference extends SwitchPreference { mHelper.checkRestrictionAndSetDisabled(userRestriction, userId); } - public void setDisabledByAdmin(boolean disabled) { - mHelper.setDisabledByAdmin(disabled, null, UserHandle.USER_NULL); - } - - public void setDisabledByAdmin(boolean disabled, ComponentName admin, int userId) { - if (mHelper.setDisabledByAdmin(disabled, admin, userId)) { + public void setDisabledByAdmin(EnforcedAdmin admin) { + if (mHelper.setDisabledByAdmin(admin)) { notifyChanged(); } } diff --git a/src/com/android/settings/accounts/AccountSyncSettings.java b/src/com/android/settings/accounts/AccountSyncSettings.java index 0590cbda770..a060c767f9a 100644 --- a/src/com/android/settings/accounts/AccountSyncSettings.java +++ b/src/com/android/settings/accounts/AccountSyncSettings.java @@ -28,11 +28,13 @@ import android.app.Dialog; import android.content.ContentResolver; import android.content.Context; import android.content.DialogInterface; +import android.content.Intent; import android.content.SyncAdapterType; import android.content.SyncInfo; import android.content.SyncStatusInfo; import android.content.pm.ProviderInfo; import android.content.pm.UserInfo; +import android.graphics.Color; import android.os.Binder; import android.os.Bundle; import android.os.UserHandle; @@ -52,6 +54,8 @@ import android.widget.TextView; import com.android.internal.logging.MetricsLogger; import com.android.settings.R; +import com.android.settings.RestrictedLockUtils; +import com.android.settings.ShowAdminSupportDetailsDialog; import com.android.settings.Utils; import com.google.android.collect.Lists; @@ -61,6 +65,8 @@ import java.util.Collections; import java.util.Date; import java.util.List; +import static com.android.settings.RestrictedLockUtils.EnforcedAdmin; + public class AccountSyncSettings extends AccountPreferenceBase { public static final String ACCOUNT_KEY = "account"; @@ -259,13 +265,17 @@ public class AccountSyncSettings extends AccountPreferenceBase { MenuItem syncCancel = menu.add(0, MENU_SYNC_CANCEL_ID, 0, getString(R.string.sync_menu_sync_cancel)) .setIcon(com.android.internal.R.drawable.ic_menu_close_clear_cancel); - final UserManager um = (UserManager) getSystemService(Context.USER_SERVICE); - if (!um.hasUserRestriction(UserManager.DISALLOW_MODIFY_ACCOUNTS, mUserHandle)) { - MenuItem removeAccount = menu.add(0, MENU_REMOVE_ACCOUNT_ID, 0, - getString(R.string.remove_account_label)) - .setIcon(R.drawable.ic_menu_delete); - removeAccount.setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER | - MenuItem.SHOW_AS_ACTION_WITH_TEXT); + MenuItem removeAccount = menu.add(0, MENU_REMOVE_ACCOUNT_ID, 0, + getString(R.string.remove_account_label)) + .setIcon(R.drawable.ic_menu_delete); + removeAccount.setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER | + MenuItem.SHOW_AS_ACTION_WITH_TEXT); + final EnforcedAdmin admin = RestrictedLockUtils.checkIfRestrictionEnforced( + getPrefContext(), UserManager.DISALLOW_MODIFY_ACCOUNTS, + mUserHandle.getIdentifier()); + if (admin != null) { + RestrictedLockUtils.setMenuItemAsDisabledByAdmin(getPrefContext(), + removeAccount, admin); } syncNow.setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER | MenuItem.SHOW_AS_ACTION_WITH_TEXT); diff --git a/src/com/android/settings/notification/ConfigureNotificationSettings.java b/src/com/android/settings/notification/ConfigureNotificationSettings.java index f3f74a79eab..9f0767b5224 100644 --- a/src/com/android/settings/notification/ConfigureNotificationSettings.java +++ b/src/com/android/settings/notification/ConfigureNotificationSettings.java @@ -19,9 +19,11 @@ package com.android.settings.notification; import com.android.internal.widget.LockPatternUtils; import com.android.settings.InstrumentedFragment; import com.android.settings.R; +import com.android.settings.RestrictedDropDownPreference; +import com.android.settings.RestrictedDropDownPreference.RestrictedItem; +import com.android.settings.RestrictedLockUtils; import com.android.settings.SettingsPreferenceFragment; -import android.app.admin.DevicePolicyManager; import android.content.ContentResolver; import android.content.Context; import android.database.ContentObserver; @@ -30,13 +32,18 @@ import android.os.Bundle; import android.os.Handler; import android.os.UserHandle; import android.provider.Settings; -import android.support.v7.preference.DropDownPreference; import android.support.v7.preference.Preference; import android.support.v7.preference.Preference.OnPreferenceChangeListener; import android.support.v7.preference.TwoStatePreference; import android.util.Log; import java.util.ArrayList; +import java.util.List; + +import static android.app.admin.DevicePolicyManager.KEYGUARD_DISABLE_SECURE_NOTIFICATIONS; +import static android.app.admin.DevicePolicyManager.KEYGUARD_DISABLE_UNREDACTED_NOTIFICATIONS; + +import static com.android.settings.RestrictedLockUtils.EnforcedAdmin; public class ConfigureNotificationSettings extends SettingsPreferenceFragment { private static final String TAG = "ConfigNotiSettings"; @@ -49,7 +56,7 @@ public class ConfigureNotificationSettings extends SettingsPreferenceFragment { private Context mContext; private TwoStatePreference mNotificationPulse; - private DropDownPreference mLockscreen; + private RestrictedDropDownPreference mLockscreen; private boolean mSecure; private int mLockscreenSelectedValue; @@ -124,28 +131,36 @@ public class ConfigureNotificationSettings extends SettingsPreferenceFragment { // === Lockscreen (public / private) notifications === private void initLockscreenNotifications() { - mLockscreen = (DropDownPreference) getPreferenceScreen().findPreference( + mLockscreen = (RestrictedDropDownPreference) getPreferenceScreen().findPreference( KEY_LOCK_SCREEN_NOTIFICATIONS); if (mLockscreen == null) { Log.i(TAG, "Preference not found: " + KEY_LOCK_SCREEN_NOTIFICATIONS); return; } - boolean isSecureNotificationsDisabled = isSecureNotificationsDisabled(); - boolean isUnredactedNotificationsDisabled = isUnredactedNotificationsDisabled(); ArrayList entries = new ArrayList<>(); ArrayList values = new ArrayList<>(); - if (!isSecureNotificationsDisabled && !isUnredactedNotificationsDisabled) { - entries.add(getString(R.string.lock_screen_notifications_summary_show)); - values.add(Integer.toString(R.string.lock_screen_notifications_summary_show)); - } - if (mSecure && !isSecureNotificationsDisabled) { - entries.add(getString(R.string.lock_screen_notifications_summary_hide)); - values.add(Integer.toString(R.string.lock_screen_notifications_summary_hide)); - } entries.add(getString(R.string.lock_screen_notifications_summary_disable)); values.add(Integer.toString(R.string.lock_screen_notifications_summary_disable)); + String summaryShowEntry = getString(R.string.lock_screen_notifications_summary_show); + String summaryShowEntryValue = Integer.toString( + R.string.lock_screen_notifications_summary_show); + entries.add(summaryShowEntry); + values.add(summaryShowEntryValue); + setRestrictedIfNotificationFeaturesDisabled(summaryShowEntry, summaryShowEntryValue, + KEYGUARD_DISABLE_SECURE_NOTIFICATIONS | KEYGUARD_DISABLE_UNREDACTED_NOTIFICATIONS); + + if (mSecure) { + String summaryHideEntry = getString(R.string.lock_screen_notifications_summary_hide); + String summaryHideEntryValue = Integer.toString( + R.string.lock_screen_notifications_summary_hide); + entries.add(summaryHideEntry); + values.add(summaryHideEntryValue); + setRestrictedIfNotificationFeaturesDisabled(summaryHideEntry, summaryHideEntryValue, + KEYGUARD_DISABLE_SECURE_NOTIFICATIONS); + } + mLockscreen.setEntries(entries.toArray(new CharSequence[entries.size()])); mLockscreen.setEntryValues(values.toArray(new CharSequence[values.size()])); updateLockscreenNotifications(); @@ -174,18 +189,14 @@ public class ConfigureNotificationSettings extends SettingsPreferenceFragment { } } - private boolean isSecureNotificationsDisabled() { - final DevicePolicyManager dpm = - (DevicePolicyManager) getSystemService(Context.DEVICE_POLICY_SERVICE); - return dpm != null && (dpm.getKeyguardDisabledFeatures(null) - & DevicePolicyManager.KEYGUARD_DISABLE_SECURE_NOTIFICATIONS) != 0; - } - - private boolean isUnredactedNotificationsDisabled() { - final DevicePolicyManager dpm = - (DevicePolicyManager) getSystemService(Context.DEVICE_POLICY_SERVICE); - return dpm != null && (dpm.getKeyguardDisabledFeatures(null) - & DevicePolicyManager.KEYGUARD_DISABLE_UNREDACTED_NOTIFICATIONS) != 0; + private void setRestrictedIfNotificationFeaturesDisabled(CharSequence entry, + CharSequence entryValue, int keyguardNotificationFeatures) { + EnforcedAdmin admin = RestrictedLockUtils.checkIfKeyguardNotificationFeaturesDisabled( + mContext, keyguardNotificationFeatures); + if (admin != null) { + RestrictedItem item = new RestrictedItem(entry, entryValue, admin); + mLockscreen.addRestrictedItem(item); + } } private void updateLockscreenNotifications() {