diff --git a/res/layout/preference_importance_slider.xml b/res/layout/preference_importance_slider.xml index 00993842a0e..677a32b9e54 100644 --- a/res/layout/preference_importance_slider.xml +++ b/res/layout/preference_importance_slider.xml @@ -23,35 +23,11 @@ android:paddingEnd="?android:attr/listPreferredItemPaddingEnd" android:orientation="vertical" android:clickable="false" - android:focusable="false" - android:paddingTop="8dip" - android:paddingBottom="8dip"> - - - - + android:focusable="false" > + android:layout_height="wrap_content" > - diff --git a/res/values/strings.xml b/res/values/strings.xml index 0ef31a7d2bf..f86ba755da1 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -5839,6 +5839,9 @@ Importance + + Not set + Blocked: Never show these notifications @@ -5854,6 +5857,9 @@ Urgent: Peek onto the screen and make sound + + Reset + Notification assistant diff --git a/res/xml/app_notification_settings.xml b/res/xml/app_notification_settings.xml index 3141af85ece..d48cf9361a2 100644 --- a/res/xml/app_notification_settings.xml +++ b/res/xml/app_notification_settings.xml @@ -22,6 +22,47 @@ + android:order="1" /> + + + + + + + + + + + + + + + + + + diff --git a/res/xml/topic_notification_settings.xml b/res/xml/topic_notification_settings.xml index d5f28b32a65..2f155008148 100644 --- a/res/xml/topic_notification_settings.xml +++ b/res/xml/topic_notification_settings.xml @@ -19,26 +19,31 @@ android:key="topic_notification_settings"> + + android:order="2" /> - - + - + android:order="4" /> + + + diff --git a/src/com/android/settings/notification/AppNotificationSettings.java b/src/com/android/settings/notification/AppNotificationSettings.java index 4fcec269020..626e5a4f5ef 100644 --- a/src/com/android/settings/notification/AppNotificationSettings.java +++ b/src/com/android/settings/notification/AppNotificationSettings.java @@ -22,8 +22,7 @@ import android.content.pm.ActivityInfo; import android.content.pm.ApplicationInfo; import android.content.pm.ResolveInfo; import android.os.Bundle; -import android.service.notification.NotificationListenerService; -import android.support.v14.preference.SwitchPreference; +import android.service.notification.NotificationListenerService.Ranking; import android.support.v7.preference.Preference; import android.support.v7.preference.Preference.OnPreferenceChangeListener; import android.support.v7.preference.Preference.OnPreferenceClickListener; @@ -37,6 +36,7 @@ import com.android.settings.AppHeader; import com.android.settings.R; import com.android.settings.Utils; import com.android.settings.applications.AppInfoBase; +import com.android.settings.applications.LayoutPreference; import com.android.settings.notification.NotificationBackend.AppRow; import com.android.settingslib.RestrictedLockUtils; import com.android.settingslib.RestrictedSwitchPreference; @@ -79,7 +79,16 @@ public class AppNotificationSettings extends NotificationSettingsBase { super.onCreate(savedInstanceState); addPreferencesFromResource(R.xml.app_notification_settings); - getPreferenceScreen().setOrderingAsAdded(true); + mCategories = (PreferenceCategory) findPreference(KEY_CATEGORIES); + mBlock = (RestrictedSwitchPreference) findPreference(KEY_BLOCK); + mImportance = (ImportanceSeekBarPreference) findPreference(KEY_IMPORTANCE); + mImportanceReset = (LayoutPreference) findPreference(KEY_IMPORTANCE_RESET); + mImportanceTitle = findPreference(KEY_IMPORTANCE_TITLE); + mPriority = + (RestrictedSwitchPreference) getPreferenceScreen().findPreference(KEY_BYPASS_DND); + mSensitive = + (RestrictedSwitchPreference) getPreferenceScreen().findPreference(KEY_SENSITIVE); + mAppRow = mBackend.loadAppRow(mPm, mPkgInfo); // load settings intent @@ -90,16 +99,13 @@ public class AppNotificationSettings extends NotificationSettingsBase { // Add topics List topics = mBackend.getTopics(mPkg, mUid); if (topics.size() <= 1) { - setupImportancePref(mAppRow, null, mAppRow.appImportance); - setupPriorityPref(null, mAppRow.appBypassDnd); - setupSensitivePref(null, mAppRow.appSensitive); + removeAppPrefs(); + setupImportancePrefs(mAppRow.systemApp, mAppRow.appImportance); + setupPriorityPref(mAppRow.appBypassDnd); + setupSensitivePref(mAppRow.appSensitive); } else { + removeTopicPrefs(); setupBlockSwitch(); - mCategories = new PreferenceCategory(getPrefContext()); - mCategories.setKey(KEY_CATEGORIES); - mCategories.setTitle(R.string.notification_topic_categories); - mCategories.setOrderingAsAdded(true); - getPreferenceScreen().addPreference(mCategories); for (Notification.Topic topic : topics) { RestrictedPreference topicPreference = new RestrictedPreference(getPrefContext()); topicPreference.setDisabledByAdmin( @@ -138,22 +144,28 @@ public class AppNotificationSettings extends NotificationSettingsBase { @Override protected void updateDependents(int progress) { - updateDependents(progress == NotificationListenerService.Ranking.IMPORTANCE_NONE); + updateDependents(progress == Ranking.IMPORTANCE_NONE); + } + + private void removeTopicPrefs() { + setVisible(mImportance, false); + setVisible(mImportanceReset, false); + setVisible(mImportanceTitle, false); + setVisible(mPriority, false); + setVisible(mSensitive, false); + } + + private void removeAppPrefs() { + setVisible(mBlock, false); + setVisible(mCategories, false); } private void updateDependents(boolean banned) { - if (mBlock != null) { - mBlock.setEnabled(!mAppRow.systemApp); - mBlock.setDisabledByAdmin( - RestrictedLockUtils.checkIfApplicationIsSuspended(mContext, mPkg, mUserId)); - } - if (mCategories != null) { - setVisible(mCategories, !banned); - } + mBlock.setEnabled(!mAppRow.systemApp); + mCategories.setEnabled(!banned); } private void setupBlockSwitch() { - mBlock = new RestrictedSwitchPreference(getPrefContext()); mBlock.setDisabledByAdmin( RestrictedLockUtils.checkIfApplicationIsSuspended(mContext, mPkg, mUserId)); mBlock.setOnPreferenceChangeListener(new OnPreferenceChangeListener() { @@ -170,10 +182,6 @@ public class AppNotificationSettings extends NotificationSettingsBase { return success; } }); - mBlock.setKey(KEY_BLOCK); - mBlock.setTitle(R.string.app_notification_block_title); - mBlock.setSummary(R.string.app_notification_block_summary); - getPreferenceScreen().addPreference(mBlock); mBlock.setChecked(mAppRow.banned); updateDependents(mAppRow.banned); } diff --git a/src/com/android/settings/notification/ImportanceSeekBarPreference.java b/src/com/android/settings/notification/ImportanceSeekBarPreference.java index 920fcc30b77..aff96882544 100644 --- a/src/com/android/settings/notification/ImportanceSeekBarPreference.java +++ b/src/com/android/settings/notification/ImportanceSeekBarPreference.java @@ -20,12 +20,10 @@ import com.android.settings.R; import com.android.settings.SeekBarPreference; import android.content.Context; -import android.service.notification.NotificationListenerService; import android.support.v7.preference.PreferenceViewHolder; import android.util.AttributeSet; import android.widget.ImageView; import android.widget.SeekBar; -import android.widget.TextView; /** * A slider preference that controls notification importance. @@ -35,8 +33,6 @@ public class ImportanceSeekBarPreference extends SeekBarPreference implements private static final String TAG = "ImportanceSeekBarPref"; private Callback mCallback; - private TextView mSummaryTextView; - private String mSummary; private int mMinProgress; private boolean mSystemApp; @@ -64,6 +60,7 @@ public class ImportanceSeekBarPreference extends SeekBarPreference implements public void setMinimumProgress(int minProgress) { mMinProgress = minProgress; + notifyChanged(); } public void setSystemApp(boolean systemApp) { @@ -74,17 +71,12 @@ public class ImportanceSeekBarPreference extends SeekBarPreference implements @Override public void onBindViewHolder(PreferenceViewHolder view) { super.onBindViewHolder(view); - mSummaryTextView = (TextView) view.findViewById(com.android.internal.R.id.summary); if (mSystemApp) { ((ImageView) view.findViewById(R.id.low_importance)).getDrawable().setTint( getContext().getColor(R.color.importance_disabled_tint)); } - } - - @Override - public void setProgress(int progress) { - mSummary = getProgressSummary(progress); - super.setProgress(progress); + view.setDividerAllowedAbove(false); + view.setDividerAllowedBelow(false); } @Override @@ -94,37 +86,11 @@ public class ImportanceSeekBarPreference extends SeekBarPreference implements seekBar.setProgress(mMinProgress); progress = mMinProgress; } - mSummary = getProgressSummary(progress); - if (mSummaryTextView != null) { - mSummaryTextView.setText(mSummary); - } if (fromTouch) { mCallback.onImportanceChanged(progress); } } - @Override - public CharSequence getSummary() { - return mSummary; - } - - private String getProgressSummary(int progress) { - switch (progress) { - case NotificationListenerService.Ranking.IMPORTANCE_NONE: - return getContext().getString(R.string.notification_importance_blocked); - case NotificationListenerService.Ranking.IMPORTANCE_LOW: - return getContext().getString(R.string.notification_importance_low); - case NotificationListenerService.Ranking.IMPORTANCE_DEFAULT: - return getContext().getString(R.string.notification_importance_default); - case NotificationListenerService.Ranking.IMPORTANCE_HIGH: - return getContext().getString(R.string.notification_importance_high); - case NotificationListenerService.Ranking.IMPORTANCE_MAX: - return getContext().getString(R.string.notification_importance_max); - default: - return ""; - } - } - public interface Callback { void onImportanceChanged(int progress); } diff --git a/src/com/android/settings/notification/NotificationSettingsBase.java b/src/com/android/settings/notification/NotificationSettingsBase.java index 92d8d2f5208..740f8c1ba77 100644 --- a/src/com/android/settings/notification/NotificationSettingsBase.java +++ b/src/com/android/settings/notification/NotificationSettingsBase.java @@ -21,6 +21,7 @@ import com.android.settings.SettingsPreferenceFragment; import com.android.settings.applications.AppInfoBase; import com.android.settingslib.RestrictedLockUtils; import com.android.settingslib.RestrictedSwitchPreference; +import com.android.settings.applications.LayoutPreference; import android.app.Notification; import android.content.Context; @@ -32,10 +33,11 @@ import android.os.Bundle; import android.os.UserHandle; import android.provider.Settings; import android.service.notification.NotificationListenerService.Ranking; -import android.support.v14.preference.SwitchPreference; import android.support.v7.preference.Preference; import android.text.TextUtils; import android.util.Log; +import android.view.View; +import android.widget.Button; import android.widget.Toast; import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin; @@ -45,10 +47,13 @@ abstract public class NotificationSettingsBase extends SettingsPreferenceFragmen private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); protected static final String ARG_PACKAGE_INFO = "arg_info"; + protected static final String ARG_TOPIC = "arg_topic"; protected static final String KEY_BYPASS_DND = "bypass_dnd"; protected static final String KEY_SENSITIVE = "sensitive"; protected static final String KEY_IMPORTANCE = "importance"; + protected static final String KEY_IMPORTANCE_TITLE = "importance_title"; + protected static final String KEY_IMPORTANCE_RESET = "importance_reset_button"; protected PackageManager mPm; protected final NotificationBackend mBackend = new NotificationBackend(); @@ -58,7 +63,10 @@ abstract public class NotificationSettingsBase extends SettingsPreferenceFragmen protected int mUserId; protected String mPkg; protected PackageInfo mPkgInfo; + protected Notification.Topic mTopic; protected ImportanceSeekBarPreference mImportance; + protected Preference mImportanceTitle; + protected LayoutPreference mImportanceReset; protected RestrictedSwitchPreference mPriority; protected RestrictedSwitchPreference mSensitive; @@ -114,6 +122,10 @@ abstract public class NotificationSettingsBase extends SettingsPreferenceFragmen toastAndFinish(); return; } + + // Will be null for app wide settings. + mTopic = args != null && args.containsKey(ARG_TOPIC) + ? (Notification.Topic) args.getParcelable(ARG_TOPIC) : null; } @Override @@ -137,70 +149,89 @@ abstract public class NotificationSettingsBase extends SettingsPreferenceFragmen } } - protected void setupImportancePref(final NotificationBackend.AppRow appRow, - final Notification.Topic topic, int importance) { - if (mImportance == null) { - mImportance = new ImportanceSeekBarPreference(getPrefContext()); - mImportance.setDisabledByAdmin( - RestrictedLockUtils.checkIfApplicationIsSuspended(mContext, mPkg, mUserId)); - mImportance.setTitle(R.string.notification_importance_title); - mImportance.setKey(KEY_IMPORTANCE); - getPreferenceScreen().addPreference(mImportance); + protected void setupImportancePrefs(boolean isSystemApp, int importance) { + mImportance.setDisabledByAdmin( + RestrictedLockUtils.checkIfApplicationIsSuspended(mContext, mPkg, mUserId)); + if (importance == Ranking.IMPORTANCE_UNSPECIFIED) { + mImportance.setVisible(false); + mImportanceReset.setVisible(false); + mImportanceTitle.setOnPreferenceClickListener(showEditableImportance); + } else { + mImportanceTitle.setOnPreferenceClickListener(null); } - mImportance.setSystemApp(appRow.systemApp); + + mImportanceTitle.setSummary(getProgressSummary(importance)); + mImportance.setSystemApp(isSystemApp); mImportance.setMinimumProgress( - appRow.systemApp ? Ranking.IMPORTANCE_LOW : Ranking.IMPORTANCE_NONE); + isSystemApp ? Ranking.IMPORTANCE_LOW : Ranking.IMPORTANCE_NONE); mImportance.setMax(Ranking.IMPORTANCE_MAX); - // TODO: stop defaulting to 'normal' in the UI when there are mocks for this scenario. - importance = importance == Ranking.IMPORTANCE_UNSPECIFIED - ? Ranking.IMPORTANCE_DEFAULT - : importance; mImportance.setProgress(importance); mImportance.setCallback(new ImportanceSeekBarPreference.Callback() { @Override public void onImportanceChanged(int progress) { - mBackend.setImportance(appRow.pkg, appRow.uid, topic, progress); + mBackend.setImportance(mPkg, mUid, mTopic, progress); + mImportanceTitle.setSummary(getProgressSummary(progress)); updateDependents(progress); } }); + + Button button = (Button) mImportanceReset.findViewById(R.id.left_button); + button.setText(R.string.importance_reset); + button.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + mBackend.setImportance(mPkg, mUid, mTopic, Ranking.IMPORTANCE_UNSPECIFIED); + mImportanceReset.setVisible(false); + mImportance.setVisible(false); + mImportanceTitle.setOnPreferenceClickListener(showEditableImportance); + mImportanceTitle.setSummary(getProgressSummary(Ranking.IMPORTANCE_UNSPECIFIED)); + updateDependents(Ranking.IMPORTANCE_UNSPECIFIED); + } + }); + mImportanceReset.findViewById(R.id.right_button).setVisibility(View.INVISIBLE); } - protected void setupPriorityPref(final Notification.Topic topic, boolean priority) { - if (mPriority == null) { - mPriority = new RestrictedSwitchPreference(getPrefContext()); - mPriority.setDisabledByAdmin( - RestrictedLockUtils.checkIfApplicationIsSuspended(mContext, mPkg, mUserId)); - mPriority.setTitle(R.string.app_notification_override_dnd_title); - mPriority.setSummary(R.string.app_notification_override_dnd_summary); - mPriority.setKey(KEY_BYPASS_DND); - getPreferenceScreen().addPreference(mPriority); + private String getProgressSummary(int progress) { + switch (progress) { + case Ranking.IMPORTANCE_NONE: + return mContext.getString(R.string.notification_importance_blocked); + case Ranking.IMPORTANCE_LOW: + return mContext.getString(R.string.notification_importance_low); + case Ranking.IMPORTANCE_DEFAULT: + return mContext.getString(R.string.notification_importance_default); + case Ranking.IMPORTANCE_HIGH: + return mContext.getString(R.string.notification_importance_high); + case Ranking.IMPORTANCE_MAX: + return mContext.getString(R.string.notification_importance_max); + case Ranking.IMPORTANCE_UNSPECIFIED: + return mContext.getString(R.string.notification_importance_none); + default: + return ""; } + } + + protected void setupPriorityPref(boolean priority) { + mPriority.setDisabledByAdmin( + RestrictedLockUtils.checkIfApplicationIsSuspended(mContext, mPkg, mUserId)); mPriority.setChecked(priority); mPriority.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { @Override public boolean onPreferenceChange(Preference preference, Object newValue) { final boolean bypassZenMode = (Boolean) newValue; - return mBackend.setBypassZenMode(mPkgInfo.packageName, mUid, topic, bypassZenMode); + return mBackend.setBypassZenMode(mPkgInfo.packageName, mUid, mTopic, bypassZenMode); } }); } - protected void setupSensitivePref(final Notification.Topic topic, boolean sensitive) { - if (mSensitive == null) { - mSensitive = new RestrictedSwitchPreference(getPrefContext()); - mSensitive.setDisabledByAdmin( - RestrictedLockUtils.checkIfApplicationIsSuspended(mContext, mPkg, mUserId)); - mSensitive.setTitle(R.string.app_notification_sensitive_title); - mSensitive.setSummary(R.string.app_notification_sensitive_summary); - mSensitive.setKey(KEY_SENSITIVE); - getPreferenceScreen().addPreference(mSensitive); - } + protected void setupSensitivePref(boolean sensitive) { + mSensitive.setDisabledByAdmin( + RestrictedLockUtils.checkIfApplicationIsSuspended(mContext, mPkg, mUserId)); mSensitive.setChecked(sensitive); mSensitive.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { @Override public boolean onPreferenceChange(Preference preference, Object newValue) { final boolean sensitive = (Boolean) newValue; - return mBackend.setSensitive(mPkgInfo.packageName, mUid, topic, sensitive); + return mBackend.setSensitive(mPkgInfo.packageName, mUid, mTopic, sensitive); } }); } @@ -239,4 +270,18 @@ abstract public class NotificationSettingsBase extends SettingsPreferenceFragmen } return null; } + + private Preference.OnPreferenceClickListener showEditableImportance = + new Preference.OnPreferenceClickListener() { + @Override + public boolean onPreferenceClick(Preference preference) { + mBackend.setImportance(mPkg, mUid, mTopic, Ranking.IMPORTANCE_DEFAULT); + mImportance.setProgress(Ranking.IMPORTANCE_DEFAULT); + mImportanceTitle.setSummary(getProgressSummary(Ranking.IMPORTANCE_DEFAULT)); + mImportance.setVisible(true); + mImportanceReset.setVisible(true); + mImportanceTitle.setOnPreferenceClickListener(null); + return true; + } + }; } diff --git a/src/com/android/settings/notification/TopicNotificationSettings.java b/src/com/android/settings/notification/TopicNotificationSettings.java index ce4c4778df1..bbbcadef641 100644 --- a/src/com/android/settings/notification/TopicNotificationSettings.java +++ b/src/com/android/settings/notification/TopicNotificationSettings.java @@ -20,34 +20,19 @@ import com.android.internal.logging.MetricsProto.MetricsEvent; import com.android.internal.widget.LockPatternUtils; import com.android.settings.AppHeader; import com.android.settings.R; -import com.android.settings.SettingsPreferenceFragment; -import com.android.settings.applications.AppInfoBase; +import com.android.settings.applications.LayoutPreference; import com.android.settings.notification.NotificationBackend.TopicRow; import com.android.settingslib.RestrictedSwitchPreference; -import android.app.Notification; import android.app.NotificationManager; -import android.content.Context; -import android.content.Intent; -import android.content.pm.PackageInfo; -import android.content.pm.PackageManager; import android.os.Bundle; import android.os.UserHandle; import android.provider.Settings; -import android.service.notification.NotificationListenerService; import android.service.notification.NotificationListenerService.Ranking; -import android.support.v14.preference.SwitchPreference; -import android.support.v7.preference.Preference; -import android.support.v7.preference.Preference.OnPreferenceChangeListener; -import android.util.Log; -import android.widget.Toast; /** These settings are per topic, so should not be returned in global search results. */ public class TopicNotificationSettings extends NotificationSettingsBase { private static final String TAG = "TopicNotiSettings"; - - protected static final String ARG_TOPIC = "arg_topic"; - private TopicRow mTopicRow; private boolean mDndVisualEffectsSuppressed; @@ -72,25 +57,23 @@ public class TopicNotificationSettings extends NotificationSettingsBase { NotificationManager.from(mContext).getNotificationPolicy(); mDndVisualEffectsSuppressed = policy == null ? false : policy.suppressedVisualEffects != 0; - Bundle args = getArguments(); - final Notification.Topic topic = args != null && args.containsKey(ARG_TOPIC) - ? (Notification.Topic) args.getParcelable(ARG_TOPIC) : null; - if (topic == null) { + if (mTopic == null) { toastAndFinish(); return; } addPreferencesFromResource(R.xml.topic_notification_settings); - mTopicRow = mBackend.loadTopicRow(mPm, mPkgInfo, topic); + mTopicRow = mBackend.loadTopicRow(mPm, mPkgInfo, mTopic); mImportance = (ImportanceSeekBarPreference) findPreference(KEY_IMPORTANCE); - setupImportancePref(mTopicRow, mTopicRow.topic, mTopicRow.importance); - + mImportanceReset = (LayoutPreference) findPreference(KEY_IMPORTANCE_RESET); + mImportanceTitle = findPreference(KEY_IMPORTANCE_TITLE); mPriority = (RestrictedSwitchPreference) findPreference(KEY_BYPASS_DND); - setupPriorityPref(mTopicRow.topic, mTopicRow.priority); - mSensitive = (RestrictedSwitchPreference) findPreference(KEY_SENSITIVE); - setupSensitivePref(mTopicRow.topic, mTopicRow.sensitive); + + setupImportancePrefs(mTopicRow.systemApp, mTopicRow.importance); + setupPriorityPref(mTopicRow.priority); + setupSensitivePref(mTopicRow.sensitive); updateDependents(mTopicRow.importance); } @@ -102,13 +85,19 @@ public class TopicNotificationSettings extends NotificationSettingsBase { final boolean lockscreenNotificationsEnabled = getLockscreenNotificationsEnabled(); final boolean allowPrivate = getLockscreenAllowPrivateNotifications(); - - setVisible(mPriority, importance > NotificationListenerService.Ranking.IMPORTANCE_DEFAULT + setVisible(mPriority, checkCanBeVisible(Ranking.IMPORTANCE_DEFAULT, importance) && !mDndVisualEffectsSuppressed); - setVisible(mSensitive, (importance > NotificationListenerService.Ranking.IMPORTANCE_LOW) + setVisible(mSensitive, checkCanBeVisible(Ranking.IMPORTANCE_LOW, importance) && lockscreenSecure && lockscreenNotificationsEnabled && allowPrivate); } + protected boolean checkCanBeVisible(int minImportanceVisible, int importance) { + if (importance == Ranking.IMPORTANCE_UNSPECIFIED) { + return true; + } + return importance > minImportanceVisible; + } + private boolean getLockscreenNotificationsEnabled() { return Settings.Secure.getInt(getContentResolver(), Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS, 0) != 0;