Notification settings updates

- Text changes
- Show channels on the app settings screen (again)
- Hide most of the channel settings under 'advanced' (note: this hides
  the footer preference(s) also, at the moment. the functionality
  to exclude those is coming in a later cl)
  - Add a 'show notifications' toggle for each app created group

Bug: 63927402
Test: make RunSettingsRoboTests

Change-Id: I9906ef943d05e1915061b59294a25d81c4e6cbb5
This commit is contained in:
Julia Reynolds
2017-12-21 13:28:20 -05:00
parent 9c3d329de6
commit 3527ef7c29
8 changed files with 80 additions and 87 deletions

View File

@@ -6926,7 +6926,7 @@
<string name="notification_group_title">Notification category group</string> <string name="notification_group_title">Notification category group</string>
<!-- [CHAR LIMIT=100] Notification importance screen title --> <!-- [CHAR LIMIT=100] Notification importance screen title -->
<string name="notification_importance_title">Importance</string> <string name="notification_importance_title">Behavior</string>
<!-- [CHAR LIMIT=100 BACKUP_MESSAGE_ID=1820188704793497324] Notification Importance: unspecified importance level description --> <!-- [CHAR LIMIT=100 BACKUP_MESSAGE_ID=1820188704793497324] Notification Importance: unspecified importance level description -->
<string name="notification_importance_unspecified">Allow sound</string> <string name="notification_importance_unspecified">Allow sound</string>
@@ -6991,6 +6991,9 @@
<!-- [CHAR LIMIT=100] Notification Importance title: high importance level title --> <!-- [CHAR LIMIT=100] Notification Importance title: high importance level title -->
<string name="notification_channel_summary_high">Urgent importance</string> <string name="notification_channel_summary_high">Urgent importance</string>
<!-- [CHAR LIMIT=100] Label for on/off toggle -->
<string name="notification_switch_label">Show notifications</string>
<!-- Default Apps > Default notification assistant --> <!-- Default Apps > Default notification assistant -->
<string name="default_notification_assistant">Notification assistant</string> <string name="default_notification_assistant">Notification assistant</string>
@@ -7087,13 +7090,13 @@
<string name="loading_notification_apps">Loading apps...</string> <string name="loading_notification_apps">Loading apps...</string>
<!-- [CHAR LIMIT=NONE] Text appearing when app notifications are off --> <!-- [CHAR LIMIT=NONE] Text appearing when app notifications are off -->
<string name="app_notifications_off_desc">Android is blocking this app\'s notifications from appearing on this device</string> <string name="app_notifications_off_desc">At your request, Android is blocking this app\'s notifications from appearing on this device</string>
<!-- [CHAR LIMIT=NONE] Text appearing when channel notifications are off --> <!-- [CHAR LIMIT=NONE] Text appearing when channel notifications are off -->
<string name="channel_notifications_off_desc">Android is blocking this category of notifications from appearing on this device</string> <string name="channel_notifications_off_desc">At your request, Android is blocking this category of notifications from appearing on this device</string>
<!-- [CHAR LIMIT=NONE] Text appearing when channel group notifications are off --> <!-- [CHAR LIMIT=NONE] Text appearing when channel group notifications are off -->
<string name="channel_group_notifications_off_desc">Android is blocking this group of notifications from appearing on this device</string> <string name="channel_group_notifications_off_desc">At your request, Android is blocking this group of notifications from appearing on this device</string>
<!-- [CHAR LIMIT=NONE] App notification settings: channels title --> <!-- [CHAR LIMIT=NONE] App notification settings: channels title -->
<string name="notification_channels">Categories</string> <string name="notification_channels">Categories</string>

View File

@@ -15,7 +15,8 @@
--> -->
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:settings="http://schemas.android.com/apk/res-auto" > xmlns:settings="http://schemas.android.com/apk/res-auto"
settings:initialExpandedChildrenCount="3">
<com.android.settings.applications.LayoutPreference <com.android.settings.applications.LayoutPreference
android:key="pref_app_header" android:key="pref_app_header"

View File

@@ -19,20 +19,15 @@
<com.android.settings.widget.RadioButtonPreference <com.android.settings.widget.RadioButtonPreference
android:key="importance_high" android:key="importance_high"
android:title="@string/notification_importance_high_title" android:title="@string/notification_importance_high" />
android:summary="@string/notification_importance_high"
/>
<com.android.settings.widget.RadioButtonPreference <com.android.settings.widget.RadioButtonPreference
android:key="importance_default" android:key="importance_default"
android:title="@string/notification_importance_default_title" android:title="@string/notification_importance_default" />
android:summary="@string/notification_importance_default" />
<com.android.settings.widget.RadioButtonPreference <com.android.settings.widget.RadioButtonPreference
android:key="importance_low" android:key="importance_low"
android:title="@string/notification_importance_low_title" android:title="@string/notification_importance_low" />
android:summary="@string/notification_importance_low" />
<com.android.settings.widget.RadioButtonPreference <com.android.settings.widget.RadioButtonPreference
android:key="importance_min" android:key="importance_min"
android:title="@string/notification_importance_min_title" android:title="@string/notification_importance_min" />
android:summary="@string/notification_importance_min" />
</PreferenceScreen> </PreferenceScreen>

View File

@@ -135,7 +135,6 @@ public class AppNotificationSettings extends NotificationSettingsBase {
return new ArrayList<>(mControllers); return new ArrayList<>(mControllers);
} }
private void populateList() { private void populateList() {
if (!mDynamicPreferences.isEmpty()) { if (!mDynamicPreferences.isEmpty()) {
// If there's anything in mChannelGroups, we've called populateChannelList twice. // If there's anything in mChannelGroups, we've called populateChannelList twice.
@@ -164,61 +163,41 @@ public class AppNotificationSettings extends NotificationSettingsBase {
} }
private void populateGroupList() { private void populateGroupList() {
PreferenceCategory groupCategory = new PreferenceCategory(getPrefContext());
groupCategory.setTitle(R.string.notification_channels);
groupCategory.setKey(KEY_GENERAL_CATEGORY);
groupCategory.setOrderingAsAdded(true);
getPreferenceScreen().addPreference(groupCategory);
mDynamicPreferences.add(groupCategory);
for (NotificationChannelGroup group : mChannelGroupList) { for (NotificationChannelGroup group : mChannelGroupList) {
final List<NotificationChannel> channels = group.getChannels(); PreferenceCategory groupCategory = new PreferenceCategory(getPrefContext());
int N = channels.size(); groupCategory.setOrderingAsAdded(true);
// app defined groups with one channel and channels with no group display the channel getPreferenceScreen().addPreference(groupCategory);
// name and no summary and link directly to the channel page unless the group is blocked mDynamicPreferences.add(groupCategory);
if ((group.getId() == null || N < 2) && !group.isBlocked()) { if (group.getId() == null) {
Collections.sort(channels, mChannelComparator); groupCategory.setTitle(mChannelGroupList.size() > 1
for (int i = 0; i < N; i++) { ? R.string.notification_channels_other
final NotificationChannel channel = channels.get(i); : R.string.notification_channels);
populateSingleChannelPrefs(groupCategory, channel, ""); groupCategory.setKey(KEY_GENERAL_CATEGORY);
}
} else { } else {
populateGroupPreference(groupCategory, group, N); groupCategory.setTitle(group.getName());
groupCategory.setKey(group.getId());
Bundle groupArgs = new Bundle();
groupArgs.putInt(AppInfoBase.ARG_PACKAGE_UID, mUid);
groupArgs.putString(AppInfoBase.ARG_PACKAGE_NAME, mPkg);
groupArgs.putString(Settings.EXTRA_CHANNEL_GROUP_ID, group.getId());
Intent channelIntent = Utils.onBuildStartFragmentIntent(getActivity(),
ChannelGroupNotificationSettings.class.getName(),
groupArgs, null, R.string.notification_group_title,
null, false, getMetricsCategory());
groupCategory.setIntent(channelIntent);
populateGroupToggle(groupCategory, group);
}
final List<NotificationChannel> channels = group.getChannels();
Collections.sort(channels, mChannelComparator);
int N = channels.size();
for (int i = 0; i < N; i++) {
final NotificationChannel channel = channels.get(i);
populateSingleChannelPrefs(groupCategory, channel, group.isBlocked());
} }
} }
} }
void populateGroupPreference(PreferenceGroup parent,
final NotificationChannelGroup group, int channelCount) {
MasterSwitchPreference groupPref = new MasterSwitchPreference(
getPrefContext());
groupPref.setSwitchEnabled(mSuspendedAppsAdmin == null
&& isChannelGroupBlockable(group));
groupPref.setKey(group.getId());
groupPref.setTitle(group.getName());
groupPref.setChecked(!group.isBlocked());
groupPref.setSummary(getResources().getQuantityString(
R.plurals.notification_group_summary, channelCount, channelCount));
Bundle groupArgs = new Bundle();
groupArgs.putInt(AppInfoBase.ARG_PACKAGE_UID, mUid);
groupArgs.putString(AppInfoBase.ARG_PACKAGE_NAME, mPkg);
groupArgs.putString(Settings.EXTRA_CHANNEL_GROUP_ID, group.getId());
Intent groupIntent = Utils.onBuildStartFragmentIntent(getActivity(),
ChannelGroupNotificationSettings.class.getName(),
groupArgs, null, R.string.notification_group_title, null, false,
getMetricsCategory());
groupPref.setIntent(groupIntent);
groupPref.setOnPreferenceChangeListener(
(preference, o) -> {
boolean value = (Boolean) o;
group.setBlocked(!value);
mBackend.updateChannelGroup(mPkg, mUid, group);
return true;
});
parent.addPreference(groupPref);
}
private Comparator<NotificationChannelGroup> mChannelGroupComparator = private Comparator<NotificationChannelGroup> mChannelGroupComparator =
new Comparator<NotificationChannelGroup>() { new Comparator<NotificationChannelGroup>() {

View File

@@ -67,6 +67,8 @@ public class BlockPreferenceController extends NotificationPreferenceController
LayoutPreference pref = (LayoutPreference) preference; LayoutPreference pref = (LayoutPreference) preference;
SwitchBar bar = pref.findViewById(R.id.switch_bar); SwitchBar bar = pref.findViewById(R.id.switch_bar);
if (bar != null) { if (bar != null) {
bar.setSwitchBarText(R.string.notification_switch_label,
R.string.notification_switch_label);
bar.show(); bar.show();
try { try {
bar.addOnSwitchChangeListener(this); bar.addOnSwitchChangeListener(this);

View File

@@ -19,7 +19,6 @@ package com.android.settings.notification;
import android.app.NotificationChannel; import android.app.NotificationChannel;
import android.content.Context; import android.content.Context;
import android.support.v7.preference.Preference; import android.support.v7.preference.Preference;
import android.text.TextUtils;
import android.util.Log; import android.util.Log;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
@@ -98,9 +97,7 @@ public class ChannelGroupNotificationSettings extends NotificationSettingsBase {
Collections.sort(channels, mChannelComparator); Collections.sort(channels, mChannelComparator);
for (NotificationChannel channel : channels) { for (NotificationChannel channel : channels) {
mDynamicPreferences.add(populateSingleChannelPrefs( mDynamicPreferences.add(populateSingleChannelPrefs(
getPreferenceScreen(), channel, getPreferenceScreen(), channel, mChannelGroup.isBlocked()));
ImportancePreferenceController.getImportanceSummary(
getPrefContext(), channel)));
} }
} }

View File

@@ -73,7 +73,8 @@ public class ImportancePreferenceController extends NotificationPreferenceContro
if (preference.isEnabled()) { if (preference.isEnabled()) {
Intent channelIntent = Utils.onBuildStartFragmentIntent(mContext, Intent channelIntent = Utils.onBuildStartFragmentIntent(mContext,
ChannelImportanceSettings.class.getName(), ChannelImportanceSettings.class.getName(),
channelArgs, null, R.string.notification_importance_title, null, channelArgs, null,
R.string.notification_importance_title, null,
false, getMetricsCategory()); false, getMetricsCategory());
preference.setIntent(channelIntent); preference.setIntent(channelIntent);
preference.setSummary(getImportanceSummary(mContext, mChannel)); preference.setSummary(getImportanceSummary(mContext, mChannel));
@@ -82,23 +83,19 @@ public class ImportancePreferenceController extends NotificationPreferenceContro
} }
protected static String getImportanceSummary(Context context, NotificationChannel channel) { protected static String getImportanceSummary(Context context, NotificationChannel channel) {
String title; String summary = "";
String summary = null;
int importance = channel.getImportance(); int importance = channel.getImportance();
switch (importance) { switch (importance) {
case IMPORTANCE_UNSPECIFIED: case IMPORTANCE_UNSPECIFIED:
title = context.getString(R.string.notification_importance_unspecified); summary = context.getString(R.string.notification_importance_unspecified);
break; break;
case NotificationManager.IMPORTANCE_MIN: case NotificationManager.IMPORTANCE_MIN:
title = context.getString(R.string.notification_importance_min_title);
summary = context.getString(R.string.notification_importance_min); summary = context.getString(R.string.notification_importance_min);
break; break;
case NotificationManager.IMPORTANCE_LOW: case NotificationManager.IMPORTANCE_LOW:
title = context.getString(R.string.notification_importance_low_title);
summary = context.getString(R.string.notification_importance_low); summary = context.getString(R.string.notification_importance_low);
break; break;
case NotificationManager.IMPORTANCE_DEFAULT: case NotificationManager.IMPORTANCE_DEFAULT:
title = context.getString(R.string.notification_importance_default_title);
if (SoundPreferenceController.hasValidSound(channel)) { if (SoundPreferenceController.hasValidSound(channel)) {
summary = context.getString(R.string.notification_importance_default); summary = context.getString(R.string.notification_importance_default);
} else { } else {
@@ -107,7 +104,6 @@ public class ImportancePreferenceController extends NotificationPreferenceContro
break; break;
case NotificationManager.IMPORTANCE_HIGH: case NotificationManager.IMPORTANCE_HIGH:
case NotificationManager.IMPORTANCE_MAX: case NotificationManager.IMPORTANCE_MAX:
title = context.getString(R.string.notification_importance_high_title);
if (SoundPreferenceController.hasValidSound(channel)) { if (SoundPreferenceController.hasValidSound(channel)) {
summary = context.getString(R.string.notification_importance_high); summary = context.getString(R.string.notification_importance_high);
} else { } else {
@@ -118,10 +114,6 @@ public class ImportancePreferenceController extends NotificationPreferenceContro
return ""; return "";
} }
if (summary != null) { return summary;
return context.getString(R.string.notification_importance_divider, title, summary);
} else {
return title;
}
} }
} }

View File

@@ -61,6 +61,7 @@ import android.os.UserManager;
import android.provider.SearchIndexableResource; import android.provider.SearchIndexableResource;
import android.provider.Settings; import android.provider.Settings;
import android.service.notification.NotificationListenerService; import android.service.notification.NotificationListenerService;
import android.support.v14.preference.SwitchPreference;
import android.support.v7.preference.Preference; import android.support.v7.preference.Preference;
import android.support.v7.preference.PreferenceGroup; import android.support.v7.preference.PreferenceGroup;
import android.support.v7.preference.PreferenceScreen; import android.support.v7.preference.PreferenceScreen;
@@ -214,7 +215,6 @@ abstract public class NotificationSettingsBase extends DashboardFragment {
} }
for (ResolveInfo ri : resolveInfos) { for (ResolveInfo ri : resolveInfos) {
final ActivityInfo activityInfo = ri.activityInfo; final ActivityInfo activityInfo = ri.activityInfo;
final ApplicationInfo appInfo = activityInfo.applicationInfo;
if (mAppRow.settingsIntent != null) { if (mAppRow.settingsIntent != null) {
if (DEBUG) { if (DEBUG) {
Log.d(TAG, "Ignoring duplicate notification preference activity (" Log.d(TAG, "Ignoring duplicate notification preference activity ("
@@ -225,7 +225,8 @@ abstract public class NotificationSettingsBase extends DashboardFragment {
} }
mAppRow.settingsIntent = intent mAppRow.settingsIntent = intent
.setPackage(null) .setPackage(null)
.setClassName(activityInfo.packageName, activityInfo.name); .setClassName(activityInfo.packageName, activityInfo.name)
.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
if (mChannel != null) { if (mChannel != null) {
mAppRow.settingsIntent.putExtra(Notification.EXTRA_CHANNEL_ID, mChannel.getId()); mAppRow.settingsIntent.putExtra(Notification.EXTRA_CHANNEL_ID, mChannel.getId());
} }
@@ -257,17 +258,41 @@ abstract public class NotificationSettingsBase extends DashboardFragment {
return null; return null;
} }
protected void populateGroupToggle(final PreferenceGroup parent,
NotificationChannelGroup group) {
RestrictedSwitchPreference preference = new RestrictedSwitchPreference(getPrefContext());
preference.setTitle(R.string.notification_switch_label);
preference.setEnabled(mSuspendedAppsAdmin == null
&& isChannelGroupBlockable(group));
preference.setChecked(!group.isBlocked());
preference.setOnPreferenceClickListener(preference1 -> {
final boolean allowGroup = ((SwitchPreference) preference1).isChecked();
group.setBlocked(!allowGroup);
mBackend.updateChannelGroup(mAppRow.pkg, mAppRow.uid, group);
for (int i = 0; i < parent.getPreferenceCount(); i++) {
Preference pref = parent.getPreference(i);
if (pref instanceof MasterSwitchPreference) {
((MasterSwitchPreference) pref).setSwitchEnabled(allowGroup);
}
}
return true;
});
parent.addPreference(preference);
}
protected Preference populateSingleChannelPrefs(PreferenceGroup parent, protected Preference populateSingleChannelPrefs(PreferenceGroup parent,
final NotificationChannel channel, String summary) { final NotificationChannel channel, final boolean groupBlocked) {
MasterSwitchPreference channelPref = new MasterSwitchPreference( MasterSwitchPreference channelPref = new MasterSwitchPreference(
getPrefContext()); getPrefContext());
channelPref.setSwitchEnabled(mSuspendedAppsAdmin == null channelPref.setSwitchEnabled(mSuspendedAppsAdmin == null
&& isChannelBlockable(channel) && isChannelBlockable(channel)
&& isChannelConfigurable(channel)); && isChannelConfigurable(channel)
&& !groupBlocked);
channelPref.setKey(channel.getId()); channelPref.setKey(channel.getId());
channelPref.setTitle(channel.getName()); channelPref.setTitle(channel.getName());
channelPref.setChecked(channel.getImportance() != IMPORTANCE_NONE); channelPref.setChecked(channel.getImportance() != IMPORTANCE_NONE);
channelPref.setSummary(summary);
Bundle channelArgs = new Bundle(); Bundle channelArgs = new Bundle();
channelArgs.putInt(AppInfoBase.ARG_PACKAGE_UID, mUid); channelArgs.putInt(AppInfoBase.ARG_PACKAGE_UID, mUid);
channelArgs.putString(AppInfoBase.ARG_PACKAGE_NAME, mPkg); channelArgs.putString(AppInfoBase.ARG_PACKAGE_NAME, mPkg);
@@ -288,7 +313,6 @@ abstract public class NotificationSettingsBase extends DashboardFragment {
channel.setImportance(importance); channel.setImportance(importance);
channel.lockFields( channel.lockFields(
NotificationChannel.USER_LOCKED_IMPORTANCE); NotificationChannel.USER_LOCKED_IMPORTANCE);
channelPref.setSummary(summary);
mBackend.updateChannel(mPkg, mUid, channel); mBackend.updateChannel(mPkg, mUid, channel);
return true; return true;