diff --git a/res/values/strings.xml b/res/values/strings.xml index 6d8496573e5..457e07508ea 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -9211,6 +9211,16 @@ None All + + + {count, plural, offset:2 + =0 {No apps can interrupt} + =1 {{app_1} can interrupt} + =2 {{app_1} and {app_2} can interrupt} + =3 {{app_1}, {app_2}, and {app_3} can interrupt} + other {{app_1}, {app_2}, and # more can interrupt} + } + Allow apps to override diff --git a/src/com/android/settings/notification/modes/ZenModeSummaryHelper.java b/src/com/android/settings/notification/modes/ZenModeSummaryHelper.java index b4075cde656..77f364cd701 100644 --- a/src/com/android/settings/notification/modes/ZenModeSummaryHelper.java +++ b/src/com/android/settings/notification/modes/ZenModeSummaryHelper.java @@ -43,13 +43,18 @@ import android.icu.text.MessageFormat; import android.service.notification.ZenDeviceEffects; import android.service.notification.ZenPolicy; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + import com.android.settings.R; import java.util.ArrayList; +import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Locale; import java.util.Map; +import java.util.Set; import java.util.function.Predicate; class ZenModeSummaryHelper { @@ -397,12 +402,13 @@ class ZenModeSummaryHelper { } /** - * Generates a summary to display under the top level "Apps" preference for a mode. + * Generates a summary to display under the top level "Apps" preference for a mode, based + * on the given mode and provided set of apps. */ - public String getAppsSummary(ZenMode zenMode) { - // TODO: b/308819928 - Set summary using priority app list if Selected Apps Chosen. + public @NonNull String getAppsSummary(@NonNull ZenMode zenMode, + @Nullable Set appsBypassing) { if (zenMode.getPolicy().getAllowedChannels() == ZenPolicy.CHANNEL_POLICY_PRIORITY) { - return mContext.getResources().getString(R.string.zen_mode_apps_priority_apps); + return formatAppsList(appsBypassing); } else if (zenMode.getPolicy().getAllowedChannels() == ZenPolicy.CHANNEL_POLICY_NONE) { return mContext.getResources().getString(R.string.zen_mode_apps_none_apps); } else if (zenMode.getPolicy().getAllowedChannels() == ZenMode.CHANNEL_POLICY_ALL) { @@ -410,4 +416,35 @@ class ZenModeSummaryHelper { } return ""; } + + /** + * Generates a formatted string declaring which apps can interrupt in the style of + * "App, App2, and 4 more can interrupt." + * Apps selected for explicit mention are selected in order from the provided set sorted + * alphabetically. + */ + public @NonNull String formatAppsList(@Nullable Set appsBypassingDnd) { + if (appsBypassingDnd == null) { + return mContext.getResources().getString(R.string.zen_mode_apps_priority_apps); + } + final int numAppsBypassingDnd = appsBypassingDnd.size(); + String[] appsBypassingDndArr = appsBypassingDnd.toArray(new String[numAppsBypassingDnd]); + // Sorts the provided apps alphabetically. + Arrays.sort(appsBypassingDndArr); + MessageFormat msgFormat = new MessageFormat( + mContext.getString(R.string.zen_mode_apps_subtext), + Locale.getDefault()); + Map args = new HashMap<>(); + args.put("count", numAppsBypassingDnd); + if (numAppsBypassingDnd >= 1) { + args.put("app_1", appsBypassingDndArr[0]); + if (numAppsBypassingDnd >= 2) { + args.put("app_2", appsBypassingDndArr[1]); + if (numAppsBypassingDnd == 3) { + args.put("app_3", appsBypassingDndArr[2]); + } + } + } + return msgFormat.format(args); + } } diff --git a/tests/robotests/src/com/android/settings/notification/modes/ZenModesSummaryHelperTest.java b/tests/robotests/src/com/android/settings/notification/modes/ZenModesSummaryHelperTest.java index d8c8bf0bfb5..ef8290a4873 100644 --- a/tests/robotests/src/com/android/settings/notification/modes/ZenModesSummaryHelperTest.java +++ b/tests/robotests/src/com/android/settings/notification/modes/ZenModesSummaryHelperTest.java @@ -38,6 +38,9 @@ import org.mockito.MockitoAnnotations; import org.robolectric.RobolectricTestRunner; import org.robolectric.RuntimeEnvironment; +import java.util.LinkedHashSet; +import java.util.Set; + @RunWith(RobolectricTestRunner.class) public class ZenModesSummaryHelperTest { private Context mContext; @@ -339,7 +342,7 @@ public class ZenModesSummaryHelperTest { .build(); ZenMode zenMode = new ZenMode("id", rule, true); - assertThat(mSummaryHelper.getAppsSummary(zenMode)).isEqualTo("All"); + assertThat(mSummaryHelper.getAppsSummary(zenMode, new LinkedHashSet<>())).isEqualTo("All"); } @Test @@ -353,7 +356,56 @@ public class ZenModesSummaryHelperTest { .build(); ZenMode zenMode = new ZenMode("id", rule, true); - assertThat(mSummaryHelper.getAppsSummary(zenMode)).isEqualTo("None"); + assertThat(mSummaryHelper.getAppsSummary(zenMode, new LinkedHashSet<>())).isEqualTo("None"); + } + + @Test + public void getAppsSummary_priorityAppsNoList() { + AutomaticZenRule rule = new AutomaticZenRule.Builder("Bedtime", Uri.parse("bed")) + .setType(AutomaticZenRule.TYPE_BEDTIME) + .setInterruptionFilter(INTERRUPTION_FILTER_PRIORITY) + .setZenPolicy(new ZenPolicy.Builder() + .allowChannels(ZenPolicy.CHANNEL_POLICY_PRIORITY) + .build()) + .build(); + ZenMode zenMode = new ZenMode("id", rule, true); + + assertThat(mSummaryHelper.getAppsSummary(zenMode, null)).isEqualTo("Selected apps"); + } + + @Test + public void getAppsSummary_formatAppsListEmpty() { + Set apps = new LinkedHashSet<>(); + assertThat(mSummaryHelper.formatAppsList(apps)).isEqualTo("No apps can interrupt"); + } + + @Test + public void getAppsSummary_formatAppsListSingle() { + Set apps = Set.of("My App"); + assertThat(mSummaryHelper.formatAppsList(apps)).isEqualTo("My App can interrupt"); + } + + @Test + public void getAppsSummary_formatAppsListTwo() { + Set apps = Set.of("My App", "SecondApp"); + assertThat(mSummaryHelper.formatAppsList(apps)).isEqualTo("My App and SecondApp " + + "can interrupt"); + } + + @Test + public void getAppsSummary_formatAppsListThree() { + Set apps = Set.of("My App", "SecondApp", "ThirdApp"); + assertThat(mSummaryHelper.formatAppsList(apps)).isEqualTo("My App, SecondApp, " + + "and ThirdApp can interrupt"); + } + + @Test + public void getAppsSummary_formatAppsListMany() { + Set apps = Set.of("My App", "SecondApp", "ThirdApp", "FourthApp", + "FifthApp", "SixthApp"); + // Note that apps are selected alphabetically. + assertThat(mSummaryHelper.formatAppsList(apps)).isEqualTo("FifthApp, FourthApp, " + + "and 4 more can interrupt"); } @Test @@ -366,7 +418,11 @@ public class ZenModesSummaryHelperTest { .build()) .build(); ZenMode zenMode = new ZenMode("id", rule, true); + Set apps = Set.of("My App", "SecondApp", "ThirdApp", "FourthApp", + "FifthApp", "SixthApp"); - assertThat(mSummaryHelper.getAppsSummary(zenMode)).isEqualTo("Selected apps"); + assertThat(mSummaryHelper.getAppsSummary(zenMode, apps)).isEqualTo("FifthApp, FourthApp, " + + "and 4 more can interrupt"); } + }