From 5107a0b19088093990122dceb5b803f07dacf127 Mon Sep 17 00:00:00 2001 From: Alexander Roederer Date: Tue, 31 Oct 2023 16:22:47 +0000 Subject: [PATCH 1/2] aconfig flag for dnd app settings channels dedupe Aconfig flag to control adding the group name to the channel name in the DND App Settings page, to disambiguate channels that have identical names in the list. Test: adding flag; builds Bug: 294333850 Change-Id: Icac50932e75b011b25b507b38433620c09680f3c --- aconfig/Android.bp | 1 + aconfig/settings_notification_flag_declarations.aconfig | 9 +++++++++ 2 files changed, 10 insertions(+) create mode 100644 aconfig/settings_notification_flag_declarations.aconfig diff --git a/aconfig/Android.bp b/aconfig/Android.bp index 78fba34bd1c..6b7869ec921 100644 --- a/aconfig/Android.bp +++ b/aconfig/Android.bp @@ -10,6 +10,7 @@ aconfig_declarations { "settings_connecteddevice_flag_declarations.aconfig", "settings_globalintl_flag_declarations.aconfig", "settings_experience_flag_declarations.aconfig", + "settings_notification_flag_declarations.aconfig", "settings_onboarding_experience_flag_declarations.aconfig", "settings_telephony_flag_declarations.aconfig", "settings_biometrics_integration_declarations.aconfig", diff --git a/aconfig/settings_notification_flag_declarations.aconfig b/aconfig/settings_notification_flag_declarations.aconfig new file mode 100644 index 00000000000..f2bf1c87a1f --- /dev/null +++ b/aconfig/settings_notification_flag_declarations.aconfig @@ -0,0 +1,9 @@ +package: "com.android.settings.flags" + +flag { + name: "dedupe_dnd_settings_channels" + namespace: "systemui" + description: "Controls adding group names to channel names in the DND>Apps settings page" + bug: "294333850" +} + From d44bfaf86fef5bb04aa74464b18fcfc0ea076210 Mon Sep 17 00:00:00 2001 From: Alexander Roederer Date: Wed, 25 Oct 2023 20:39:35 +0000 Subject: [PATCH 2/2] Adds group to DND settings if channel names same Adds the channel group name as a summary to the DND channel Preference if two or more channels have identical names in the DND Menu. This allows users to disambiguate between the channels. Bug: 294333850 Test: Unit test updated, run with $make -j RunSettingsRoboTests ROBOTEST_FILTER=AppChannelsBypassingDndPreferenceControllerTest Change-Id: I4eaf48e5b2ea6513098fde79c3f81d18c6f4bb3d --- ...nnelsBypassingDndPreferenceController.java | 29 ++++++++++++ ...sBypassingDndPreferenceControllerTest.java | 46 +++++++++++++++++++ 2 files changed, 75 insertions(+) diff --git a/src/com/android/settings/notification/app/AppChannelsBypassingDndPreferenceController.java b/src/com/android/settings/notification/app/AppChannelsBypassingDndPreferenceController.java index 2830024ff03..200a47b54eb 100644 --- a/src/com/android/settings/notification/app/AppChannelsBypassingDndPreferenceController.java +++ b/src/com/android/settings/notification/app/AppChannelsBypassingDndPreferenceController.java @@ -39,13 +39,18 @@ import com.android.settings.R; import com.android.settings.applications.AppInfoBase; import com.android.settings.core.PreferenceControllerMixin; import com.android.settings.core.SubSettingLauncher; +import com.android.settings.flags.Flags; import com.android.settings.notification.NotificationBackend; import com.android.settingslib.PrimarySwitchPreference; import com.android.settingslib.RestrictedSwitchPreference; import java.util.ArrayList; import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; import java.util.List; +import java.util.Map; +import java.util.Set; /** * Populates the PreferenceCategory with notification channels associated with the given app. @@ -61,6 +66,9 @@ public class AppChannelsBypassingDndPreferenceController extends NotificationPre private RestrictedSwitchPreference mAllNotificationsToggle; private PreferenceCategory mPreferenceCategory; private List mChannels = new ArrayList<>(); + private Set mDuplicateChannelNames = new HashSet<>(); + private Map mChannelGroupNames = + new HashMap(); public AppChannelsBypassingDndPreferenceController( Context context, @@ -135,10 +143,20 @@ public class AppChannelsBypassingDndPreferenceController extends NotificationPre List newChannelList = new ArrayList<>(); List mChannelGroupList = mBackend.getGroups(mAppRow.pkg, mAppRow.uid).getList(); + Set allChannelNames = new HashSet<>(); for (NotificationChannelGroup channelGroup : mChannelGroupList) { for (NotificationChannel channel : channelGroup.getChannels()) { if (!isConversation(channel)) { newChannelList.add(channel); + if (Flags.dedupeDndSettingsChannels()) { + mChannelGroupNames.put(channel, channelGroup.getName().toString()); + // Check if channel name is unique on this page; if not, save it. + if (allChannelNames.contains(channel.getName())) { + mDuplicateChannelNames.add(channel.getName().toString()); + } else { + allChannelNames.add(channel.getName().toString()); + } + } } } } @@ -172,6 +190,17 @@ public class AppChannelsBypassingDndPreferenceController extends NotificationPre && isChannelConfigurable(channel) && showNotification(channel)); channelPreference.setTitle(BidiFormatter.getInstance().unicodeWrap(channel.getName())); + if (Flags.dedupeDndSettingsChannels()) { + // If the channel shares its name with another channel, set group name as summary + // to disambiguate in the list. + if (mDuplicateChannelNames.contains(channel.getName().toString()) + && mChannelGroupNames.containsKey(channel) + && mChannelGroupNames.get(channel) != null + && !mChannelGroupNames.get(channel).isEmpty()) { + channelPreference.setSummary(BidiFormatter.getInstance().unicodeWrap( + mChannelGroupNames.get(channel))); + } + } channelPreference.setChecked(showNotificationInDnd(channel)); channelPreference.setOnPreferenceChangeListener( new Preference.OnPreferenceChangeListener() { diff --git a/tests/robotests/src/com/android/settings/notification/app/AppChannelsBypassingDndPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/app/AppChannelsBypassingDndPreferenceControllerTest.java index 13528b4f9f6..053b3520cbe 100644 --- a/tests/robotests/src/com/android/settings/notification/app/AppChannelsBypassingDndPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/notification/app/AppChannelsBypassingDndPreferenceControllerTest.java @@ -26,16 +26,19 @@ import android.app.NotificationChannelGroup; import android.app.NotificationManager; import android.content.Context; import android.content.pm.ParceledListSlice; +import android.platform.test.flag.junit.SetFlagsRule; import androidx.preference.PreferenceCategory; import androidx.preference.PreferenceManager; import androidx.preference.PreferenceScreen; import androidx.test.core.app.ApplicationProvider; +import com.android.settings.flags.Flags; import com.android.settings.notification.NotificationBackend; import com.android.settingslib.PrimarySwitchPreference; import org.junit.Before; +import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; @@ -51,6 +54,9 @@ import java.util.Collections; @LooperMode(LooperMode.Mode.LEGACY) public class AppChannelsBypassingDndPreferenceControllerTest { + @Rule + public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(); + @Mock private NotificationBackend mBackend; @@ -150,4 +156,44 @@ public class AppChannelsBypassingDndPreferenceControllerTest { } return new ParceledListSlice<>(Collections.singletonList(group)); } + + @Test + public void displayPreference_duplicateChannelName_AddsGroupNameAsSummary() { + mSetFlagsRule.enableFlags(Flags.FLAG_DEDUPE_DND_SETTINGS_CHANNELS); + NotificationChannelGroup group1 = new NotificationChannelGroup("group1_id", "Group1"); + NotificationChannelGroup group2 = new NotificationChannelGroup("group2_id", "Group2"); + + group1.addChannel(new NotificationChannel("mail_group1_id", "Mail", + NotificationManager.IMPORTANCE_DEFAULT)); + group1.addChannel(new NotificationChannel("other_group1_id", "Other", + NotificationManager.IMPORTANCE_DEFAULT)); + + group2.addChannel(new NotificationChannel("music_group2_id", "Music", + NotificationManager.IMPORTANCE_DEFAULT)); + // This channel has the same name as a channel in group1. + group2.addChannel(new NotificationChannel("mail_group2_id", "Mail", + NotificationManager.IMPORTANCE_DEFAULT)); + + ParceledListSlice groups = new ParceledListSlice<>( + new ArrayList() { + { + add(group1); + add(group2); + } + } + ); + + when(mBackend.getGroups(eq(mAppRow.pkg), eq(mAppRow.uid))).thenReturn(groups); + mController.displayPreference(mPreferenceScreen); + ShadowApplication.runBackgroundTasks(); + // Check that we've added the group name as a summary to channels that have identical names. + // Channels are also alphabetized. + assertThat(mCategory.getPreference(1).getTitle().toString()).isEqualTo("Mail"); + assertThat(mCategory.getPreference(1).getSummary().toString()).isEqualTo("Group1"); + assertThat(mCategory.getPreference(2).getTitle().toString()).isEqualTo("Mail"); + assertThat(mCategory.getPreference(2).getSummary().toString()).isEqualTo("Group2"); + assertThat(mCategory.getPreference(3).getTitle().toString()).isEqualTo("Music"); + assertThat(mCategory.getPreference(4).getTitle().toString()).isEqualTo("Other"); + + } }