Loading core/java/android/provider/Settings.java +20 −0 Original line number Diff line number Diff line Loading @@ -10839,6 +10839,26 @@ public final class Settings { */ public static final String ENABLE_DELETION_HELPER_NO_THRESHOLD_TOGGLE = "enable_deletion_helper_no_threshold_toggle"; /** * The list of snooze options for notifications * This is encoded as a key=value list, separated by commas. Ex: * * "default=60,options_array=15:30:60:120" * * The following keys are supported: * * <pre> * default (int) * options_array (string) * </pre> * * All delays in integer minutes. Array order is respected. * Options will be used in order up to the maximum allowed by the UI. * @hide */ public static final String NOTIFICATION_SNOOZE_OPTIONS = "notification_snooze_options"; } /** Loading core/tests/coretests/src/android/provider/SettingsBackupTest.java +1 −0 Original line number Diff line number Diff line Loading @@ -277,6 +277,7 @@ public class SettingsBackupTest { Settings.Global.NEW_CONTACT_AGGREGATOR, Settings.Global.NITZ_UPDATE_DIFF, Settings.Global.NITZ_UPDATE_SPACING, Settings.Global.NOTIFICATION_SNOOZE_OPTIONS, Settings.Global.NSD_ON, Settings.Global.NTP_SERVER, Settings.Global.NTP_TIMEOUT, Loading packages/SystemUI/res/values/config.xml +10 −0 Original line number Diff line number Diff line Loading @@ -422,4 +422,14 @@ increase the rate of unintentional unlocks. --> <bool name="config_lockscreenAntiFalsingClassifierEnabled">true</bool> <!-- Snooze: default notificaiton snooze time. --> <integer name="config_notification_snooze_time_default">60</integer> <!-- Snooze: List of snooze values in integer minutes. --> <integer-array name="config_notification_snooze_times"> <item>15</item> <item>30</item> <item>60</item> <item>120</item> </integer-array> </resources> packages/SystemUI/res/values/ids.xml +4 −4 Original line number Diff line number Diff line Loading @@ -82,10 +82,10 @@ <!-- Accessibility actions for the notification menu --> <item type="id" name="action_snooze_undo"/> <item type="id" name="action_snooze_15_min"/> <item type="id" name="action_snooze_30_min"/> <item type="id" name="action_snooze_1_hour"/> <item type="id" name="action_snooze_2_hours"/> <item type="id" name="action_snooze_shorter"/> <item type="id" name="action_snooze_short"/> <item type="id" name="action_snooze_long"/> <item type="id" name="action_snooze_longer"/> <item type="id" name="action_snooze_assistant_suggestion_1"/> </resources> packages/SystemUI/src/com/android/systemui/statusbar/NotificationSnooze.java +65 −6 Original line number Diff line number Diff line Loading @@ -16,8 +16,10 @@ package com.android.systemui.statusbar; */ import java.util.ArrayList; import java.util.Arrays; import java.util.List; import com.android.internal.annotations.VisibleForTesting; import com.android.systemui.plugins.statusbar.NotificationSwipeActionHelper; import com.android.systemui.plugins.statusbar.NotificationSwipeActionHelper.SnoozeOption; Loading @@ -29,11 +31,13 @@ import android.content.Context; import android.content.res.Resources; import android.graphics.Typeface; import android.os.Bundle; import android.provider.Settings; import android.service.notification.SnoozeCriterion; import android.service.notification.StatusBarNotification; import android.text.SpannableString; import android.text.style.StyleSpan; import android.util.AttributeSet; import android.util.KeyValueListParser; import android.util.Log; import android.view.LayoutInflater; import android.view.View; Loading @@ -51,11 +55,14 @@ import com.android.systemui.R; public class NotificationSnooze extends LinearLayout implements NotificationGuts.GutsContent, View.OnClickListener { private static final String TAG = "NotificationSnooze"; /** * If this changes more number increases, more assistant action resId's should be defined for * accessibility purposes, see {@link #setSnoozeOptions(List)} */ private static final int MAX_ASSISTANT_SUGGESTIONS = 1; private static final String KEY_DEFAULT_SNOOZE = "default"; private static final String KEY_OPTIONS = "options_array"; private NotificationGuts mGutsContainer; private NotificationSwipeActionHelper mSnoozeListener; private StatusBarNotification mSbn; Loading @@ -72,9 +79,29 @@ public class NotificationSnooze extends LinearLayout private boolean mSnoozing; private boolean mExpanded; private AnimatorSet mExpandAnimation; private KeyValueListParser mParser; private final static int[] sAccessibilityActions = { R.id.action_snooze_shorter, R.id.action_snooze_short, R.id.action_snooze_long, R.id.action_snooze_longer, }; public NotificationSnooze(Context context, AttributeSet attrs) { super(context, attrs); mParser = new KeyValueListParser(','); } @VisibleForTesting SnoozeOption getDefaultOption() { return mDefaultOption; } @VisibleForTesting void setKeyValueListParser(KeyValueListParser parser) { mParser = parser; } @Override Loading Loading @@ -172,17 +199,49 @@ public class NotificationSnooze extends LinearLayout mSbn = sbn; } private ArrayList<SnoozeOption> getDefaultSnoozeOptions() { @VisibleForTesting ArrayList<SnoozeOption> getDefaultSnoozeOptions() { final Resources resources = getContext().getResources(); ArrayList<SnoozeOption> options = new ArrayList<>(); try { final String config = Settings.Global.getString(getContext().getContentResolver(), Settings.Global.NOTIFICATION_SNOOZE_OPTIONS); mParser.setString(config); } catch (IllegalArgumentException e) { Log.e(TAG, "Bad snooze constants"); } final int defaultSnooze = mParser.getInt(KEY_DEFAULT_SNOOZE, resources.getInteger(R.integer.config_notification_snooze_time_default)); final int[] snoozeTimes = parseIntArray(KEY_OPTIONS, resources.getIntArray(R.array.config_notification_snooze_times)); options.add(createOption(15 /* minutes */, R.id.action_snooze_15_min)); options.add(createOption(30 /* minutes */, R.id.action_snooze_30_min)); mDefaultOption = createOption(60 /* minutes */, R.id.action_snooze_1_hour); options.add(mDefaultOption); options.add(createOption(60 * 2 /* minutes */, R.id.action_snooze_2_hours)); for (int i = 0; i < snoozeTimes.length && i < sAccessibilityActions.length; i++) { int snoozeTime = snoozeTimes[i]; SnoozeOption option = createOption(snoozeTime, sAccessibilityActions[i]); if (i == 0 || snoozeTime == defaultSnooze) { mDefaultOption = option; } options.add(option); } return options; } @VisibleForTesting int[] parseIntArray(final String key, final int[] defaultArray) { final String value = mParser.getString(key, null); if (value != null) { try { return Arrays.stream(value.split(":")).map(String::trim).mapToInt( Integer::parseInt).toArray(); } catch (NumberFormatException e) { return defaultArray; } } else { return defaultArray; } } private SnoozeOption createOption(int minutes, int accessibilityActionId) { Resources res = getResources(); boolean showInHours = minutes >= 60; Loading Loading
core/java/android/provider/Settings.java +20 −0 Original line number Diff line number Diff line Loading @@ -10839,6 +10839,26 @@ public final class Settings { */ public static final String ENABLE_DELETION_HELPER_NO_THRESHOLD_TOGGLE = "enable_deletion_helper_no_threshold_toggle"; /** * The list of snooze options for notifications * This is encoded as a key=value list, separated by commas. Ex: * * "default=60,options_array=15:30:60:120" * * The following keys are supported: * * <pre> * default (int) * options_array (string) * </pre> * * All delays in integer minutes. Array order is respected. * Options will be used in order up to the maximum allowed by the UI. * @hide */ public static final String NOTIFICATION_SNOOZE_OPTIONS = "notification_snooze_options"; } /** Loading
core/tests/coretests/src/android/provider/SettingsBackupTest.java +1 −0 Original line number Diff line number Diff line Loading @@ -277,6 +277,7 @@ public class SettingsBackupTest { Settings.Global.NEW_CONTACT_AGGREGATOR, Settings.Global.NITZ_UPDATE_DIFF, Settings.Global.NITZ_UPDATE_SPACING, Settings.Global.NOTIFICATION_SNOOZE_OPTIONS, Settings.Global.NSD_ON, Settings.Global.NTP_SERVER, Settings.Global.NTP_TIMEOUT, Loading
packages/SystemUI/res/values/config.xml +10 −0 Original line number Diff line number Diff line Loading @@ -422,4 +422,14 @@ increase the rate of unintentional unlocks. --> <bool name="config_lockscreenAntiFalsingClassifierEnabled">true</bool> <!-- Snooze: default notificaiton snooze time. --> <integer name="config_notification_snooze_time_default">60</integer> <!-- Snooze: List of snooze values in integer minutes. --> <integer-array name="config_notification_snooze_times"> <item>15</item> <item>30</item> <item>60</item> <item>120</item> </integer-array> </resources>
packages/SystemUI/res/values/ids.xml +4 −4 Original line number Diff line number Diff line Loading @@ -82,10 +82,10 @@ <!-- Accessibility actions for the notification menu --> <item type="id" name="action_snooze_undo"/> <item type="id" name="action_snooze_15_min"/> <item type="id" name="action_snooze_30_min"/> <item type="id" name="action_snooze_1_hour"/> <item type="id" name="action_snooze_2_hours"/> <item type="id" name="action_snooze_shorter"/> <item type="id" name="action_snooze_short"/> <item type="id" name="action_snooze_long"/> <item type="id" name="action_snooze_longer"/> <item type="id" name="action_snooze_assistant_suggestion_1"/> </resources>
packages/SystemUI/src/com/android/systemui/statusbar/NotificationSnooze.java +65 −6 Original line number Diff line number Diff line Loading @@ -16,8 +16,10 @@ package com.android.systemui.statusbar; */ import java.util.ArrayList; import java.util.Arrays; import java.util.List; import com.android.internal.annotations.VisibleForTesting; import com.android.systemui.plugins.statusbar.NotificationSwipeActionHelper; import com.android.systemui.plugins.statusbar.NotificationSwipeActionHelper.SnoozeOption; Loading @@ -29,11 +31,13 @@ import android.content.Context; import android.content.res.Resources; import android.graphics.Typeface; import android.os.Bundle; import android.provider.Settings; import android.service.notification.SnoozeCriterion; import android.service.notification.StatusBarNotification; import android.text.SpannableString; import android.text.style.StyleSpan; import android.util.AttributeSet; import android.util.KeyValueListParser; import android.util.Log; import android.view.LayoutInflater; import android.view.View; Loading @@ -51,11 +55,14 @@ import com.android.systemui.R; public class NotificationSnooze extends LinearLayout implements NotificationGuts.GutsContent, View.OnClickListener { private static final String TAG = "NotificationSnooze"; /** * If this changes more number increases, more assistant action resId's should be defined for * accessibility purposes, see {@link #setSnoozeOptions(List)} */ private static final int MAX_ASSISTANT_SUGGESTIONS = 1; private static final String KEY_DEFAULT_SNOOZE = "default"; private static final String KEY_OPTIONS = "options_array"; private NotificationGuts mGutsContainer; private NotificationSwipeActionHelper mSnoozeListener; private StatusBarNotification mSbn; Loading @@ -72,9 +79,29 @@ public class NotificationSnooze extends LinearLayout private boolean mSnoozing; private boolean mExpanded; private AnimatorSet mExpandAnimation; private KeyValueListParser mParser; private final static int[] sAccessibilityActions = { R.id.action_snooze_shorter, R.id.action_snooze_short, R.id.action_snooze_long, R.id.action_snooze_longer, }; public NotificationSnooze(Context context, AttributeSet attrs) { super(context, attrs); mParser = new KeyValueListParser(','); } @VisibleForTesting SnoozeOption getDefaultOption() { return mDefaultOption; } @VisibleForTesting void setKeyValueListParser(KeyValueListParser parser) { mParser = parser; } @Override Loading Loading @@ -172,17 +199,49 @@ public class NotificationSnooze extends LinearLayout mSbn = sbn; } private ArrayList<SnoozeOption> getDefaultSnoozeOptions() { @VisibleForTesting ArrayList<SnoozeOption> getDefaultSnoozeOptions() { final Resources resources = getContext().getResources(); ArrayList<SnoozeOption> options = new ArrayList<>(); try { final String config = Settings.Global.getString(getContext().getContentResolver(), Settings.Global.NOTIFICATION_SNOOZE_OPTIONS); mParser.setString(config); } catch (IllegalArgumentException e) { Log.e(TAG, "Bad snooze constants"); } final int defaultSnooze = mParser.getInt(KEY_DEFAULT_SNOOZE, resources.getInteger(R.integer.config_notification_snooze_time_default)); final int[] snoozeTimes = parseIntArray(KEY_OPTIONS, resources.getIntArray(R.array.config_notification_snooze_times)); options.add(createOption(15 /* minutes */, R.id.action_snooze_15_min)); options.add(createOption(30 /* minutes */, R.id.action_snooze_30_min)); mDefaultOption = createOption(60 /* minutes */, R.id.action_snooze_1_hour); options.add(mDefaultOption); options.add(createOption(60 * 2 /* minutes */, R.id.action_snooze_2_hours)); for (int i = 0; i < snoozeTimes.length && i < sAccessibilityActions.length; i++) { int snoozeTime = snoozeTimes[i]; SnoozeOption option = createOption(snoozeTime, sAccessibilityActions[i]); if (i == 0 || snoozeTime == defaultSnooze) { mDefaultOption = option; } options.add(option); } return options; } @VisibleForTesting int[] parseIntArray(final String key, final int[] defaultArray) { final String value = mParser.getString(key, null); if (value != null) { try { return Arrays.stream(value.split(":")).map(String::trim).mapToInt( Integer::parseInt).toArray(); } catch (NumberFormatException e) { return defaultArray; } } else { return defaultArray; } } private SnoozeOption createOption(int minutes, int accessibilityActionId) { Resources res = getResources(); boolean showInHours = minutes >= 60; Loading