• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2007 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package android.app;
18 
19 import static android.Manifest.permission.POST_NOTIFICATIONS;
20 import static android.app.NotificationChannel.DEFAULT_CHANNEL_ID;
21 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
22 import static android.service.notification.Flags.notificationClassification;
23 
24 import android.annotation.CallbackExecutor;
25 import android.annotation.FlaggedApi;
26 import android.annotation.IntDef;
27 import android.annotation.NonNull;
28 import android.annotation.Nullable;
29 import android.annotation.RequiresPermission;
30 import android.annotation.SdkConstant;
31 import android.annotation.SuppressLint;
32 import android.annotation.SystemApi;
33 import android.annotation.SystemService;
34 import android.annotation.TestApi;
35 import android.annotation.UserHandleAware;
36 import android.annotation.WorkerThread;
37 import android.app.Notification.Builder;
38 import android.app.compat.CompatChanges;
39 import android.compat.annotation.ChangeId;
40 import android.compat.annotation.EnabledSince;
41 import android.compat.annotation.UnsupportedAppUsage;
42 import android.content.ComponentName;
43 import android.content.Context;
44 import android.content.Intent;
45 import android.content.pm.PackageManager;
46 import android.content.pm.ParceledListSlice;
47 import android.content.pm.ShortcutInfo;
48 import android.graphics.drawable.Icon;
49 import android.net.Uri;
50 import android.os.Binder;
51 import android.os.Build;
52 import android.os.Bundle;
53 import android.os.IBinder;
54 import android.os.IpcDataCache;
55 import android.os.Parcel;
56 import android.os.Parcelable;
57 import android.os.RemoteException;
58 import android.os.ServiceManager;
59 import android.os.StrictMode;
60 import android.os.SystemClock;
61 import android.os.UserHandle;
62 import android.provider.Settings;
63 import android.provider.Settings.Global;
64 import android.service.notification.Adjustment;
65 import android.service.notification.Condition;
66 import android.service.notification.RateEstimator;
67 import android.service.notification.StatusBarNotification;
68 import android.service.notification.ZenDeviceEffects;
69 import android.service.notification.ZenModeConfig;
70 import android.service.notification.ZenPolicy;
71 import android.text.TextUtils;
72 import android.util.ArrayMap;
73 import android.util.Log;
74 import android.util.LruCache;
75 import android.util.Slog;
76 import android.util.proto.ProtoOutputStream;
77 
78 import com.android.internal.annotations.VisibleForTesting;
79 import com.android.internal.notification.NotificationChannelGroupsHelper;
80 
81 import java.lang.annotation.Retention;
82 import java.lang.annotation.RetentionPolicy;
83 import java.time.Duration;
84 import java.time.Instant;
85 import java.time.InstantSource;
86 import java.util.ArrayList;
87 import java.util.Arrays;
88 import java.util.HashMap;
89 import java.util.HashSet;
90 import java.util.List;
91 import java.util.Map;
92 import java.util.Objects;
93 import java.util.Set;
94 import java.util.concurrent.Executor;
95 
96 /**
97  * Class to notify the user of events that happen.  This is how you tell
98  * the user that something has happened in the background.
99  *
100  * <p>Notifications can take different forms:
101  * <ul>
102  *      <li>A persistent icon that goes in the status bar and is accessible
103  *          through the launcher, (when the user selects it, a designated Intent
104  *          can be launched),</li>
105  *      <li>Turning on or flashing LEDs on the device, or</li>
106  *      <li>Alerting the user by flashing the backlight, playing a sound,
107  *          or vibrating.</li>
108  * </ul>
109  *
110  * <p>
111  * Each of the notify methods takes an int id parameter and optionally a
112  * {@link String} tag parameter, which may be {@code null}.  These parameters
113  * are used to form a pair (tag, id), or ({@code null}, id) if tag is
114  * unspecified.  This pair identifies this notification from your app to the
115  * system, so that pair should be unique within your app.  If you call one
116  * of the notify methods with a (tag, id) pair that is currently active and
117  * a new set of notification parameters, it will be updated.  For example,
118  * if you pass a new status bar icon, the old icon in the status bar will
119  * be replaced with the new one.  This is also the same tag and id you pass
120  * to the {@link #cancel(int)} or {@link #cancel(String, int)} method to clear
121  * this notification.
122  *
123  * <div class="special reference">
124  * <h3>Developer Guides</h3>
125  * <p>For a guide to creating notifications, read the
126  * <a href="{@docRoot}guide/topics/ui/notifiers/notifications.html">Status Bar Notifications</a>
127  * developer guide.</p>
128  * </div>
129  *
130  * @see android.app.Notification
131  */
132 @SystemService(Context.NOTIFICATION_SERVICE)
133 public class NotificationManager {
134     private static String TAG = "NotificationManager";
135     private static boolean localLOGV = false;
136 
137     /**
138      * Intent that is broadcast when an application is blocked or unblocked.
139      *
140      * This broadcast is only sent to the app whose block state has changed.
141      *
142      * Input: nothing
143      * Output: {@link #EXTRA_BLOCKED_STATE}
144      */
145     @SdkConstant(SdkConstant.SdkConstantType.BROADCAST_INTENT_ACTION)
146     public static final String ACTION_APP_BLOCK_STATE_CHANGED =
147             "android.app.action.APP_BLOCK_STATE_CHANGED";
148 
149     /**
150      * Intent that is broadcast when a {@link NotificationChannel} is blocked
151      * (when {@link NotificationChannel#getImportance()} is {@link #IMPORTANCE_NONE}) or unblocked
152      * (when {@link NotificationChannel#getImportance()} is anything other than
153      * {@link #IMPORTANCE_NONE}).
154      *
155      * This broadcast is only sent to the app that owns the channel that has changed.
156      *
157      * Input: nothing
158      * Output: {@link #EXTRA_NOTIFICATION_CHANNEL_ID}
159      * Output: {@link #EXTRA_BLOCKED_STATE}
160      */
161     @SdkConstant(SdkConstant.SdkConstantType.BROADCAST_INTENT_ACTION)
162     public static final String ACTION_NOTIFICATION_CHANNEL_BLOCK_STATE_CHANGED =
163             "android.app.action.NOTIFICATION_CHANNEL_BLOCK_STATE_CHANGED";
164 
165     /**
166      * Activity action: Toggle notification panel of the specified handler.
167      *
168      * <p><strong>Important:</strong>You must protect the activity that handles this action with
169      * the {@link android.Manifest.permission#STATUS_BAR_SERVICE} permission to ensure that only
170      * the SystemUI can launch this activity. Activities that are not properly protected will not
171      * be launched.
172      *
173      * <p class="note">This is currently only used on TV to allow a system app to handle the
174      * notification panel. The package handling the notification panel has to be specified by
175      * config_notificationHandlerPackage in values/config.xml.
176      *
177      * Input: nothing
178      * Output: nothing
179      * @hide
180      */
181     @SystemApi
182     @RequiresPermission(android.Manifest.permission.STATUS_BAR_SERVICE)
183     @SdkConstant(SdkConstant.SdkConstantType.ACTIVITY_INTENT_ACTION)
184     public static final String ACTION_TOGGLE_NOTIFICATION_HANDLER_PANEL =
185             "android.app.action.TOGGLE_NOTIFICATION_HANDLER_PANEL";
186 
187     /**
188      * Activity action: Open notification panel of the specified handler.
189      *
190      * <p><strong>Important:</strong>You must protect the activity that handles this action with
191      * the {@link android.Manifest.permission#STATUS_BAR_SERVICE} permission to ensure that only
192      * the SystemUI can launch this activity. Activities that are not properly protected will
193      * not be launched.
194      *
195      * <p class="note"> This is currently only used on TV to allow a system app to handle the
196      * notification panel. The package handling the notification panel has to be specified by
197      * config_notificationHandlerPackage in values/config.xml.
198      *
199      * Input: nothing
200      * Output: nothing
201      * @hide
202      */
203     @SystemApi
204     @RequiresPermission(android.Manifest.permission.STATUS_BAR_SERVICE)
205     @SdkConstant(SdkConstant.SdkConstantType.ACTIVITY_INTENT_ACTION)
206     public static final String ACTION_OPEN_NOTIFICATION_HANDLER_PANEL =
207             "android.app.action.OPEN_NOTIFICATION_HANDLER_PANEL";
208 
209     /**
210      * Intent that is broadcast when the notification panel of the specified handler is to be
211      * closed.
212      *
213      * <p><strong>Important:</strong>You should protect the receiver that handles this action with
214      * the {@link android.Manifest.permission#STATUS_BAR_SERVICE} permission to ensure that only
215      * the SystemUI can send this broadcast to the notification handler.
216      *
217      * <p class="note"> This is currently only used on TV to allow a system app to handle the
218      * notification panel. The package handling the notification panel has to be specified by
219      * config_notificationHandlerPackage in values/config.xml. This is a protected intent that can
220      * only be sent by the system.
221      *
222      * Input: nothing.
223      * Output: nothing.
224      * @hide
225      */
226     @SystemApi
227     @RequiresPermission(android.Manifest.permission.STATUS_BAR_SERVICE)
228     @SdkConstant(SdkConstant.SdkConstantType.BROADCAST_INTENT_ACTION)
229     public static final String ACTION_CLOSE_NOTIFICATION_HANDLER_PANEL =
230             "android.app.action.CLOSE_NOTIFICATION_HANDLER_PANEL";
231 
232     /**
233      * Extra for {@link #ACTION_NOTIFICATION_CHANNEL_BLOCK_STATE_CHANGED} containing the id of the
234      * {@link NotificationChannel} which has a new blocked state.
235      *
236      * The value will be the {@link NotificationChannel#getId()} of the channel.
237      */
238     public static final String EXTRA_NOTIFICATION_CHANNEL_ID =
239             "android.app.extra.NOTIFICATION_CHANNEL_ID";
240 
241     /**
242      * Extra for {@link #ACTION_NOTIFICATION_CHANNEL_GROUP_BLOCK_STATE_CHANGED} containing the id
243      * of the {@link NotificationChannelGroup} which has a new blocked state.
244      *
245      * The value will be the {@link NotificationChannelGroup#getId()} of the group.
246      */
247     public static final String EXTRA_NOTIFICATION_CHANNEL_GROUP_ID =
248             "android.app.extra.NOTIFICATION_CHANNEL_GROUP_ID";
249 
250 
251     /**
252      * Extra for {@link #ACTION_NOTIFICATION_CHANNEL_BLOCK_STATE_CHANGED} or
253      * {@link #ACTION_NOTIFICATION_CHANNEL_GROUP_BLOCK_STATE_CHANGED} containing the new blocked
254      * state as a boolean.
255      *
256      * The value will be {@code true} if this channel or group is now blocked and {@code false} if
257      * this channel or group is now unblocked.
258      */
259     public static final String EXTRA_BLOCKED_STATE = "android.app.extra.BLOCKED_STATE";
260 
261     /**
262      * Intent that is broadcast when a {@link NotificationChannelGroup} is
263      * {@link NotificationChannelGroup#isBlocked() blocked} or unblocked.
264      *
265      * This broadcast is only sent to the app that owns the channel group that has changed.
266      *
267      * Input: nothing
268      * Output: {@link #EXTRA_NOTIFICATION_CHANNEL_GROUP_ID}
269      * Output: {@link #EXTRA_BLOCKED_STATE}
270      */
271     @SdkConstant(SdkConstant.SdkConstantType.BROADCAST_INTENT_ACTION)
272     public static final String ACTION_NOTIFICATION_CHANNEL_GROUP_BLOCK_STATE_CHANGED =
273             "android.app.action.NOTIFICATION_CHANNEL_GROUP_BLOCK_STATE_CHANGED";
274 
275     /**
276      * Intent that is broadcast when the status of an {@link AutomaticZenRule} has changed.
277      *
278      * <p>Use this to know whether you need to continue monitor to device state in order to
279      * provide up-to-date states (with {@link #setAutomaticZenRuleState(String, Condition)}) for
280      * this rule.</p>
281      *
282      * Input: nothing
283      * Output: {@link #EXTRA_AUTOMATIC_ZEN_RULE_ID}
284      * Output: {@link #EXTRA_AUTOMATIC_ZEN_RULE_STATUS}
285      */
286     @SdkConstant(SdkConstant.SdkConstantType.BROADCAST_INTENT_ACTION)
287     public static final String ACTION_AUTOMATIC_ZEN_RULE_STATUS_CHANGED =
288             "android.app.action.AUTOMATIC_ZEN_RULE_STATUS_CHANGED";
289 
290     /**
291      * Integer extra for {@link #ACTION_AUTOMATIC_ZEN_RULE_STATUS_CHANGED} containing the state of
292      * the {@link AutomaticZenRule}.
293      *
294      * <p>The value will be one of {@link #AUTOMATIC_RULE_STATUS_ENABLED},
295      * {@link #AUTOMATIC_RULE_STATUS_DISABLED}, {@link #AUTOMATIC_RULE_STATUS_REMOVED},
296      * {@link #AUTOMATIC_RULE_STATUS_ACTIVATED}, {@link #AUTOMATIC_RULE_STATUS_DEACTIVATED}, or
297      * {@link #AUTOMATIC_RULE_STATUS_UNKNOWN}.
298      *
299      * <p>Note that the {@link #AUTOMATIC_RULE_STATUS_ACTIVATED} and
300      * {@link #AUTOMATIC_RULE_STATUS_DEACTIVATED} statuses are only sent to packages targeting
301      * {@link Build.VERSION_CODES#VANILLA_ICE_CREAM} and above; apps targeting a lower SDK version
302      * will be sent {@link #AUTOMATIC_RULE_STATUS_UNKNOWN} in their place instead.
303      */
304     public static final String EXTRA_AUTOMATIC_ZEN_RULE_STATUS =
305             "android.app.extra.AUTOMATIC_ZEN_RULE_STATUS";
306 
307     /**
308      * String extra for {@link #ACTION_AUTOMATIC_ZEN_RULE_STATUS_CHANGED} containing the id of the
309      * {@link AutomaticZenRule} (see {@link #addAutomaticZenRule(AutomaticZenRule)}) that has
310      * changed.
311      */
312     public static final String EXTRA_AUTOMATIC_ZEN_RULE_ID =
313             "android.app.extra.AUTOMATIC_ZEN_RULE_ID";
314 
315     /** @hide */
316     @IntDef(prefix = { "AUTOMATIC_RULE_STATUS" }, value = {
317             AUTOMATIC_RULE_STATUS_ENABLED, AUTOMATIC_RULE_STATUS_DISABLED,
318             AUTOMATIC_RULE_STATUS_REMOVED, AUTOMATIC_RULE_STATUS_UNKNOWN,
319             AUTOMATIC_RULE_STATUS_ACTIVATED, AUTOMATIC_RULE_STATUS_DEACTIVATED
320     })
321     @Retention(RetentionPolicy.SOURCE)
322     public @interface AutomaticZenRuleStatus {}
323 
324     /**
325      * Constant value for {@link #EXTRA_AUTOMATIC_ZEN_RULE_STATUS} - the current status of the
326      * rule is unknown at your target sdk version, and you should continue to provide state changes
327      * via {@link #setAutomaticZenRuleState(String, Condition)}.
328      */
329     public static final int AUTOMATIC_RULE_STATUS_UNKNOWN = -1;
330 
331     /**
332      * Constant value for {@link #EXTRA_AUTOMATIC_ZEN_RULE_STATUS} - the given rule currently
333      * exists and is enabled. You should continue to provide state changes via
334      * {@link #setAutomaticZenRuleState(String, Condition)}.
335      */
336     public static final int AUTOMATIC_RULE_STATUS_ENABLED = 1;
337 
338     /**
339      * Constant value for {@link #EXTRA_AUTOMATIC_ZEN_RULE_STATUS} - the given rule currently
340      * exists but is disabled. You do not need to continue to provide state changes via
341      * {@link #setAutomaticZenRuleState(String, Condition)} until the rule is reenabled.
342      */
343     public static final int AUTOMATIC_RULE_STATUS_DISABLED = 2;
344 
345     /**
346      * Constant value for {@link #EXTRA_AUTOMATIC_ZEN_RULE_STATUS} - the given rule has been
347      * deleted. Further calls to {@link #setAutomaticZenRuleState(String, Condition)} will be
348      * ignored.
349      */
350     public static final int AUTOMATIC_RULE_STATUS_REMOVED = 3;
351 
352     /**
353      * Constant value for {@link #EXTRA_AUTOMATIC_ZEN_RULE_STATUS} - the given rule has been
354      * activated by the user or cross device sync. Sent from
355      * {@link Build.VERSION_CODES#VANILLA_ICE_CREAM}. If the rule owner has a mode that includes
356      * a DND component, the rule owner should activate any extra behavior that's part of that mode
357      * in response to this broadcast.
358      */
359     public static final int AUTOMATIC_RULE_STATUS_ACTIVATED = 4;
360 
361     /**
362      * Constant value for {@link #EXTRA_AUTOMATIC_ZEN_RULE_STATUS} - the given rule has been
363      * deactivated ("snoozed") by the user. The rule will not return to an activated state until
364      * the app calls {@link #setAutomaticZenRuleState(String, Condition)} with
365      * {@link Condition#STATE_FALSE} (either immediately or when the trigger criteria is no
366      * longer met) and then {@link Condition#STATE_TRUE} when the trigger criteria is freshly met,
367      * or when the user re-activates it.
368      */
369     public static final int AUTOMATIC_RULE_STATUS_DEACTIVATED = 5;
370 
371     /**
372      * Intent that is broadcast when the state of {@link #getEffectsSuppressor()} changes.
373      *
374      * <p>This broadcast is only sent to registered receivers and (starting from
375      * {@link Build.VERSION_CODES#Q}) receivers in packages that have been granted Do Not
376      * Disturb access (see {@link #isNotificationPolicyAccessGranted()}).
377      *
378      * @hide
379      */
380     @SdkConstant(SdkConstant.SdkConstantType.BROADCAST_INTENT_ACTION)
381     public static final String ACTION_EFFECTS_SUPPRESSOR_CHANGED
382             = "android.os.action.ACTION_EFFECTS_SUPPRESSOR_CHANGED";
383 
384     /**
385      * Intent that is broadcast when the state of {@link #isNotificationPolicyAccessGranted()}
386      * changes.
387      *
388      * This broadcast is only sent to registered receivers, and only to the apps that have changed.
389      */
390     @SdkConstant(SdkConstant.SdkConstantType.BROADCAST_INTENT_ACTION)
391     public static final String ACTION_NOTIFICATION_POLICY_ACCESS_GRANTED_CHANGED
392             = "android.app.action.NOTIFICATION_POLICY_ACCESS_GRANTED_CHANGED";
393 
394     /**
395      * Intent that is broadcast when the state of {@link #getNotificationPolicy()} changes.
396      *
397      * <p>This broadcast is only sent to registered receivers and (starting from
398      * {@link Build.VERSION_CODES#Q}) receivers in packages that have been granted Do Not
399      * Disturb access (see {@link #isNotificationPolicyAccessGranted()}).
400      *
401      * <p>Starting with {@link Build.VERSION_CODES#VANILLA_ICE_CREAM}, most calls to
402      * {@link #setNotificationPolicy(Policy)} will update the app's implicit rule policy instead of
403      * the global policy, so this broadcast will be sent much less frequently.
404      */
405     @SdkConstant(SdkConstant.SdkConstantType.BROADCAST_INTENT_ACTION)
406     public static final String ACTION_NOTIFICATION_POLICY_CHANGED
407             = "android.app.action.NOTIFICATION_POLICY_CHANGED";
408 
409     /**
410      * Intent that is broadcast when the state of {@link #getConsolidatedNotificationPolicy()}
411      * changes.
412      *
413      * <p>This broadcast is only sent to registered receivers and receivers in packages that have
414      * been granted Notification Policy access (see {@link #isNotificationPolicyAccessGranted()}).
415      */
416     @SdkConstant(SdkConstant.SdkConstantType.BROADCAST_INTENT_ACTION)
417     public static final String ACTION_CONSOLIDATED_NOTIFICATION_POLICY_CHANGED =
418             "android.app.action.CONSOLIDATED_NOTIFICATION_POLICY_CHANGED";
419 
420     /**
421      * Extra for {@link #ACTION_NOTIFICATION_POLICY_CHANGED} and
422      * {@link #ACTION_CONSOLIDATED_NOTIFICATION_POLICY_CHANGED} containing the new
423      * {@link Policy} value.
424      */
425     public static final String EXTRA_NOTIFICATION_POLICY =
426             "android.app.extra.NOTIFICATION_POLICY";
427 
428     /**
429      * Intent that is broadcast when the state of getCurrentInterruptionFilter() changes.
430      *
431      * <p>This broadcast is only sent to registered receivers and (starting from
432      * {@link Build.VERSION_CODES#Q}) receivers in packages that have been granted Do Not
433      * Disturb access (see {@link #isNotificationPolicyAccessGranted()}).
434      */
435     @SdkConstant(SdkConstant.SdkConstantType.BROADCAST_INTENT_ACTION)
436     public static final String ACTION_INTERRUPTION_FILTER_CHANGED
437             = "android.app.action.INTERRUPTION_FILTER_CHANGED";
438 
439     /**
440      * Intent that is broadcast when the state of
441      * {@link #hasEnabledNotificationListener(String, UserHandle)} changes.
442      * @hide
443      */
444     @SdkConstant(SdkConstant.SdkConstantType.BROADCAST_INTENT_ACTION)
445     @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
446     public static final String ACTION_NOTIFICATION_LISTENER_ENABLED_CHANGED =
447             "android.app.action.NOTIFICATION_LISTENER_ENABLED_CHANGED";
448 
449     /**
450      * Intent that is broadcast when the state of getCurrentInterruptionFilter() changes.
451      * @hide
452      */
453     @SdkConstant(SdkConstant.SdkConstantType.BROADCAST_INTENT_ACTION)
454     public static final String ACTION_INTERRUPTION_FILTER_CHANGED_INTERNAL
455             = "android.app.action.INTERRUPTION_FILTER_CHANGED_INTERNAL";
456 
457     /** @hide */
458     @IntDef(prefix = { "INTERRUPTION_FILTER_" }, value = {
459             INTERRUPTION_FILTER_NONE, INTERRUPTION_FILTER_PRIORITY, INTERRUPTION_FILTER_ALARMS,
460             INTERRUPTION_FILTER_ALL, INTERRUPTION_FILTER_UNKNOWN
461     })
462     @Retention(RetentionPolicy.SOURCE)
463     public @interface InterruptionFilter {}
464 
465     /**
466      * {@link #getCurrentInterruptionFilter() Interruption filter} constant -
467      *     Normal interruption filter - no notifications are suppressed.
468      */
469     public static final int INTERRUPTION_FILTER_ALL = 1;
470 
471     /**
472      * {@link #getCurrentInterruptionFilter() Interruption filter} constant -
473      *     Priority interruption filter - all notifications are suppressed except those that match
474      *     the priority criteria. Some audio streams are muted. See
475      *     {@link Policy#priorityCallSenders}, {@link Policy#priorityCategories},
476      *     {@link Policy#priorityMessageSenders} to define or query this criteria. Users can
477      *     additionally specify packages that can bypass this interruption filter.
478      */
479     public static final int INTERRUPTION_FILTER_PRIORITY = 2;
480 
481     /**
482      * {@link #getCurrentInterruptionFilter() Interruption filter} constant -
483      *     No interruptions filter - all notifications are suppressed and all audio streams (except
484      *     those used for phone calls) and vibrations are muted.
485      */
486     public static final int INTERRUPTION_FILTER_NONE = 3;
487 
488     /**
489      * {@link #getCurrentInterruptionFilter() Interruption filter} constant -
490      *     Alarms only interruption filter - all notifications except those of category
491      *     {@link Notification#CATEGORY_ALARM} are suppressed. Some audio streams are muted.
492      */
493     public static final int INTERRUPTION_FILTER_ALARMS = 4;
494 
495     /** {@link #getCurrentInterruptionFilter() Interruption filter} constant - returned when
496      * the value is unavailable for any reason.
497      */
498     public static final int INTERRUPTION_FILTER_UNKNOWN = 0;
499 
500     /** @hide */
501     @IntDef(prefix = { "IMPORTANCE_" }, value = {
502             IMPORTANCE_UNSPECIFIED, IMPORTANCE_NONE,
503             IMPORTANCE_MIN, IMPORTANCE_LOW, IMPORTANCE_DEFAULT, IMPORTANCE_HIGH
504     })
505     @Retention(RetentionPolicy.SOURCE)
506     public @interface Importance {}
507 
508     /** @hide */
509     @IntDef(prefix = { "BUBBLE_PREFERENCE_" }, value = {
510             BUBBLE_PREFERENCE_NONE, BUBBLE_PREFERENCE_SELECTED,
511             BUBBLE_PREFERENCE_ALL
512     })
513     @Retention(RetentionPolicy.SOURCE)
514     public @interface BubblePreference {}
515 
516     /**
517      * Activity Action: Launch an Automatic Zen Rule configuration screen
518      *
519      * <p> Input: Optionally, {@link #EXTRA_AUTOMATIC_RULE_ID}, if the configuration screen for an
520      * existing rule should be displayed. If the rule id is missing or null, apps should display
521      * a configuration screen where users can create a new instance of the rule.
522      *
523      * <p> Output: Nothing
524      *
525      * <p> You can have multiple activities handling this intent, if you support multiple
526      * {@link AutomaticZenRule rules}. In order for the system to properly display all of your
527      * rule types so that users can create new instances or configure existing ones, you need
528      * to add some extra metadata ({@link #META_DATA_AUTOMATIC_RULE_TYPE})
529      * to your activity tag in your manifest. If you'd like to limit the number of rules a user
530      * can create from this flow, you can additionally optionally include
531      * {@link #META_DATA_RULE_INSTANCE_LIMIT}. For example,
532      *
533      * <pre>
534      *     {@code
535      *     <meta-data
536      *         android:name="android.service.zen.automatic.ruleType"
537      *         android:value="@string/my_condition_rule" />
538      *     <meta-data
539      *         android:name="android.service.zen.automatic.ruleInstanceLimit"
540      *         android:value="1" />
541      *     }
542      * </pre>
543      *
544      * @see #addAutomaticZenRule(AutomaticZenRule)
545      */
546     @SdkConstant(SdkConstant.SdkConstantType.ACTIVITY_INTENT_ACTION)
547     public static final String ACTION_AUTOMATIC_ZEN_RULE =
548             "android.app.action.AUTOMATIC_ZEN_RULE";
549 
550     /**
551      * Used as an optional string extra on {@link #ACTION_AUTOMATIC_ZEN_RULE} intents. If
552      * provided, contains the id of the {@link AutomaticZenRule} (as returned from
553      * {@link NotificationManager#addAutomaticZenRule(AutomaticZenRule)}) for which configuration
554      * settings should be displayed.
555      */
556     public static final String EXTRA_AUTOMATIC_RULE_ID = "android.app.extra.AUTOMATIC_RULE_ID";
557 
558     /**
559      * A required {@code meta-data} tag for activities that handle
560      * {@link #ACTION_AUTOMATIC_ZEN_RULE}.
561      *
562      * This tag should contain a localized name of the type of the zen rule provided by the
563      * activity.
564      */
565     public static final String META_DATA_AUTOMATIC_RULE_TYPE =
566             "android.service.zen.automatic.ruleType";
567 
568     /**
569      * An optional {@code meta-data} tag for activities that handle
570      * {@link #ACTION_AUTOMATIC_ZEN_RULE}.
571      *
572      * This tag should contain the maximum number of rule instances that
573      * can be created for this rule type. Omit or enter a value <= 0 to allow unlimited instances.
574      */
575     public static final String META_DATA_RULE_INSTANCE_LIMIT =
576             "android.service.zen.automatic.ruleInstanceLimit";
577 
578     /** Value signifying that the user has not expressed a per-app visibility override value.
579      * @hide */
580     public static final int VISIBILITY_NO_OVERRIDE = -1000;
581 
582     /**
583      * Value signifying that the user has not expressed an importance.
584      *
585      * This value is for persisting preferences, and should never be associated with
586      * an actual notification.
587      */
588     public static final int IMPORTANCE_UNSPECIFIED = -1000;
589 
590     /**
591      * A notification with no importance: does not show in the shade.
592      */
593     public static final int IMPORTANCE_NONE = 0;
594 
595     /**
596      * Min notification importance: only shows in the shade, below the fold.  This should
597      * not be used with {@link Service#startForeground(int, Notification) Service.startForeground}
598      * since a foreground service is supposed to be something the user cares about so it does
599      * not make semantic sense to mark its notification as minimum importance.  If you do this
600      * as of Android version {@link android.os.Build.VERSION_CODES#O}, the system will show
601      * a higher-priority notification about your app running in the background.
602      */
603     public static final int IMPORTANCE_MIN = 1;
604 
605     /**
606      * Low notification importance: Shows in the shade, and potentially in the status bar
607      * (see {@link #shouldHideSilentStatusBarIcons()}), but is not audibly intrusive.
608      */
609     public static final int IMPORTANCE_LOW = 2;
610 
611     /**
612      * Default notification importance: shows everywhere, makes noise, but does not visually
613      * intrude.
614      */
615     public static final int IMPORTANCE_DEFAULT = 3;
616 
617     /**
618      * Higher notification importance: shows everywhere, makes noise and peeks. May use full screen
619      * intents.
620      */
621     public static final int IMPORTANCE_HIGH = 4;
622 
623     /**
624      * Unused.
625      */
626     public static final int IMPORTANCE_MAX = 5;
627 
628     /**
629      * Indicates that the no bubbles are allowed from the app. If the app sends bubbles, only the
630      * notification will appear. The notification will have an affordance allowing the user to
631      * bubble it. If the user selects this affordance, that notification is approved to bubble
632      * and the apps' bubble preference will be upgraded to {@link #BUBBLE_PREFERENCE_SELECTED}.
633      */
634     public static final int BUBBLE_PREFERENCE_NONE = 0;
635 
636     /**
637      * Indicates that all bubbles are allowed from the app. If the app sends bubbles, the bubble
638      * will appear along with the notification.
639      */
640     public static final int BUBBLE_PREFERENCE_ALL = 1;
641 
642     /**
643      * Indicates that only notifications selected by the user will appear as bubbles. If
644      * the app sends bubbles that haven't been selected, only the notification appear. If the
645      * bubble has been approved by the user, it will appear along with the notification.
646      */
647     public static final int BUBBLE_PREFERENCE_SELECTED = 2;
648 
649     /**
650      * Maximum length of the component name of a registered NotificationListenerService.
651      * @hide
652      */
653     public static int MAX_SERVICE_COMPONENT_NAME_LENGTH = 500;
654 
655     private static final float MAX_NOTIFICATION_UPDATE_RATE = 5f;
656     private static final float MAX_NOTIFICATION_UNNECESSARY_CANCEL_RATE = 5f;
657     private static final int KNOWN_STATUS_ENQUEUED = 1;
658     private static final int KNOWN_STATUS_CANCELLED = 2;
659 
660     private final Context mContext;
661     private final Map<CallNotificationEventListener, CallNotificationEventCallbackStub>
662             mCallNotificationEventCallbacks = new HashMap<>();
663 
664     private final InstantSource mClock;
665     private final RateLimiter mUpdateRateLimiter = new RateLimiter("notify (update)",
666             "notifications.value_client_throttled_notify_update",
667             MAX_NOTIFICATION_UPDATE_RATE);
668     private final RateLimiter mUnnecessaryCancelRateLimiter = new RateLimiter("cancel (dupe)",
669             "notifications.value_client_throttled_cancel_duplicate",
670             MAX_NOTIFICATION_UNNECESSARY_CANCEL_RATE);
671     // Value is KNOWN_STATUS_ENQUEUED/_CANCELLED
672     private final LruCache<NotificationKey, Integer> mKnownNotifications = new LruCache<>(100);
673     private final Object mThrottleLock = new Object();
674 
675     @UnsupportedAppUsage
676     private static INotificationManager sService;
677 
678     /** @hide */
679     @UnsupportedAppUsage
getService()680     static public INotificationManager getService()
681     {
682         if (sService != null) {
683             return sService;
684         }
685         IBinder b = ServiceManager.getService("notification");
686         sService = INotificationManager.Stub.asInterface(b);
687         return sService;
688     }
689 
690     /** @hide */
service()691     protected INotificationManager service() {
692         return getService();
693     }
694 
695     /** {@hide} */
NotificationManager(Context context)696     public NotificationManager(Context context)
697     {
698         this(context, SystemClock.elapsedRealtimeClock());
699     }
700 
701     /** {@hide} */
702     @UnsupportedAppUsage
NotificationManager(Context context, InstantSource clock)703     public NotificationManager(Context context, InstantSource clock) {
704         mContext = context;
705         mClock = clock;
706     }
707 
708     /** {@hide} */
709     @UnsupportedAppUsage
from(Context context)710     public static NotificationManager from(Context context) {
711         return (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
712     }
713 
714     /**
715      * Post a notification to be shown in the status bar. If a notification with
716      * the same id has already been posted by your application and has not yet been canceled, it
717      * will be replaced by the updated information.
718      *
719      * @param id An identifier for this notification unique within your
720      *        application.
721      * @param notification A {@link Notification} object describing what to show the user. Must not
722      *        be null.
723      */
notify(int id, Notification notification)724     public void notify(int id, Notification notification)
725     {
726         notify(null, id, notification);
727     }
728 
729     /**
730      * Posts a notification to be shown in the status bar. If a notification with
731      * the same tag and id has already been posted by your application and has not yet been
732      * canceled, it will be replaced by the updated information.
733      *
734      * All {@link android.service.notification.NotificationListenerService listener services} will
735      * be granted {@link Intent#FLAG_GRANT_READ_URI_PERMISSION} access to any {@link Uri uris}
736      * provided on this notification or the
737      * {@link NotificationChannel} this notification is posted to using
738      * {@link Context#grantUriPermission(String, Uri, int)}. Permission will be revoked when the
739      * notification is canceled, or you can revoke permissions with
740      * {@link Context#revokeUriPermission(Uri, int)}.
741      *
742      * @param tag A string identifier for this notification.  May be {@code null}.
743      * @param id An identifier for this notification.  The pair (tag, id) must be unique
744      *        within your application.
745      * @param notification A {@link Notification} object describing what to
746      *        show the user. Must not be null.
747      */
notify(String tag, int id, Notification notification)748     public void notify(String tag, int id, Notification notification)
749     {
750         notifyAsUser(tag, id, notification, mContext.getUser());
751     }
752 
753     /**
754      * Posts a notification as a specified package to be shown in the status bar. If a notification
755      * with the same tag and id has already been posted for that package and has not yet been
756      * canceled, it will be replaced by the updated information.
757      *
758      * All {@link android.service.notification.NotificationListenerService listener services} will
759      * be granted {@link Intent#FLAG_GRANT_READ_URI_PERMISSION} access to any {@link Uri uris}
760      * provided on this notification or the
761      * {@link NotificationChannel} this notification is posted to using
762      * {@link Context#grantUriPermission(String, Uri, int)}. Permission will be revoked when the
763      * notification is canceled, or you can revoke permissions with
764      * {@link Context#revokeUriPermission(Uri, int)}.
765      *
766      * @param targetPackage The package to post the notification as. The package must have granted
767      *                      you access to post notifications on their behalf with
768      *                      {@link #setNotificationDelegate(String)}.
769      * @param tag A string identifier for this notification.  May be {@code null}.
770      * @param id An identifier for this notification.  The pair (tag, id) must be unique
771      *        within your application.
772      * @param notification A {@link Notification} object describing what to
773      *        show the user. Must not be null.
774      */
notifyAsPackage(@onNull String targetPackage, @Nullable String tag, int id, @NonNull Notification notification)775     public void notifyAsPackage(@NonNull String targetPackage, @Nullable String tag, int id,
776             @NonNull Notification notification) {
777         INotificationManager service = service();
778         String sender = mContext.getPackageName();
779 
780         if (discardNotify(mContext.getUser(), targetPackage, tag, id, notification)) {
781             return;
782         }
783 
784         try {
785             if (localLOGV) Log.v(TAG, sender + ": notify(" + id + ", " + notification + ")");
786             service.enqueueNotificationWithTag(targetPackage, sender, tag, id,
787                     fixNotification(notification), mContext.getUser().getIdentifier());
788         } catch (RemoteException e) {
789             throw e.rethrowFromSystemServer();
790         }
791     }
792 
793     /**
794      * @hide
795      */
796     @UnsupportedAppUsage
notifyAsUser(@ullable String tag, int id, Notification notification, UserHandle user)797     public void notifyAsUser(@Nullable String tag, int id, Notification notification,
798             UserHandle user)
799     {
800         INotificationManager service = service();
801         String pkg = mContext.getPackageName();
802         if (discardNotify(user, pkg, tag, id, notification)) {
803             return;
804         }
805 
806         try {
807             if (localLOGV) Log.v(TAG, pkg + ": notify(" + id + ", " + notification + ")");
808             service.enqueueNotificationWithTag(pkg, mContext.getOpPackageName(), tag, id,
809                     fixNotification(notification), user.getIdentifier());
810         } catch (RemoteException e) {
811             throw e.rethrowFromSystemServer();
812         }
813     }
814 
815     /**
816      * Determines whether a {@link #notify} call should be skipped. If the notification is not
817      * skipped, updates tracking metadata to use in future decisions.
818      */
discardNotify(UserHandle user, String pkg, @Nullable String tag, int id, Notification notification)819     private boolean discardNotify(UserHandle user, String pkg, @Nullable String tag, int id,
820             Notification notification) {
821         if (notificationClassification()
822                 && NotificationChannel.SYSTEM_RESERVED_IDS.contains(notification.getChannelId())) {
823             return true;
824         }
825 
826         if (Flags.nmBinderPerfThrottleNotify()) {
827             NotificationKey key = new NotificationKey(user, pkg, tag, id);
828             synchronized (mThrottleLock) {
829                 Integer status = mKnownNotifications.get(key);
830                 if (status != null && status == KNOWN_STATUS_ENQUEUED
831                         && !notification.hasCompletedProgress()) {
832                     if (mUpdateRateLimiter.eventExceedsRate()) {
833                         mUpdateRateLimiter.recordRejected(key);
834                         return true;
835                     }
836                     mUpdateRateLimiter.recordAccepted();
837                 }
838                 mKnownNotifications.put(key, KNOWN_STATUS_ENQUEUED);
839             }
840         }
841 
842         return false;
843     }
844 
NotificationKey(@onNull UserHandle user, @NonNull String pkg, @Nullable String tag, int id)845     private record NotificationKey(@NonNull UserHandle user, @NonNull String pkg,
846                                    @Nullable String tag, int id) { }
847 
848     /** Helper class to rate-limit Binder calls. */
849     private class RateLimiter {
850 
851         private static final Duration RATE_LIMITER_LOG_INTERVAL = Duration.ofSeconds(1);
852 
853         private final RateEstimator mInputRateEstimator;
854         private final RateEstimator mOutputRateEstimator;
855         private final String mName;
856         private final String mCounterName;
857         private final float mLimitRate;
858 
859         private Instant mLogSilencedUntil;
860 
RateLimiter(String name, String counterName, float limitRate)861         private RateLimiter(String name, String counterName, float limitRate) {
862             mInputRateEstimator = new RateEstimator();
863             mOutputRateEstimator = new RateEstimator();
864             mName = name;
865             mCounterName = counterName;
866             mLimitRate = limitRate;
867         }
868 
eventExceedsRate()869         boolean eventExceedsRate() {
870             long nowMillis = mClock.millis();
871             mInputRateEstimator.update(nowMillis);
872             return mOutputRateEstimator.getRate(nowMillis) > mLimitRate;
873         }
874 
recordAccepted()875         void recordAccepted() {
876             mOutputRateEstimator.update(mClock.millis());
877         }
878 
recordRejected(NotificationKey key)879         void recordRejected(NotificationKey key) {
880             Instant now = mClock.instant();
881             if (mLogSilencedUntil != null && now.isBefore(mLogSilencedUntil)) {
882                 return;
883             }
884 
885             if (Flags.nmBinderPerfLogNmThrottling()) {
886                 try {
887                     service().incrementCounter(mCounterName);
888                 } catch (RemoteException e) {
889                     Slog.w(TAG, "Ignoring error while trying to log " + mCounterName, e);
890                 }
891             }
892 
893             long nowMillis = now.toEpochMilli();
894             Slog.w(TAG, TextUtils.formatSimple(
895                     "Shedding %s of %s, rate limit (%s) exceeded: input %s, output would be %s",
896                     mName, key, mLimitRate, mInputRateEstimator.getRate(nowMillis),
897                     mOutputRateEstimator.getRate(nowMillis)));
898 
899             mLogSilencedUntil = now.plus(RATE_LIMITER_LOG_INTERVAL);
900         }
901     }
902 
fixNotification(Notification notification)903     private Notification fixNotification(Notification notification) {
904         String pkg = mContext.getPackageName();
905         // Fix the notification as best we can.
906         Notification.addFieldsFromContext(mContext, notification);
907 
908         if (notification.sound != null) {
909             notification.sound = notification.sound.getCanonicalUri();
910             if (StrictMode.vmFileUriExposureEnabled()) {
911                 notification.sound.checkFileUriExposed("Notification.sound");
912             }
913 
914         }
915         fixLegacySmallIcon(notification, pkg);
916         if (mContext.getApplicationInfo().targetSdkVersion > Build.VERSION_CODES.LOLLIPOP_MR1) {
917             if (notification.getSmallIcon() == null) {
918                 throw new IllegalArgumentException("Invalid notification (no valid small icon): "
919                         + notification);
920             }
921         }
922 
923         notification.reduceImageSizes(mContext);
924         return Builder.maybeCloneStrippedForDelivery(notification);
925     }
926 
fixLegacySmallIcon(Notification n, String pkg)927     private void fixLegacySmallIcon(Notification n, String pkg) {
928         if (n.getSmallIcon() == null && n.icon != 0) {
929             n.setSmallIcon(Icon.createWithResource(pkg, n.icon));
930         }
931     }
932 
933     /**
934      * Cancels a previously posted notification.
935      *
936      *  <p>If the notification does not currently represent a
937      *  {@link Service#startForeground(int, Notification) foreground service} or a
938      *  {@link android.app.job.JobInfo.Builder#setUserInitiated(boolean) user-initiated job},
939      *  it will be removed from the UI and live
940      *  {@link android.service.notification.NotificationListenerService notification listeners}
941      *  will be informed so they can remove the notification from their UIs.</p>
942      */
cancel(int id)943     public void cancel(int id)
944     {
945         cancel(null, id);
946     }
947 
948     /**
949      * Cancels a previously posted notification.
950      *
951      *  <p>If the notification does not currently represent a
952      *  {@link Service#startForeground(int, Notification) foreground service} or a
953      *  {@link android.app.job.JobInfo.Builder#setUserInitiated(boolean) user-initiated job},
954      *  it will be removed from the UI and live
955      *  {@link android.service.notification.NotificationListenerService notification listeners}
956      *  will be informed so they can remove the notification from their UIs.</p>
957      */
cancel(@ullable String tag, int id)958     public void cancel(@Nullable String tag, int id)
959     {
960         cancelAsUser(tag, id, mContext.getUser());
961     }
962 
963     /**
964      * Cancels a previously posted notification.
965      *
966      * <p>If the notification does not currently represent a
967      *  {@link Service#startForeground(int, Notification) foreground service} or a
968      *  {@link android.app.job.JobInfo.Builder#setUserInitiated(boolean) user-initiated job},
969      *  it will be removed from the UI and live
970      * {@link android.service.notification.NotificationListenerService notification listeners}
971      * will be informed so they can remove the notification from their UIs.</p>
972      *
973      * <p>This method may be used by {@link #getNotificationDelegate() a notification delegate} to
974      * cancel notifications that they have posted via {@link #notifyAsPackage(String, String, int,
975      * Notification)}.</p>
976      *
977      * @param targetPackage The package to cancel the notification as. If this package is not your
978      *                      package, you can only cancel notifications you posted with
979      *                      {@link #notifyAsPackage(String, String, int, Notification).
980      * @param tag A string identifier for this notification.  May be {@code null}.
981      * @param id An identifier for this notification.
982      */
cancelAsPackage(@onNull String targetPackage, @Nullable String tag, int id)983     public void cancelAsPackage(@NonNull String targetPackage, @Nullable String tag, int id) {
984         if (discardCancel(mContext.getUser(), targetPackage, tag, id)) {
985             return;
986         }
987 
988         INotificationManager service = service();
989         try {
990             service.cancelNotificationWithTag(targetPackage, mContext.getOpPackageName(),
991                     tag, id, mContext.getUser().getIdentifier());
992         } catch (RemoteException e) {
993             throw e.rethrowFromSystemServer();
994         }
995     }
996 
997     /**
998      * @hide
999      */
1000     @UnsupportedAppUsage
cancelAsUser(@ullable String tag, int id, UserHandle user)1001     public void cancelAsUser(@Nullable String tag, int id, UserHandle user)
1002     {
1003         String pkg = mContext.getPackageName();
1004         if (discardCancel(user, pkg, tag, id)) {
1005             return;
1006         }
1007 
1008         INotificationManager service = service();
1009         if (localLOGV) Log.v(TAG, pkg + ": cancel(" + id + ")");
1010         try {
1011             service.cancelNotificationWithTag(
1012                     pkg, mContext.getOpPackageName(), tag, id, user.getIdentifier());
1013         } catch (RemoteException e) {
1014             throw e.rethrowFromSystemServer();
1015         }
1016     }
1017 
1018     /**
1019      * Determines whether a {@link #cancel} call should be skipped. If not skipped, updates tracking
1020      * metadata to use in future decisions.
1021      */
discardCancel(UserHandle user, String pkg, @Nullable String tag, int id)1022     private boolean discardCancel(UserHandle user, String pkg, @Nullable String tag, int id) {
1023         if (Flags.nmBinderPerfThrottleNotify()) {
1024             NotificationKey key = new NotificationKey(user, pkg, tag, id);
1025             synchronized (mThrottleLock) {
1026                 Integer status = mKnownNotifications.get(key);
1027                 if (status != null && status == KNOWN_STATUS_CANCELLED) {
1028                     if (mUnnecessaryCancelRateLimiter.eventExceedsRate()) {
1029                         mUnnecessaryCancelRateLimiter.recordRejected(key);
1030                         return true;
1031                     }
1032                     mUnnecessaryCancelRateLimiter.recordAccepted();
1033                 }
1034                 mKnownNotifications.put(key, KNOWN_STATUS_CANCELLED);
1035             }
1036         }
1037 
1038         return false;
1039     }
1040 
1041     /**
1042      * Cancel all previously shown notifications. See {@link #cancel} for the
1043      * detailed behavior.
1044      */
cancelAll()1045     public void cancelAll()
1046     {
1047         String pkg = mContext.getPackageName();
1048         UserHandle user = mContext.getUser();
1049 
1050         if (Flags.nmBinderPerfThrottleNotify()) {
1051             synchronized (mThrottleLock) {
1052                 for (NotificationKey key : mKnownNotifications.snapshot().keySet()) {
1053                     if (key.pkg.equals(pkg) && key.user.equals(user)) {
1054                         mKnownNotifications.put(key, KNOWN_STATUS_CANCELLED);
1055                     }
1056                 }
1057             }
1058         }
1059 
1060         INotificationManager service = service();
1061         if (localLOGV) Log.v(TAG, pkg + ": cancelAll()");
1062         try {
1063             service.cancelAllNotifications(pkg, mContext.getUserId());
1064         } catch (RemoteException e) {
1065             throw e.rethrowFromSystemServer();
1066         }
1067     }
1068 
1069     /**
1070      * Allows a package to post notifications on your behalf using
1071      * {@link #notifyAsPackage(String, String, int, Notification)}.
1072      *
1073      * This can be used to allow persistent processes to post notifications based on messages
1074      * received on your behalf from the cloud, without your process having to wake up.
1075      *
1076      * You can check if you have an allowed delegate with {@link #getNotificationDelegate()} and
1077      * revoke your delegate by passing null to this method.
1078      *
1079      * @param delegate Package name of the app which can send notifications on your behalf.
1080      */
setNotificationDelegate(@ullable String delegate)1081     public void setNotificationDelegate(@Nullable String delegate) {
1082         INotificationManager service = service();
1083         String pkg = mContext.getPackageName();
1084         if (localLOGV) Log.v(TAG, pkg + ": setNotificationDelegate()");
1085         try {
1086             service.setNotificationDelegate(pkg, delegate);
1087         } catch (RemoteException e) {
1088             throw e.rethrowFromSystemServer();
1089         }
1090     }
1091 
1092     /**
1093      * Returns the {@link #setNotificationDelegate(String) delegate} that can post notifications on
1094      * your behalf, if there currently is one.
1095      */
getNotificationDelegate()1096     public @Nullable String getNotificationDelegate() {
1097         INotificationManager service = service();
1098         String pkg = mContext.getPackageName();
1099         try {
1100             return service.getNotificationDelegate(pkg);
1101         } catch (RemoteException e) {
1102             throw e.rethrowFromSystemServer();
1103         }
1104     }
1105 
1106     /**
1107      * Returns whether you are allowed to post notifications on behalf of a given package, with
1108      * {@link #notifyAsPackage(String, String, int, Notification)}.
1109      *
1110      * See {@link #setNotificationDelegate(String)}.
1111      */
canNotifyAsPackage(@onNull String pkg)1112     public boolean canNotifyAsPackage(@NonNull String pkg) {
1113         INotificationManager service = service();
1114         try {
1115             return service.canNotifyAsPackage(mContext.getPackageName(), pkg, mContext.getUserId());
1116         } catch (RemoteException e) {
1117             throw e.rethrowFromSystemServer();
1118         }
1119     }
1120 
1121     /**
1122      * Returns whether the calling app can send fullscreen intents.
1123      * <p>From Android {@link android.os.Build.VERSION_CODES#UPSIDE_DOWN_CAKE}, apps may not have
1124      * permission to use {@link android.Manifest.permission#USE_FULL_SCREEN_INTENT}. If permission
1125      * is denied, notification will show up as an expanded heads up notification on lockscreen.
1126      * <p> To request access, add the {@link android.Manifest.permission#USE_FULL_SCREEN_INTENT}
1127      * permission to your manifest, and use
1128      * {@link android.provider.Settings#ACTION_MANAGE_APP_USE_FULL_SCREEN_INTENT}.
1129      */
canUseFullScreenIntent()1130     public boolean canUseFullScreenIntent() {
1131         INotificationManager service = service();
1132         try {
1133             return service.canUseFullScreenIntent(mContext.getAttributionSource());
1134         } catch (RemoteException e) {
1135             throw e.rethrowFromSystemServer();
1136         }
1137     }
1138 
1139     /**
1140      * Returns whether the calling app's properly formatted notifications can appear in a promoted
1141      * format, which may result in higher ranking, appearances on additional surfaces, and richer
1142      * presentation.
1143      *
1144      * Apps can request this permission by sending the user to the activity that matches the system
1145      * intent action {@link android.provider.Settings#ACTION_APP_NOTIFICATION_PROMOTION_SETTINGS}.
1146      */
1147     @FlaggedApi(android.app.Flags.FLAG_API_RICH_ONGOING)
canPostPromotedNotifications()1148     public boolean canPostPromotedNotifications() {
1149         INotificationManager service = service();
1150         try {
1151             return service.canBePromoted(mContext.getPackageName());
1152         } catch (RemoteException e) {
1153             throw e.rethrowFromSystemServer();
1154         }
1155     }
1156 
1157     /**
1158      * Setter for {@link #canPostPromotedNotifications()}. Only callable by the OS.
1159      * @hide
1160      */
1161     @TestApi
1162     @FlaggedApi(android.app.Flags.FLAG_API_RICH_ONGOING)
setCanPostPromotedNotifications(@onNull String pkg, int uid, boolean allowed)1163     public void setCanPostPromotedNotifications(@NonNull String pkg, int uid, boolean allowed) {
1164         INotificationManager service = service();
1165         try {
1166             service.setCanBePromoted(pkg, uid, allowed, true);
1167         } catch (RemoteException e) {
1168             throw e.rethrowFromSystemServer();
1169         }
1170     }
1171 
1172     /**
1173      * Creates a group container for {@link NotificationChannel} objects.
1174      *
1175      * This can be used to rename an existing group.
1176      * <p>
1177      *     Group information is only used for presentation, not for behavior. Groups are optional
1178      *     for channels, and you can have a mix of channels that belong to groups and channels
1179      *     that do not.
1180      * </p>
1181      * <p>
1182      *     For example, if your application supports multiple accounts, and those accounts will
1183      *     have similar channels, you can create a group for each account with account specific
1184      *     labels instead of appending account information to each channel's label.
1185      * </p>
1186      *
1187      * @param group The group to create
1188      */
createNotificationChannelGroup(@onNull NotificationChannelGroup group)1189     public void createNotificationChannelGroup(@NonNull NotificationChannelGroup group) {
1190         createNotificationChannelGroups(Arrays.asList(group));
1191     }
1192 
1193     /**
1194      * Creates multiple notification channel groups.
1195      *
1196      * @param groups The list of groups to create
1197      */
createNotificationChannelGroups(@onNull List<NotificationChannelGroup> groups)1198     public void createNotificationChannelGroups(@NonNull List<NotificationChannelGroup> groups) {
1199         INotificationManager service = service();
1200         try {
1201             service.createNotificationChannelGroups(mContext.getPackageName(),
1202                     new ParceledListSlice(groups));
1203         } catch (RemoteException e) {
1204             throw e.rethrowFromSystemServer();
1205         }
1206     }
1207 
1208     /**
1209      * Creates a notification channel that notifications can be posted to.
1210      *
1211      * This can also be used to restore a deleted channel and to update an existing channel's
1212      * name, description, group, and/or importance.
1213      *
1214      * <p>The name and description should only be changed if the locale changes
1215      * or in response to the user renaming this channel. For example, if a user has a channel
1216      * named 'Messages' and the user changes their locale, this channel's name should be updated
1217      * with the translation of 'Messages' in the new locale.
1218      *
1219      * <p>The importance of an existing channel will only be changed if the new importance is lower
1220      * than the current value and the user has not altered any settings on this channel.
1221      *
1222      * <p>The group an existing channel will only be changed if the channel does not already
1223      * belong to a group.
1224      *
1225      * All other fields are ignored for channels that already exist.
1226      *
1227      * @param channel  the channel to create.  Note that the created channel may differ from this
1228      *                 value. If the provided channel is malformed, a RemoteException will be
1229      *                 thrown.
1230      */
createNotificationChannel(@onNull NotificationChannel channel)1231     public void createNotificationChannel(@NonNull NotificationChannel channel) {
1232         createNotificationChannels(Arrays.asList(channel));
1233     }
1234 
1235     /**
1236      * Creates multiple notification channels that different notifications can be posted to. See
1237      * {@link #createNotificationChannel(NotificationChannel)}.
1238      *
1239      * @param channels the list of channels to attempt to create.
1240      */
createNotificationChannels(@onNull List<NotificationChannel> channels)1241     public void createNotificationChannels(@NonNull List<NotificationChannel> channels) {
1242         INotificationManager service = service();
1243         try {
1244             service.createNotificationChannels(mContext.getPackageName(),
1245                     new ParceledListSlice(channels));
1246         } catch (RemoteException e) {
1247             throw e.rethrowFromSystemServer();
1248         }
1249     }
1250 
1251     /**
1252      * Returns the notification channel settings for a given channel id.
1253      *
1254      * <p>The channel must belong to your package, or to a package you are an approved notification
1255      * delegate for (see {@link #canNotifyAsPackage(String)}), or it will not be returned. To query
1256      * a channel as a notification delegate, call this method from a context created for that
1257      * package (see {@link Context#createPackageContext(String, int)}).</p>
1258      */
getNotificationChannel(String channelId)1259     public NotificationChannel getNotificationChannel(String channelId) {
1260         if (Flags.nmBinderPerfCacheChannels()) {
1261             return getChannelFromList(channelId,
1262                     mNotificationChannelListCache.query(new NotificationChannelQuery(
1263                             mContext.getOpPackageName(),
1264                             mContext.getPackageName(),
1265                             mContext.getUserId())));
1266         } else {
1267             INotificationManager service = service();
1268             try {
1269                 return service.getNotificationChannel(mContext.getOpPackageName(),
1270                         mContext.getUserId(), mContext.getPackageName(), channelId);
1271             } catch (RemoteException e) {
1272                 throw e.rethrowFromSystemServer();
1273             }
1274         }
1275     }
1276 
1277     /**
1278      * Returns the notification channel settings for a given channel and
1279      * {@link ShortcutInfo#getId() conversation id}.
1280      *
1281      * <p>The channel must belong to your package, or to a package you are an approved notification
1282      * delegate for (see {@link #canNotifyAsPackage(String)}), or it will not be returned. To query
1283      * a channel as a notification delegate, call this method from a context created for that
1284      * package (see {@link Context#createPackageContext(String, int)}).</p>
1285      *
1286      * <p>If a conversation channel with the given conversation id is not found, this method will
1287      * instead return the parent channel with the given channel ID, or {@code null} if neither
1288      * exists.</p>
1289      */
getNotificationChannel(@onNull String channelId, @NonNull String conversationId)1290     public @Nullable NotificationChannel getNotificationChannel(@NonNull String channelId,
1291             @NonNull String conversationId) {
1292         if (Flags.nmBinderPerfCacheChannels()) {
1293             return getConversationChannelFromList(channelId, conversationId,
1294                     mNotificationChannelListCache.query(new NotificationChannelQuery(
1295                             mContext.getOpPackageName(),
1296                             mContext.getPackageName(),
1297                             mContext.getUserId())));
1298         } else {
1299             INotificationManager service = service();
1300             try {
1301                 return service.getConversationNotificationChannel(mContext.getOpPackageName(),
1302                         mContext.getUserId(), mContext.getPackageName(), channelId, true,
1303                         conversationId);
1304             } catch (RemoteException e) {
1305                 throw e.rethrowFromSystemServer();
1306             }
1307         }
1308     }
1309 
1310     /**
1311      * Returns all notification channels belonging to the calling package.
1312      *
1313      * <p>Approved notification delegates (see {@link #canNotifyAsPackage(String)}) can query
1314      * notification channels belonging to packages they are the delegate for. To do so, call this
1315      * method from a context created for that package (see
1316      * {@link Context#createPackageContext(String, int)}).</p>
1317      */
getNotificationChannels()1318     public List<NotificationChannel> getNotificationChannels() {
1319         if (Flags.nmBinderPerfCacheChannels()) {
1320             List<NotificationChannel> channelList = mNotificationChannelListCache.query(
1321                     new NotificationChannelQuery(mContext.getOpPackageName(),
1322                             mContext.getPackageName(), mContext.getUserId()));
1323             List<NotificationChannel> out = new ArrayList();
1324             if (channelList != null) {
1325                 for (NotificationChannel c : channelList) {
1326                     out.add(c.copy());
1327                 }
1328             }
1329             return out;
1330         } else {
1331             INotificationManager service = service();
1332             try {
1333                 return service.getNotificationChannels(mContext.getOpPackageName(),
1334                         mContext.getPackageName(), mContext.getUserId()).getList();
1335             } catch (RemoteException e) {
1336                 throw e.rethrowFromSystemServer();
1337             }
1338         }
1339     }
1340 
1341     // channel list assumed to be associated with the appropriate package & user id already.
getChannelFromList(String channelId, List<NotificationChannel> channels)1342     private static NotificationChannel getChannelFromList(String channelId,
1343             List<NotificationChannel> channels) {
1344         if (channels == null) {
1345             return null;
1346         }
1347         if (channelId == null) {
1348             channelId = DEFAULT_CHANNEL_ID;
1349         }
1350         for (NotificationChannel channel : channels) {
1351             if (channelId.equals(channel.getId())) {
1352                 return channel.copy();
1353             }
1354         }
1355         return null;
1356     }
1357 
getConversationChannelFromList(String channelId, String conversationId, List<NotificationChannel> channels)1358     private static NotificationChannel getConversationChannelFromList(String channelId,
1359             String conversationId, List<NotificationChannel> channels) {
1360         if (channels == null) {
1361             return null;
1362         }
1363         if (channelId == null) {
1364             channelId = DEFAULT_CHANNEL_ID;
1365         }
1366         if (conversationId == null) {
1367             return getChannelFromList(channelId, channels);
1368         }
1369         NotificationChannel parent = null;
1370         for (NotificationChannel channel : channels) {
1371             if (conversationId.equals(channel.getConversationId())
1372                     && channelId.equals(channel.getParentChannelId())) {
1373                 return channel.copy();
1374             } else if (channelId.equals(channel.getId())) {
1375                 parent = channel;
1376             }
1377         }
1378         return parent != null ? parent.copy() : null;
1379     }
1380 
1381     /**
1382      * Deletes the given notification channel.
1383      *
1384      * <p>If you {@link #createNotificationChannel(NotificationChannel) create} a new channel with
1385      * this same id, the deleted channel will be un-deleted with all of the same settings it
1386      * had before it was deleted.
1387      */
deleteNotificationChannel(String channelId)1388     public void deleteNotificationChannel(String channelId) {
1389         if (notificationClassification()
1390                 && NotificationChannel.SYSTEM_RESERVED_IDS.contains(channelId)) {
1391             return;
1392         }
1393         INotificationManager service = service();
1394         try {
1395             service.deleteNotificationChannel(mContext.getPackageName(), channelId);
1396         } catch (RemoteException e) {
1397             throw e.rethrowFromSystemServer();
1398         }
1399     }
1400 
1401     /**
1402      * Returns the notification channel group settings for a given channel group id.
1403      *
1404      * The channel group must belong to your package, or null will be returned.
1405      */
getNotificationChannelGroup(String channelGroupId)1406     public NotificationChannelGroup getNotificationChannelGroup(String channelGroupId) {
1407         if (Flags.nmBinderPerfCacheChannels()) {
1408             String pkgName = mContext.getPackageName();
1409             // getNotificationChannelGroup may only be called by the same package.
1410             List<NotificationChannel> channelList = mNotificationChannelListCache.query(
1411                     new NotificationChannelQuery(pkgName, pkgName, mContext.getUserId()));
1412             Map<String, NotificationChannelGroup> groupHeaders =
1413                     mNotificationChannelGroupsCache.query(pkgName);
1414             NotificationChannelGroup ncg = NotificationChannelGroupsHelper.getGroupWithChannels(
1415                     channelGroupId, channelList, groupHeaders, /* includeDeleted= */ false);
1416             return ncg != null ? ncg.clone() : null;
1417         } else {
1418             INotificationManager service = service();
1419             try {
1420                 return service.getNotificationChannelGroup(mContext.getPackageName(),
1421                         channelGroupId);
1422             } catch (RemoteException e) {
1423                 throw e.rethrowFromSystemServer();
1424             }
1425         }
1426     }
1427 
1428     /**
1429      * Returns all notification channel groups belonging to the calling app.
1430      */
getNotificationChannelGroups()1431     public List<NotificationChannelGroup> getNotificationChannelGroups() {
1432         if (Flags.nmBinderPerfCacheChannels()) {
1433             String pkgName = mContext.getPackageName();
1434             List<NotificationChannel> channelList = mNotificationChannelListCache.query(
1435                     new NotificationChannelQuery(pkgName, pkgName, mContext.getUserId()));
1436             Map<String, NotificationChannelGroup> groupHeaders =
1437                     mNotificationChannelGroupsCache.query(pkgName);
1438             List<NotificationChannelGroup> populatedGroupList =
1439                     NotificationChannelGroupsHelper.getGroupsWithChannels(channelList, groupHeaders,
1440                             NotificationChannelGroupsHelper.Params.forAllGroups());
1441             List<NotificationChannelGroup> out = new ArrayList<>();
1442             for (NotificationChannelGroup g : populatedGroupList) {
1443                 out.add(g.clone());
1444             }
1445             return out;
1446         } else {
1447             INotificationManager service = service();
1448             try {
1449                 final ParceledListSlice<NotificationChannelGroup> parceledList =
1450                         service.getNotificationChannelGroups(mContext.getPackageName());
1451                 if (parceledList != null) {
1452                     return parceledList.getList();
1453                 }
1454             } catch (RemoteException e) {
1455                 throw e.rethrowFromSystemServer();
1456             }
1457             return new ArrayList<>();
1458         }
1459     }
1460 
1461     /**
1462      * Deletes the given notification channel group, and all notification channels that
1463      * belong to it.
1464      */
deleteNotificationChannelGroup(String groupId)1465     public void deleteNotificationChannelGroup(String groupId) {
1466         INotificationManager service = service();
1467         try {
1468             service.deleteNotificationChannelGroup(mContext.getPackageName(), groupId);
1469         } catch (RemoteException e) {
1470             throw e.rethrowFromSystemServer();
1471         }
1472     }
1473 
1474     /**
1475      * @hide
1476      */
1477     @TestApi
updateNotificationChannel(@onNull String pkg, int uid, @NonNull NotificationChannel channel)1478     public void updateNotificationChannel(@NonNull String pkg, int uid,
1479             @NonNull NotificationChannel channel) {
1480         INotificationManager service = service();
1481         try {
1482             service.updateNotificationChannelForPackage(pkg, uid, channel);
1483         } catch (RemoteException e) {
1484             throw e.rethrowFromSystemServer();
1485         }
1486     }
1487 
1488     private static final String NOTIFICATION_CHANNELS_CACHE_API = "getNotificationChannels";
1489     private static final int NOTIFICATION_CHANNELS_CACHE_SIZE = 10;
1490     private static final String NOTIFICATION_CHANNEL_GROUPS_CACHE_API =
1491             "getNotificationChannelGroups";
1492     private static final int NOTIFICATION_CHANNEL_GROUPS_CACHE_SIZE = 10;
1493 
1494     private final IpcDataCache.QueryHandler<NotificationChannelQuery, List<NotificationChannel>>
1495             mNotificationChannelListQueryHandler = new IpcDataCache.QueryHandler<>() {
1496                 @Override
1497                 public List<NotificationChannel> apply(NotificationChannelQuery query) {
1498                     INotificationManager service = service();
1499                     try {
1500                         return service.getNotificationChannels(query.callingPkg,
1501                                 query.targetPkg, query.userId).getList();
1502                     } catch (RemoteException e) {
1503                         throw e.rethrowFromSystemServer();
1504                     }
1505                 }
1506 
1507                 @Override
1508                 public boolean shouldBypassCache(@NonNull NotificationChannelQuery query) {
1509                     // Other locations should also not be querying the cache in the first place if
1510                     // the flag is not enabled, but this is an extra precaution.
1511                     if (!Flags.nmBinderPerfCacheChannels()) {
1512                         Log.wtf(TAG,
1513                                 "shouldBypassCache called when nm_binder_perf_cache_channels off");
1514                         return true;
1515                     }
1516                     return false;
1517                 }
1518             };
1519 
1520     private final IpcDataCache<NotificationChannelQuery, List<NotificationChannel>>
1521             mNotificationChannelListCache =
1522             new IpcDataCache<>(NOTIFICATION_CHANNELS_CACHE_SIZE, IpcDataCache.MODULE_SYSTEM,
1523                     NOTIFICATION_CHANNELS_CACHE_API, NOTIFICATION_CHANNELS_CACHE_API,
1524                     mNotificationChannelListQueryHandler);
1525 
NotificationChannelQuery( String callingPkg, String targetPkg, int userId)1526     private record NotificationChannelQuery(
1527             String callingPkg,
1528             String targetPkg,
1529             int userId) {}
1530 
1531     private final IpcDataCache.QueryHandler<String, Map<String, NotificationChannelGroup>>
1532             mNotificationChannelGroupsQueryHandler = new IpcDataCache.QueryHandler<>() {
1533                 @Override
1534                 public Map<String, NotificationChannelGroup> apply(String pkg) {
1535                     INotificationManager service = service();
1536                     Map<String, NotificationChannelGroup> groups = new ArrayMap<>();
1537                     try {
1538                         final ParceledListSlice<NotificationChannelGroup> parceledList =
1539                                 service.getNotificationChannelGroupsWithoutChannels(pkg);
1540                         if (parceledList != null) {
1541                             for (NotificationChannelGroup group : parceledList.getList()) {
1542                                 groups.put(group.getId(), group);
1543                             }
1544                         }
1545                     } catch (RemoteException e) {
1546                         throw e.rethrowFromSystemServer();
1547                     }
1548                     return groups;
1549                 }
1550 
1551                 @Override
1552                 public boolean shouldBypassCache(@NonNull String query) {
1553                     // Other locations should also not be querying the cache in the first place if
1554                     // the flag is not enabled, but this is an extra precaution.
1555                     if (!Flags.nmBinderPerfCacheChannels()) {
1556                         Log.wtf(TAG,
1557                                 "shouldBypassCache called when nm_binder_perf_cache_channels off");
1558                         return true;
1559                     }
1560                     return false;
1561                 }
1562             };
1563 
1564     private final IpcDataCache<String, Map<String, NotificationChannelGroup>>
1565             mNotificationChannelGroupsCache = new IpcDataCache<>(
1566             NOTIFICATION_CHANNEL_GROUPS_CACHE_SIZE, IpcDataCache.MODULE_SYSTEM,
1567             NOTIFICATION_CHANNEL_GROUPS_CACHE_API, NOTIFICATION_CHANNEL_GROUPS_CACHE_API,
1568             mNotificationChannelGroupsQueryHandler);
1569 
1570     /**
1571      * @hide
1572      */
invalidateNotificationChannelCache()1573     public static void invalidateNotificationChannelCache() {
1574         if (Flags.nmBinderPerfCacheChannels()) {
1575             IpcDataCache.invalidateCache(IpcDataCache.MODULE_SYSTEM,
1576                     NOTIFICATION_CHANNELS_CACHE_API);
1577         } else {
1578             // if we are here, we have failed to flag something
1579             Log.wtf(TAG, "invalidateNotificationChannelCache called without flag");
1580         }
1581     }
1582 
1583     /**
1584      * @hide
1585      */
invalidateNotificationChannelGroupCache()1586     public static void invalidateNotificationChannelGroupCache() {
1587         if (Flags.nmBinderPerfCacheChannels()) {
1588             IpcDataCache.invalidateCache(IpcDataCache.MODULE_SYSTEM,
1589                     NOTIFICATION_CHANNEL_GROUPS_CACHE_API);
1590         } else {
1591             // if we are here, we have failed to flag something
1592             Log.wtf(TAG, "invalidateNotificationChannelGroupCache called without flag");
1593         }
1594     }
1595 
1596     /**
1597      * For testing only: running tests with a cache requires marking the cache's property for
1598      * testing, as test APIs otherwise cannot invalidate the cache. This must be called after
1599      * calling PropertyInvalidatedCache.setTestMode(true).
1600      * @hide
1601      */
1602     @VisibleForTesting
setChannelCachesToTestMode()1603     public void setChannelCachesToTestMode() {
1604         mNotificationChannelListCache.testPropertyName();
1605         mNotificationChannelGroupsCache.testPropertyName();
1606     }
1607 
1608     /**
1609      * @hide
1610      */
1611     @TestApi
getEffectsSuppressor()1612     public ComponentName getEffectsSuppressor() {
1613         INotificationManager service = service();
1614         try {
1615             return service.getEffectsSuppressor();
1616         } catch (RemoteException e) {
1617             throw e.rethrowFromSystemServer();
1618         }
1619     }
1620 
1621     /**
1622      * @hide
1623      */
matchesCallFilter(Bundle extras)1624     public boolean matchesCallFilter(Bundle extras) {
1625         INotificationManager service = service();
1626         try {
1627             return service.matchesCallFilter(extras);
1628         } catch (RemoteException e) {
1629             throw e.rethrowFromSystemServer();
1630         }
1631     }
1632 
1633     /**
1634      * @hide
1635      */
1636     @TestApi
cleanUpCallersAfter(long timeThreshold)1637     public void cleanUpCallersAfter(long timeThreshold) {
1638         INotificationManager service = service();
1639         try {
1640             service.cleanUpCallersAfter(timeThreshold);
1641         } catch (RemoteException e) {
1642             throw e.rethrowFromSystemServer();
1643         }
1644     }
1645 
1646     /**
1647      * @hide
1648      */
isSystemConditionProviderEnabled(String path)1649     public boolean isSystemConditionProviderEnabled(String path) {
1650         INotificationManager service = service();
1651         try {
1652             return service.isSystemConditionProviderEnabled(path);
1653         } catch (RemoteException e) {
1654             throw e.rethrowFromSystemServer();
1655         }
1656     }
1657 
1658     /**
1659      * @hide
1660      */
1661     @UnsupportedAppUsage
setZenMode(int mode, Uri conditionId, String reason)1662     public void setZenMode(int mode, Uri conditionId, String reason) {
1663         setZenMode(mode, conditionId, reason, /* fromUser= */ false);
1664     }
1665 
1666     /** @hide */
setZenMode(int mode, Uri conditionId, String reason, boolean fromUser)1667     public void setZenMode(int mode, Uri conditionId, String reason, boolean fromUser) {
1668         INotificationManager service = service();
1669         try {
1670             service.setZenMode(mode, conditionId, reason, fromUser);
1671         } catch (RemoteException e) {
1672             throw e.rethrowFromSystemServer();
1673         }
1674     }
1675 
1676 
1677     /**
1678      * @hide
1679      */
getZenMode()1680     public int getZenMode() {
1681         INotificationManager service = service();
1682         try {
1683             return service.getZenMode();
1684         } catch (RemoteException e) {
1685             throw e.rethrowFromSystemServer();
1686         }
1687     }
1688 
1689     /**
1690      * @hide
1691      */
1692     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
getZenModeConfig()1693     public ZenModeConfig getZenModeConfig() {
1694         INotificationManager service = service();
1695         try {
1696             return service.getZenModeConfig();
1697         } catch (RemoteException e) {
1698             throw e.rethrowFromSystemServer();
1699         }
1700     }
1701 
1702     /**
1703      * Returns the currently applied notification policy.
1704      *
1705      * <p>
1706      * If {@link #getCurrentInterruptionFilter} is equal to {@link #INTERRUPTION_FILTER_ALL},
1707      * then the consolidated notification policy will match the default notification policy
1708      * returned by {@link #getNotificationPolicy}.
1709      * </p>
1710      */
getConsolidatedNotificationPolicy()1711     public @NonNull NotificationManager.Policy getConsolidatedNotificationPolicy() {
1712         INotificationManager service = service();
1713         try {
1714             return service.getConsolidatedNotificationPolicy();
1715         } catch (RemoteException e) {
1716             throw e.rethrowFromSystemServer();
1717         }
1718     }
1719 
1720     /**
1721      * @hide
1722      */
getRuleInstanceCount(ComponentName owner)1723     public int getRuleInstanceCount(ComponentName owner) {
1724         INotificationManager service = service();
1725         try {
1726             return service.getRuleInstanceCount(owner);
1727         } catch (RemoteException e) {
1728             throw e.rethrowFromSystemServer();
1729         }
1730     }
1731 
1732     /**
1733      * Returns true if users can independently and fully manage {@link AutomaticZenRule} rules. This
1734      * includes the ability to independently activate/deactivate rules and overwrite/freeze the
1735      * behavior (policy) of the rule when activated.
1736      * <p>
1737      * If this method returns true, calls to
1738      * {@link #updateAutomaticZenRule(String, AutomaticZenRule)} may fail and apps should defer
1739      * rule management to system settings/uis via
1740      * {@link Settings#ACTION_AUTOMATIC_ZEN_RULE_SETTINGS}.
1741      */
areAutomaticZenRulesUserManaged()1742     public boolean areAutomaticZenRulesUserManaged() {
1743         if (Flags.modesUi()) {
1744             PackageManager pm = mContext.getPackageManager();
1745             return !pm.hasSystemFeature(PackageManager.FEATURE_WATCH)
1746                     && !pm.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)
1747                     && !pm.hasSystemFeature(PackageManager.FEATURE_LEANBACK);
1748         } else {
1749             return false;
1750         }
1751     }
1752 
1753     /**
1754      * Returns AutomaticZenRules owned by the caller.
1755      *
1756      * <p>
1757      * Throws a SecurityException if policy access is not granted to this package.
1758      * See {@link #isNotificationPolicyAccessGranted}.
1759      */
getAutomaticZenRules()1760     public Map<String, AutomaticZenRule> getAutomaticZenRules() {
1761         INotificationManager service = service();
1762         try {
1763             Map<String, AutomaticZenRule> result = new HashMap<>();
1764             ParceledListSlice<AutomaticZenRule.AzrWithId> parceledRules =
1765                     service.getAutomaticZenRules();
1766             if (parceledRules != null) {
1767                 for (AutomaticZenRule.AzrWithId rule : parceledRules.getList()) {
1768                     result.put(rule.mId, rule.mRule);
1769                 }
1770             }
1771             return result;
1772         } catch (RemoteException e) {
1773             throw e.rethrowFromSystemServer();
1774         }
1775     }
1776 
1777     /**
1778      * Returns the AutomaticZenRule with the given id, if it exists and the caller has access.
1779      *
1780      * <p>
1781      * Throws a SecurityException if policy access is not granted to this package.
1782      * See {@link #isNotificationPolicyAccessGranted}.
1783      *
1784      * <p>
1785      * Returns null if there are no zen rules that match the given id, or if the calling package
1786      * doesn't own the matching rule. See {@link AutomaticZenRule#getOwner}.
1787      */
getAutomaticZenRule(String id)1788     public AutomaticZenRule getAutomaticZenRule(String id) {
1789         INotificationManager service = service();
1790         try {
1791             return service.getAutomaticZenRule(id);
1792         } catch (RemoteException e) {
1793             throw e.rethrowFromSystemServer();
1794         }
1795     }
1796 
1797     /**
1798      * Creates the given zen rule.
1799      *
1800      * <p>
1801      * Throws a SecurityException if policy access is not granted to this package.
1802      * See {@link #isNotificationPolicyAccessGranted}.
1803      *
1804      * @param automaticZenRule the rule to create.
1805      * @return The id of the newly created rule; null if the rule could not be created.
1806      */
addAutomaticZenRule(AutomaticZenRule automaticZenRule)1807     public String addAutomaticZenRule(AutomaticZenRule automaticZenRule) {
1808         return addAutomaticZenRule(automaticZenRule, /* fromUser= */ false);
1809     }
1810 
1811     /** @hide */
1812     @TestApi
1813     @NonNull
addAutomaticZenRule(@onNull AutomaticZenRule automaticZenRule, boolean fromUser)1814     public String addAutomaticZenRule(@NonNull AutomaticZenRule automaticZenRule,
1815             boolean fromUser) {
1816         INotificationManager service = service();
1817         try {
1818             return service.addAutomaticZenRule(automaticZenRule,
1819                     mContext.getPackageName(), fromUser);
1820         } catch (RemoteException e) {
1821             throw e.rethrowFromSystemServer();
1822         }
1823     }
1824 
1825     /**
1826      * Updates the given zen rule.
1827      *
1828      * <p>Before {@link Build.VERSION_CODES#VANILLA_ICE_CREAM}, updating a rule that is not backed
1829      * up by a {@link android.service.notification.ConditionProviderService} will deactivate it if
1830      * it was previously active. Starting with {@link Build.VERSION_CODES#VANILLA_ICE_CREAM}, this
1831      * will only happen if the rule's definition is actually changing.
1832      *
1833      * <p>Throws a SecurityException if policy access is not granted to this package.
1834      * See {@link #isNotificationPolicyAccessGranted}.
1835      *
1836      * <p>Callers can only update rules that they own. See {@link AutomaticZenRule#getOwner}.
1837      *
1838      * @param id The id of the rule to update
1839      * @param automaticZenRule the rule to update.
1840      * @return Whether the rule was successfully updated.
1841      */
updateAutomaticZenRule(String id, AutomaticZenRule automaticZenRule)1842     public boolean updateAutomaticZenRule(String id, AutomaticZenRule automaticZenRule) {
1843         return updateAutomaticZenRule(id, automaticZenRule, /* fromUser= */ false);
1844     }
1845 
1846     /** @hide */
1847     @TestApi
updateAutomaticZenRule(@onNull String id, @NonNull AutomaticZenRule automaticZenRule, boolean fromUser)1848     public boolean updateAutomaticZenRule(@NonNull String id,
1849             @NonNull AutomaticZenRule automaticZenRule, boolean fromUser) {
1850         INotificationManager service = service();
1851         try {
1852             return service.updateAutomaticZenRule(id, automaticZenRule, fromUser);
1853         } catch (RemoteException e) {
1854             throw e.rethrowFromSystemServer();
1855         }
1856     }
1857 
1858     /**
1859      * Returns the current activation state of an {@link AutomaticZenRule}.
1860      *
1861      * <p>Returns {@link Condition#STATE_UNKNOWN} if the rule does not exist or the calling
1862      * package doesn't have access to it.
1863      *
1864      * @param id The id of the rule
1865      * @return the state of the rule.
1866      */
1867     @Condition.State
getAutomaticZenRuleState(@onNull String id)1868     public int getAutomaticZenRuleState(@NonNull String id) {
1869         INotificationManager service = service();
1870         try {
1871             return service.getAutomaticZenRuleState(id);
1872         } catch (RemoteException e) {
1873             throw e.rethrowFromSystemServer();
1874         }
1875     }
1876 
1877     /**
1878      * Informs the notification manager that the state of an {@link AutomaticZenRule} has changed.
1879      * Use this method to put the system into Do Not Disturb mode or request that it exits Do Not
1880      * Disturb mode. The calling app must own the provided {@link android.app.AutomaticZenRule}.
1881      *
1882      * <p>This method can be used in conjunction with or as a replacement to
1883      * {@link android.service.notification.ConditionProviderService#notifyCondition(Condition)}.
1884      *
1885      * <p>The condition change may be ignored if the user has activated or deactivated the rule
1886      * manually -- the user can "override" the rule <em>this time</em>, with the rule resuming its
1887      * normal operation for the next cycle. When this has happened, the supplied condition will be
1888      * applied only once the automatic state is in agreement with the user-provided state. For
1889      * example, assume that the {@link AutomaticZenRule} corresponds to a "Driving Mode" with
1890      * automatic driving detection.
1891      *
1892      * <ol>
1893      *     <li>App detects driving and notifies the system that the rule should be active, calling
1894      *     this method with a {@link Condition} with {@link Condition#STATE_TRUE}).
1895      *     <li>User deactivates ("snoozes") the rule for some reason. This overrides the
1896      *     app-provided condition state.
1897      *     <li>App is still detecting driving, so again calls with {@link Condition#STATE_TRUE}.
1898      *     This is ignored by the system, as the user override prevails.
1899      *     <li>Some time later, the app detects that driving stopped, so the rule should be
1900      *     inactive, and calls with {@link Condition#STATE_FALSE}). This doesn't change the actual
1901      *     rule state (it was already inactive due to the user's override), but clears the override.
1902      *     <li>Some time later, the app detects that driving has started again, and notifies that
1903      *     the rule should be active (calling with {@link Condition#STATE_TRUE} again). The rule is
1904      *     activated.
1905      * </ol>
1906      *
1907      * <p>Note that the behavior at step #3 is different if the app also specifies
1908      * {@link Condition#SOURCE_USER_ACTION} as the {@link Condition#source} -- rule state updates
1909      * coming from user actions are not ignored.
1910      *
1911      * @param id The id of the rule whose state should change
1912      * @param condition The new state of this rule
1913      */
setAutomaticZenRuleState(@onNull String id, @NonNull Condition condition)1914     public void setAutomaticZenRuleState(@NonNull String id, @NonNull Condition condition) {
1915         INotificationManager service = service();
1916         try {
1917             service.setAutomaticZenRuleState(id, condition);
1918         } catch (RemoteException e) {
1919             throw e.rethrowFromSystemServer();
1920         }
1921     }
1922 
1923     /**
1924      * Deletes the automatic zen rule with the given id.
1925      *
1926      * <p>
1927      * Throws a SecurityException if policy access is not granted to this package.
1928      * See {@link #isNotificationPolicyAccessGranted}.
1929      *
1930      * <p>
1931      * Callers can only delete rules that they own. See {@link AutomaticZenRule#getOwner}.
1932      * @param id the id of the rule to delete.
1933      * @return Whether the rule was successfully deleted.
1934      */
removeAutomaticZenRule(String id)1935     public boolean removeAutomaticZenRule(String id) {
1936         return removeAutomaticZenRule(id, /* fromUser= */ false);
1937     }
1938 
1939     /** @hide */
1940     @TestApi
removeAutomaticZenRule(@onNull String id, boolean fromUser)1941     public boolean removeAutomaticZenRule(@NonNull String id, boolean fromUser) {
1942         INotificationManager service = service();
1943         try {
1944             return service.removeAutomaticZenRule(id, fromUser);
1945         } catch (RemoteException e) {
1946             throw e.rethrowFromSystemServer();
1947         }
1948     }
1949 
1950     /**
1951      * Deletes all automatic zen rules owned by the given package.
1952      *
1953      * @hide
1954      */
removeAutomaticZenRules(String packageName)1955     public boolean removeAutomaticZenRules(String packageName) {
1956         return removeAutomaticZenRules(packageName, /* fromUser= */ false);
1957     }
1958 
1959     /** @hide */
removeAutomaticZenRules(String packageName, boolean fromUser)1960     public boolean removeAutomaticZenRules(String packageName, boolean fromUser) {
1961         INotificationManager service = service();
1962         try {
1963             return service.removeAutomaticZenRules(packageName, fromUser);
1964         } catch (RemoteException e) {
1965             throw e.rethrowFromSystemServer();
1966         }
1967     }
1968 
1969     /**
1970      * Returns the user specified importance for notifications from the calling
1971      * package.
1972      */
getImportance()1973     public @Importance int getImportance() {
1974         INotificationManager service = service();
1975         try {
1976             return service.getPackageImportance(mContext.getPackageName());
1977         } catch (RemoteException e) {
1978             throw e.rethrowFromSystemServer();
1979         }
1980     }
1981 
1982     /**
1983      * Returns whether notifications from the calling package are enabled.
1984      */
areNotificationsEnabled()1985     public boolean areNotificationsEnabled() {
1986         if (Flags.nmBinderPerfPermissionCheck()) {
1987             return mContext.checkSelfPermission(POST_NOTIFICATIONS) == PERMISSION_GRANTED;
1988         } else {
1989             INotificationManager service = service();
1990             try {
1991                 return service.areNotificationsEnabled(mContext.getPackageName());
1992             } catch (RemoteException e) {
1993                 throw e.rethrowFromSystemServer();
1994             }
1995         }
1996     }
1997 
1998     /**
1999      * Gets whether all notifications posted by this app can appear outside of the
2000      * notification shade, floating over other apps' content.
2001      *
2002      * <p>This value will be ignored for notifications that are posted to channels that do not
2003      * allow bubbles ({@link NotificationChannel#canBubble()}).
2004      *
2005      * @see Notification#getBubbleMetadata()
2006      * @deprecated use {@link #getBubblePreference()} instead.
2007      */
2008     @Deprecated
areBubblesAllowed()2009     public boolean areBubblesAllowed() {
2010         INotificationManager service = service();
2011         try {
2012             return service.areBubblesAllowed(mContext.getPackageName());
2013         } catch (RemoteException e) {
2014             throw e.rethrowFromSystemServer();
2015         }
2016     }
2017 
2018     /**
2019      * Returns whether bubbles are enabled at the feature level for the current user. When enabled,
2020      * notifications able to bubble will display an affordance allowing the user to bubble them.
2021      *
2022      * @see Notification.Builder#setBubbleMetadata(Notification.BubbleMetadata)
2023      */
areBubblesEnabled()2024     public boolean areBubblesEnabled() {
2025         INotificationManager service = service();
2026         try {
2027             return service.areBubblesEnabled(mContext.getUser());
2028         } catch (RemoteException e) {
2029             throw e.rethrowFromSystemServer();
2030         }
2031     }
2032 
2033     /**
2034      * Gets the bubble preference for the app. This preference only applies to notifications that
2035      * have been properly configured to bubble.
2036      *
2037      * <p>
2038      * If {@link #BUBBLE_PREFERENCE_ALL}, then any bubble notification will appear as a bubble, as
2039      * long as the user hasn't excluded it ({@link NotificationChannel#canBubble()}).
2040      *
2041      * <p>
2042      * If {@link #BUBBLE_PREFERENCE_SELECTED}, then any bubble notification will appear as a bubble,
2043      * as long as the user has selected it.
2044      *
2045      * <p>
2046      * If {@link #BUBBLE_PREFERENCE_NONE}, then no notification may appear as a bubble from the app.
2047      *
2048      * @see Notification#getBubbleMetadata()
2049      * @return the users' bubble preference for the app.
2050      */
getBubblePreference()2051     public @BubblePreference int getBubblePreference() {
2052         INotificationManager service = service();
2053         try {
2054             return service.getBubblePreferenceForPackage(mContext.getPackageName(),
2055                     Binder.getCallingUid());
2056         } catch (RemoteException e) {
2057             throw e.rethrowFromSystemServer();
2058         }
2059     }
2060 
2061     /**
2062      * Silences the current notification sound, if ones currently playing.
2063      * <p>
2064      * It is intended to handle use-cases such as silencing a ringing call
2065      * when the user presses the volume button during ringing.
2066      * <p>
2067      * If this method is called prior to when the notification begins playing, the sound will not be
2068      * silenced.  As such it is not intended as a means to avoid playing of a sound.
2069      * @hide
2070      */
silenceNotificationSound()2071     public void silenceNotificationSound() {
2072         INotificationManager service = service();
2073         try {
2074             service.silenceNotificationSound();
2075         } catch (RemoteException e) {
2076             throw e.rethrowFromSystemServer();
2077         }
2078     }
2079 
2080     /**
2081      * Returns whether notifications from this package are temporarily hidden. This
2082      * could be done because the package was marked as distracting to the user via
2083      * {@code PackageManager#setDistractingPackageRestrictions(String[], int)} or because the
2084      * package is {@code PackageManager#setPackagesSuspended(String[], boolean, PersistableBundle,
2085      * PersistableBundle, SuspendDialogInfo) suspended}.
2086      */
areNotificationsPaused()2087     public boolean areNotificationsPaused() {
2088         INotificationManager service = service();
2089         try {
2090             return service.isPackagePaused(mContext.getPackageName());
2091         } catch (RemoteException e) {
2092             throw e.rethrowFromSystemServer();
2093         }
2094     }
2095 
2096     /**
2097      * Checks the ability to modify Notification Policy for the calling package.
2098      *
2099      * <p>
2100      * Returns true if the calling package can modify notification policy.
2101      *
2102      * <p>
2103      * Apps can request policy access by sending the user to the activity that matches the system
2104      * intent action {@link android.provider.Settings#ACTION_NOTIFICATION_POLICY_ACCESS_SETTINGS}.
2105      *
2106      * <p>
2107      * Use {@link #ACTION_NOTIFICATION_POLICY_ACCESS_GRANTED_CHANGED} to listen for
2108      * user grant or denial of this access.
2109      */
isNotificationPolicyAccessGranted()2110     public boolean isNotificationPolicyAccessGranted() {
2111         INotificationManager service = service();
2112         try {
2113             return service.isNotificationPolicyAccessGranted(mContext.getOpPackageName());
2114         } catch (RemoteException e) {
2115             throw e.rethrowFromSystemServer();
2116         }
2117     }
2118 
2119     /**
2120      * Checks whether the user has approved a given
2121      * {@link android.service.notification.NotificationListenerService}.
2122      *
2123      * <p>
2124      * The listener service must belong to the calling app.
2125      *
2126      * <p>
2127      * Apps can request notification listener access by sending the user to the activity that
2128      * matches the system intent action
2129      * {@link android.provider.Settings#ACTION_NOTIFICATION_LISTENER_SETTINGS}.
2130      */
isNotificationListenerAccessGranted(ComponentName listener)2131     public boolean isNotificationListenerAccessGranted(ComponentName listener) {
2132         INotificationManager service = service();
2133         try {
2134             return service.isNotificationListenerAccessGranted(listener);
2135         } catch (RemoteException e) {
2136             throw e.rethrowFromSystemServer();
2137         }
2138     }
2139 
2140     /**
2141      * Checks whether the user has approved a given
2142      * {@link android.service.notification.NotificationAssistantService}.
2143      *
2144      * <p>
2145      * The assistant service must belong to the calling app.
2146      *
2147      * <p>
2148      * Apps can request notification assistant access by sending the user to the activity that
2149      * matches the system intent action
2150      * TODO: STOPSHIP: Add correct intent
2151      * {@link android.provider.Settings#ACTION_MANAGE_DEFAULT_APPS_SETTINGS}.
2152      * @hide
2153      */
2154     @SystemApi
isNotificationAssistantAccessGranted(@onNull ComponentName assistant)2155     public boolean isNotificationAssistantAccessGranted(@NonNull ComponentName assistant) {
2156         INotificationManager service = service();
2157         try {
2158             return service.isNotificationAssistantAccessGranted(assistant);
2159         } catch (RemoteException e) {
2160             throw e.rethrowFromSystemServer();
2161         }
2162     }
2163 
2164     /**
2165      * Returns whether the user wants silent notifications (see {@link #IMPORTANCE_LOW} to appear
2166      * in the status bar.
2167      *
2168      * <p>Only available for {@link #isNotificationListenerAccessGranted(ComponentName) notification
2169      * listeners}.
2170      */
shouldHideSilentStatusBarIcons()2171     public boolean shouldHideSilentStatusBarIcons() {
2172         INotificationManager service = service();
2173         try {
2174             return service.shouldHideSilentStatusIcons(mContext.getOpPackageName());
2175         } catch (RemoteException e) {
2176             throw e.rethrowFromSystemServer();
2177         }
2178     }
2179 
2180     /**
2181      * Returns the list of {@link android.service.notification.Adjustment adjustment keys} that can
2182      * be modified by the current {@link android.service.notification.NotificationAssistantService}.
2183      *
2184      * <p>Only callable by the current
2185      * {@link android.service.notification.NotificationAssistantService}.
2186      * See {@link #isNotificationAssistantAccessGranted(ComponentName)}</p>
2187      * @hide
2188      */
2189     @SystemApi
getAllowedAssistantAdjustments()2190     public @NonNull @Adjustment.Keys List<String> getAllowedAssistantAdjustments() {
2191         INotificationManager service = service();
2192         try {
2193             return service.getAllowedAssistantAdjustments(mContext.getOpPackageName());
2194         } catch (RemoteException e) {
2195             throw e.rethrowFromSystemServer();
2196         }
2197     }
2198 
2199     /**
2200      * @hide
2201      */
2202     @TestApi
2203     @FlaggedApi(android.service.notification.Flags.FLAG_NOTIFICATION_CLASSIFICATION)
allowAssistantAdjustment(@onNull String capability)2204     public void allowAssistantAdjustment(@NonNull String capability) {
2205         INotificationManager service = service();
2206         try {
2207             service.allowAssistantAdjustment(capability);
2208         } catch (RemoteException e) {
2209             throw e.rethrowFromSystemServer();
2210         }
2211     }
2212 
2213     /**
2214      * @hide
2215      */
2216     @TestApi
2217     @FlaggedApi(android.service.notification.Flags.FLAG_NOTIFICATION_CLASSIFICATION)
disallowAssistantAdjustment(@onNull String capability)2218     public void disallowAssistantAdjustment(@NonNull String capability) {
2219         INotificationManager service = service();
2220         try {
2221             service.disallowAssistantAdjustment(capability);
2222         } catch (RemoteException e) {
2223             throw e.rethrowFromSystemServer();
2224         }
2225     }
2226 
2227     /** @hide */
2228     @TestApi
isNotificationPolicyAccessGrantedForPackage(@onNull String pkg)2229     public boolean isNotificationPolicyAccessGrantedForPackage(@NonNull String pkg) {
2230         INotificationManager service = service();
2231         try {
2232             return service.isNotificationPolicyAccessGrantedForPackage(pkg);
2233         } catch (RemoteException e) {
2234             throw e.rethrowFromSystemServer();
2235         }
2236     }
2237 
2238     /**
2239      * @hide
2240      */
2241     @TestApi
2242     @FlaggedApi(android.service.notification.Flags.FLAG_NOTIFICATION_CLASSIFICATION)
setAssistantAdjustmentKeyTypeState(@djustment.Types int type, boolean enabled)2243     public void setAssistantAdjustmentKeyTypeState(@Adjustment.Types int type, boolean enabled) {
2244         INotificationManager service = service();
2245         try {
2246             service.setAssistantAdjustmentKeyTypeState(type, enabled);
2247         } catch (RemoteException e) {
2248             throw e.rethrowFromSystemServer();
2249         }
2250     }
2251 
2252     /**
2253      * @hide
2254      */
getEnabledNotificationListenerPackages()2255     public List<String> getEnabledNotificationListenerPackages() {
2256         INotificationManager service = service();
2257         try {
2258             return service.getEnabledNotificationListenerPackages();
2259         } catch (RemoteException e) {
2260             throw e.rethrowFromSystemServer();
2261         }
2262     }
2263 
2264     /**
2265      * Gets the current user-specified default notification policy.
2266      *
2267      * <p>For apps targeting {@link Build.VERSION_CODES#VANILLA_ICE_CREAM} and above (with some
2268      * exceptions, such as companion device managers) this method will return the policy associated
2269      * to their implicit {@link AutomaticZenRule} instead, if it exists. See
2270      * {@link #setNotificationPolicy(Policy)}.
2271      */
getNotificationPolicy()2272     public Policy getNotificationPolicy() {
2273         INotificationManager service = service();
2274         try {
2275             return service.getNotificationPolicy(mContext.getOpPackageName());
2276         } catch (RemoteException e) {
2277             throw e.rethrowFromSystemServer();
2278         }
2279     }
2280 
2281     /**
2282      * Sets the current notification policy (which applies when {@link #setInterruptionFilter} is
2283      * called with the {@link #INTERRUPTION_FILTER_PRIORITY} value).
2284      *
2285      * <p>Apps targeting {@link Build.VERSION_CODES#VANILLA_ICE_CREAM} and above (with some
2286      * exceptions, such as companion device managers) cannot modify the global notification policy.
2287      * Calling this method will instead create or update an {@link AutomaticZenRule} associated to
2288      * the app, using a {@link ZenPolicy} corresponding to the {@link Policy} supplied here, and
2289      * which will be activated/deactivated by calls to {@link #setInterruptionFilter(int)}.
2290      *
2291      * <p>Only available if policy access is granted to this package. See
2292      * {@link #isNotificationPolicyAccessGranted}.
2293      *
2294      * @param policy The new desired policy.
2295      */
setNotificationPolicy(@onNull Policy policy)2296     public void setNotificationPolicy(@NonNull Policy policy) {
2297         setNotificationPolicy(policy, /* fromUser= */ false);
2298     }
2299 
2300     /** @hide */
setNotificationPolicy(@onNull Policy policy, boolean fromUser)2301     public void setNotificationPolicy(@NonNull Policy policy, boolean fromUser) {
2302         checkRequired("policy", policy);
2303         INotificationManager service = service();
2304         try {
2305             service.setNotificationPolicy(mContext.getOpPackageName(), policy, fromUser);
2306         } catch (RemoteException e) {
2307             throw e.rethrowFromSystemServer();
2308         }
2309     }
2310 
2311     /** @hide */
setNotificationPolicyAccessGranted(String pkg, boolean granted)2312     public void setNotificationPolicyAccessGranted(String pkg, boolean granted) {
2313         INotificationManager service = service();
2314         try {
2315             service.setNotificationPolicyAccessGranted(pkg, granted);
2316         } catch (RemoteException e) {
2317             throw e.rethrowFromSystemServer();
2318         }
2319     }
2320 
2321     /** @hide */
setNotificationListenerAccessGranted( @onNull ComponentName listener, boolean granted)2322     public void setNotificationListenerAccessGranted(
2323             @NonNull ComponentName listener, boolean granted) {
2324         setNotificationListenerAccessGranted(listener, granted, true);
2325     }
2326     /**
2327      * Gets the device-default notification policy as a ZenPolicy.
2328      * @hide
2329      */
2330     @TestApi
getDefaultZenPolicy()2331     public @NonNull ZenPolicy getDefaultZenPolicy() {
2332         INotificationManager service = service();
2333         try {
2334             return service.getDefaultZenPolicy();
2335         } catch (RemoteException e) {
2336             throw e.rethrowFromSystemServer();
2337         }
2338     }
2339     /**
2340      * @hide
2341      */
2342     @FlaggedApi(Flags.FLAG_MODES_UI)
setManualZenRuleDeviceEffects(@onNull ZenDeviceEffects effects)2343     public void setManualZenRuleDeviceEffects(@NonNull ZenDeviceEffects effects) {
2344         INotificationManager service = service();
2345         try {
2346             service.setManualZenRuleDeviceEffects(effects);
2347         } catch (RemoteException e) {
2348             throw e.rethrowFromSystemServer();
2349         }
2350     }
2351 
2352     /**
2353      * For apps targeting {@link Build.VERSION_CODES#VANILLA_ICE_CREAM} and above, the
2354      * {@code setNotificationListenerAccessGranted} method will use the user contained within the
2355      * context.
2356      * For apps targeting an SDK version <em>below</em> this, the user of the calling process will
2357      * be used (Process.myUserHandle()).
2358      *
2359      * @hide
2360      */
2361     @ChangeId
2362     @EnabledSince(targetSdkVersion = Build.VERSION_CODES.VANILLA_ICE_CREAM)
2363     public static final long SET_LISTENER_ACCESS_GRANTED_IS_USER_AWARE = 302563478L;
2364 
2365     /**
2366      * Grants/revokes Notification Listener access to the given component for current user.
2367      * To grant access for a particular user, obtain this service by using the {@link Context}
2368      * provided by {@link Context#createPackageContextAsUser}
2369      *
2370      * @param listener Name of component to grant/revoke access
2371      * @param granted  Grant/revoke access
2372      * @param userSet  Whether the action was triggered explicitly by user
2373      * @hide
2374      */
2375     @SystemApi
2376     @TestApi
2377     @UserHandleAware(enabledSinceTargetSdkVersion = Build.VERSION_CODES.VANILLA_ICE_CREAM)
2378     @RequiresPermission(android.Manifest.permission.MANAGE_NOTIFICATION_LISTENERS)
setNotificationListenerAccessGranted( @onNull ComponentName listener, boolean granted, boolean userSet)2379     public void setNotificationListenerAccessGranted(
2380             @NonNull ComponentName listener, boolean granted, boolean userSet) {
2381         INotificationManager service = service();
2382         try {
2383             if (CompatChanges.isChangeEnabled(SET_LISTENER_ACCESS_GRANTED_IS_USER_AWARE)) {
2384                 service.setNotificationListenerAccessGrantedForUser(listener, mContext.getUserId(),
2385                         granted, userSet);
2386             } else {
2387                 service.setNotificationListenerAccessGranted(listener, granted, userSet);
2388             }
2389         } catch (RemoteException e) {
2390             throw e.rethrowFromSystemServer();
2391         }
2392     }
2393 
2394     /** @hide */
setNotificationListenerAccessGrantedForUser(ComponentName listener, int userId, boolean granted)2395     public void setNotificationListenerAccessGrantedForUser(ComponentName listener, int userId,
2396             boolean granted) {
2397         INotificationManager service = service();
2398         try {
2399             service.setNotificationListenerAccessGrantedForUser(listener, userId, granted, true);
2400         } catch (RemoteException e) {
2401             throw e.rethrowFromSystemServer();
2402         }
2403     }
2404 
2405     /**
2406      * Grants/revokes Notification Assistant access to {@code assistant} for current user.
2407      * To grant access for a particular user, obtain this service by using the {@link Context}
2408      * provided by {@link Context#createPackageContextAsUser}
2409      *
2410      * @param assistant Name of component to grant/revoke access or {@code null} to revoke access to
2411      *                  current assistant
2412      * @param granted Grant/revoke access
2413      * @hide
2414      */
2415     @SystemApi
setNotificationAssistantAccessGranted(@ullable ComponentName assistant, boolean granted)2416     public void setNotificationAssistantAccessGranted(@Nullable ComponentName assistant,
2417             boolean granted) {
2418         INotificationManager service = service();
2419         try {
2420             service.setNotificationAssistantAccessGranted(assistant, granted);
2421         } catch (RemoteException e) {
2422             throw e.rethrowFromSystemServer();
2423         }
2424     }
2425 
2426     /**
2427      * Gets the list of enabled notification listener components for current user.
2428      * To query for a particular user, obtain this service by using the {@link Context}
2429      * provided by {@link Context#createPackageContextAsUser}
2430      *
2431      * @return the list of {@link ComponentName}s of the notification listeners
2432      * @hide
2433      */
2434     @SystemApi
2435     @RequiresPermission(android.Manifest.permission.MANAGE_NOTIFICATION_LISTENERS)
getEnabledNotificationListeners()2436     public @NonNull List<ComponentName> getEnabledNotificationListeners() {
2437         return getEnabledNotificationListeners(mContext.getUserId());
2438     }
2439 
2440     /** @hide */
getEnabledNotificationListeners(int userId)2441     public List<ComponentName> getEnabledNotificationListeners(int userId) {
2442         INotificationManager service = service();
2443         try {
2444             return service.getEnabledNotificationListeners(userId);
2445         } catch (RemoteException e) {
2446             throw e.rethrowFromSystemServer();
2447         }
2448     }
2449 
2450     /** @hide */
2451     @SystemApi
getAllowedNotificationAssistant()2452     public @Nullable ComponentName getAllowedNotificationAssistant() {
2453         INotificationManager service = service();
2454         try {
2455             return service.getAllowedNotificationAssistant();
2456         } catch (RemoteException e) {
2457             throw e.rethrowFromSystemServer();
2458         }
2459     }
2460 
2461     /**
2462      * Whether the given user has an enabled
2463      * {@link android.service.notification.NotificationListenerService} with the given package name.
2464      *
2465      * @param packageName the package name of the NotificationListenerService class
2466      * @param userHandle the handle of the user that set the listener
2467      * @hide
2468      */
2469     @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
2470     @SuppressLint("UserHandle")
hasEnabledNotificationListener(@onNull String packageName, @NonNull UserHandle userHandle)2471     public boolean hasEnabledNotificationListener(@NonNull String packageName,
2472             @NonNull UserHandle userHandle) {
2473         INotificationManager service = service();
2474         try {
2475             return service.hasEnabledNotificationListener(packageName, userHandle.getIdentifier());
2476         } catch (RemoteException e) {
2477             throw e.rethrowFromSystemServer();
2478         }
2479     }
checkRequired(String name, Object value)2480     private static void checkRequired(String name, Object value) {
2481         if (value == null) {
2482             throw new IllegalArgumentException(name + " is required");
2483         }
2484     }
2485 
2486     /**
2487      * Controls whether toast rate limiting is enabled for the calling uid.
2488      *
2489      * @param enable true to enable toast rate limiting, false to disable it
2490      * @hide
2491      */
2492     @TestApi
2493     @RequiresPermission(android.Manifest.permission.MANAGE_TOAST_RATE_LIMITING)
setToastRateLimitingEnabled(boolean enable)2494     public void setToastRateLimitingEnabled(boolean enable) {
2495         INotificationManager service = service();
2496         try {
2497             service.setToastRateLimitingEnabled(enable);
2498         } catch (RemoteException e) {
2499             throw e.rethrowFromSystemServer();
2500         }
2501     }
2502 
2503     /**
2504      * Notification policy configuration.  Represents user-preferences for notification
2505      * filtering.
2506      */
2507     public static class Policy implements android.os.Parcelable {
2508         /** Reminder notifications are prioritized. */
2509         public static final int PRIORITY_CATEGORY_REMINDERS = 1 << 0;
2510         /** Event notifications are prioritized. */
2511         public static final int PRIORITY_CATEGORY_EVENTS = 1 << 1;
2512         /** Message notifications are prioritized. */
2513         public static final int PRIORITY_CATEGORY_MESSAGES = 1 << 2;
2514         /** Calls are prioritized. */
2515         public static final int PRIORITY_CATEGORY_CALLS = 1 << 3;
2516         /** Calls from repeat callers are prioritized. */
2517         public static final int PRIORITY_CATEGORY_REPEAT_CALLERS = 1 << 4;
2518         /** Alarms are prioritized */
2519         public static final int PRIORITY_CATEGORY_ALARMS = 1 << 5;
2520         /** Media, game, voice navigation are prioritized */
2521         public static final int PRIORITY_CATEGORY_MEDIA = 1 << 6;
2522         /**System (catch-all for non-never suppressible sounds) are prioritized */
2523         public static final int PRIORITY_CATEGORY_SYSTEM = 1 << 7;
2524         /**
2525          * Conversations are allowed through DND.
2526          */
2527         public static final int PRIORITY_CATEGORY_CONVERSATIONS = 1 << 8;
2528 
2529         /**
2530          * @hide
2531          */
2532         public static final int[] ALL_PRIORITY_CATEGORIES = {
2533                 PRIORITY_CATEGORY_ALARMS,
2534                 PRIORITY_CATEGORY_MEDIA,
2535                 PRIORITY_CATEGORY_SYSTEM,
2536                 PRIORITY_CATEGORY_REMINDERS,
2537                 PRIORITY_CATEGORY_EVENTS,
2538                 PRIORITY_CATEGORY_MESSAGES,
2539                 PRIORITY_CATEGORY_CALLS,
2540                 PRIORITY_CATEGORY_REPEAT_CALLERS,
2541                 PRIORITY_CATEGORY_CONVERSATIONS,
2542         };
2543 
2544         /** @hide */
2545         @IntDef(prefix = { "PRIORITY_SENDERS_" }, value = {
2546                 PRIORITY_SENDERS_ANY,
2547                 PRIORITY_SENDERS_CONTACTS,
2548                 PRIORITY_SENDERS_STARRED,
2549         })
2550         @Retention(RetentionPolicy.SOURCE)
2551         public @interface PrioritySenders {}
2552 
2553         /** Any sender is prioritized. */
2554         public static final int PRIORITY_SENDERS_ANY = 0;
2555         /** Saved contacts are prioritized. */
2556         public static final int PRIORITY_SENDERS_CONTACTS = 1;
2557         /** Only starred contacts are prioritized. */
2558         public static final int PRIORITY_SENDERS_STARRED = 2;
2559 
2560 
2561         /** @hide */
2562         @IntDef(prefix = { "CONVERSATION_SENDERS_" }, value = {
2563                 CONVERSATION_SENDERS_ANYONE,
2564                 CONVERSATION_SENDERS_IMPORTANT,
2565                 CONVERSATION_SENDERS_NONE,
2566         })
2567         @Retention(RetentionPolicy.SOURCE)
2568         public @interface ConversationSenders {}
2569         /**
2570          * Used to indicate all conversations can bypass dnd.
2571          */
2572         public static final int CONVERSATION_SENDERS_ANYONE = ZenPolicy.CONVERSATION_SENDERS_ANYONE;
2573 
2574         /**
2575          * Used to indicate important conversations can bypass dnd.
2576          */
2577         public static final int CONVERSATION_SENDERS_IMPORTANT =
2578                 ZenPolicy.CONVERSATION_SENDERS_IMPORTANT;
2579 
2580         /**
2581          * Used to indicate no conversations can bypass dnd.
2582          */
2583         public static final int CONVERSATION_SENDERS_NONE = ZenPolicy.CONVERSATION_SENDERS_NONE;
2584 
2585         /** Notification categories to prioritize. Bitmask of PRIORITY_CATEGORY_* constants. */
2586         public final int priorityCategories;
2587 
2588         /** Notification senders to prioritize for calls. One of:
2589          * PRIORITY_SENDERS_ANY, PRIORITY_SENDERS_CONTACTS, PRIORITY_SENDERS_STARRED */
2590         @PrioritySenders
2591         public final int priorityCallSenders;
2592 
2593         /** Notification senders to prioritize for messages. One of:
2594          * PRIORITY_SENDERS_ANY, PRIORITY_SENDERS_CONTACTS, PRIORITY_SENDERS_STARRED */
2595         @PrioritySenders
2596         public final int priorityMessageSenders;
2597 
2598         /**
2599          * Notification senders to prioritize for conversations. One of:
2600          * {@link #CONVERSATION_SENDERS_NONE}, {@link #CONVERSATION_SENDERS_IMPORTANT},
2601          * {@link #CONVERSATION_SENDERS_ANYONE}.
2602          */
2603         @ConversationSenders
2604         public final int priorityConversationSenders;
2605 
2606         /**
2607          * @hide
2608          */
2609         public static final int CONVERSATION_SENDERS_UNSET = -1;
2610 
2611         /**
2612          * @hide
2613          */
2614         public static final int SUPPRESSED_EFFECTS_UNSET = -1;
2615 
2616         /**
2617          * Whether notifications suppressed by DND should not interrupt visually (e.g. with
2618          * notification lights or by turning the screen on) when the screen is off.
2619          *
2620          * @deprecated use {@link #SUPPRESSED_EFFECT_FULL_SCREEN_INTENT} and
2621          * {@link #SUPPRESSED_EFFECT_AMBIENT} and {@link #SUPPRESSED_EFFECT_LIGHTS} individually.
2622          */
2623         @Deprecated
2624         public static final int SUPPRESSED_EFFECT_SCREEN_OFF = 1 << 0;
2625         /**
2626          * Whether notifications suppressed by DND should not interrupt visually when the screen
2627          * is on (e.g. by peeking onto the screen).
2628          *
2629          * @deprecated use {@link #SUPPRESSED_EFFECT_PEEK}.
2630          */
2631         @Deprecated
2632         public static final int SUPPRESSED_EFFECT_SCREEN_ON = 1 << 1;
2633 
2634         /**
2635          * Whether {@link Notification#fullScreenIntent full screen intents} from
2636          * notifications intercepted by DND are blocked.
2637          */
2638         public static final int SUPPRESSED_EFFECT_FULL_SCREEN_INTENT = 1 << 2;
2639 
2640         /**
2641          * Whether {@link NotificationChannel#shouldShowLights() notification lights} from
2642          * notifications intercepted by DND are blocked.
2643          */
2644         public static final int SUPPRESSED_EFFECT_LIGHTS = 1 << 3;
2645 
2646         /**
2647          * Whether notifications intercepted by DND are prevented from peeking.
2648          */
2649         public static final int SUPPRESSED_EFFECT_PEEK = 1 << 4;
2650 
2651         /**
2652          * Whether notifications intercepted by DND are prevented from appearing in the status bar,
2653          * on devices that support status bars.
2654          */
2655         public static final int SUPPRESSED_EFFECT_STATUS_BAR = 1 << 5;
2656 
2657         /**
2658          * Whether {@link NotificationChannel#canShowBadge() badges} from
2659          * notifications intercepted by DND are blocked on devices that support badging.
2660          */
2661         public static final int SUPPRESSED_EFFECT_BADGE = 1 << 6;
2662 
2663         /**
2664          * Whether notification intercepted by DND are prevented from appearing on ambient displays
2665          * on devices that support ambient display.
2666          */
2667         public static final int SUPPRESSED_EFFECT_AMBIENT = 1 << 7;
2668 
2669         /**
2670          * Whether notification intercepted by DND are prevented from appearing in notification
2671          * list views like the notification shade or lockscreen on devices that support those
2672          * views.
2673          */
2674         public static final int SUPPRESSED_EFFECT_NOTIFICATION_LIST = 1 << 8;
2675 
2676         private static final int[] ALL_SUPPRESSED_EFFECTS = {
2677                 SUPPRESSED_EFFECT_SCREEN_OFF,
2678                 SUPPRESSED_EFFECT_SCREEN_ON,
2679                 SUPPRESSED_EFFECT_FULL_SCREEN_INTENT,
2680                 SUPPRESSED_EFFECT_LIGHTS,
2681                 SUPPRESSED_EFFECT_PEEK,
2682                 SUPPRESSED_EFFECT_STATUS_BAR,
2683                 SUPPRESSED_EFFECT_BADGE,
2684                 SUPPRESSED_EFFECT_AMBIENT,
2685                 SUPPRESSED_EFFECT_NOTIFICATION_LIST
2686         };
2687 
2688         /**
2689          * Visual effects to suppress for a notification that is filtered by Do Not Disturb mode.
2690          * Bitmask of SUPPRESSED_EFFECT_* constants.
2691          */
2692         public final int suppressedVisualEffects;
2693 
2694         /**
2695          * @hide
2696          */
2697         public static final int STATE_HAS_PRIORITY_CHANNELS = 1 << 0;
2698 
2699         /**
2700          * Whether the policy indicates that even priority channels are NOT permitted to bypass DND.
2701          * Note that this state explicitly marks the "disallow" state because the default behavior
2702          * is to allow priority channels to break through.
2703          * @hide
2704          */
2705         public static final int STATE_PRIORITY_CHANNELS_BLOCKED = 1 << 1;
2706 
2707         /**
2708          * @hide
2709          */
2710         public static final int STATE_UNSET = -1;
2711 
2712         /**
2713          * Notification state information that is necessary to determine Do Not Disturb behavior.
2714          * Bitmask of STATE_* constants.
2715          * @hide
2716          */
2717         public final int state;
2718 
2719         /**
2720          * Constructs a policy for Do Not Disturb priority mode behavior.
2721          *
2722          * <p>
2723          *     Apps that target API levels below {@link Build.VERSION_CODES#P} cannot
2724          *     change user-designated values to allow or disallow
2725          *     {@link Policy#PRIORITY_CATEGORY_ALARMS}, {@link Policy#PRIORITY_CATEGORY_SYSTEM}, and
2726          *     {@link Policy#PRIORITY_CATEGORY_MEDIA} from bypassing dnd.
2727          *
2728          * @param priorityCategories bitmask of categories of notifications that can bypass DND.
2729          * @param priorityCallSenders which callers can bypass DND.
2730          * @param priorityMessageSenders which message senders can bypass DND.
2731          */
Policy(int priorityCategories, int priorityCallSenders, int priorityMessageSenders)2732         public Policy(int priorityCategories, int priorityCallSenders, int priorityMessageSenders) {
2733             this(priorityCategories, priorityCallSenders, priorityMessageSenders,
2734                     SUPPRESSED_EFFECTS_UNSET, STATE_UNSET, CONVERSATION_SENDERS_UNSET);
2735         }
2736 
2737         /**
2738          * Constructs a policy for Do Not Disturb priority mode behavior.
2739          *
2740          * <p>
2741          *     Apps that target API levels below {@link Build.VERSION_CODES#R} cannot
2742          *     change user-designated values to allow or disallow
2743          *     {@link Policy#PRIORITY_CATEGORY_CONVERSATIONS}, from bypassing dnd.
2744          * <p>
2745          *     Additionally, apps that target API levels below {@link Build.VERSION_CODES#P} can
2746          *     only modify the {@link #SUPPRESSED_EFFECT_SCREEN_ON} and
2747          *     {@link #SUPPRESSED_EFFECT_SCREEN_OFF} bits of the suppressed visual effects field.
2748          *     All other suppressed effects will be ignored and reconstituted from the screen on
2749          *     and screen off values.
2750          * <p>
2751          *     Apps that target {@link Build.VERSION_CODES#P} or above can set any
2752          *     suppressed visual effects. However, if any suppressed effects >
2753          *     {@link #SUPPRESSED_EFFECT_SCREEN_ON} are set, {@link #SUPPRESSED_EFFECT_SCREEN_ON}
2754          *     and {@link #SUPPRESSED_EFFECT_SCREEN_OFF} will be ignored and reconstituted from
2755          *     the more specific suppressed visual effect bits. Apps should migrate to targeting
2756          *     specific effects instead of the deprecated {@link #SUPPRESSED_EFFECT_SCREEN_ON} and
2757          *     {@link #SUPPRESSED_EFFECT_SCREEN_OFF} effects.
2758          *
2759          * @param priorityCategories bitmask of categories of notifications that can bypass DND.
2760          * @param priorityCallSenders which callers can bypass DND.
2761          * @param priorityMessageSenders which message senders can bypass DND.
2762          * @param suppressedVisualEffects which visual interruptions should be suppressed from
2763          *                                notifications that are filtered by DND.
2764          */
Policy(int priorityCategories, int priorityCallSenders, int priorityMessageSenders, int suppressedVisualEffects)2765         public Policy(int priorityCategories, int priorityCallSenders, int priorityMessageSenders,
2766                 int suppressedVisualEffects) {
2767             this(priorityCategories, priorityCallSenders, priorityMessageSenders,
2768                     suppressedVisualEffects, STATE_UNSET, CONVERSATION_SENDERS_UNSET);
2769         }
2770 
2771         /**
2772          * Constructs a policy for Do Not Disturb priority mode behavior.
2773          *
2774          * <p>
2775          *     Apps that target API levels below {@link Build.VERSION_CODES#P} cannot
2776          *     change user-designated values to allow or disallow
2777          *     {@link Policy#PRIORITY_CATEGORY_CONVERSATIONS} from bypassing dnd. If you do need
2778          *     to change them, use a {@link ZenPolicy} associated with an {@link AutomaticZenRule}
2779          *     instead of changing the global setting.
2780          * <p>
2781          *     Apps that target API levels below {@link Build.VERSION_CODES#P} cannot
2782          *     change user-designated values to allow or disallow
2783          *     {@link Policy#PRIORITY_CATEGORY_ALARMS},
2784          *     {@link Policy#PRIORITY_CATEGORY_SYSTEM}, and
2785          *     {@link Policy#PRIORITY_CATEGORY_MEDIA} from bypassing dnd.
2786          * <p>
2787          *     Additionally, apps that target API levels below {@link Build.VERSION_CODES#P} can
2788          *     only modify the {@link #SUPPRESSED_EFFECT_SCREEN_ON} and
2789          *     {@link #SUPPRESSED_EFFECT_SCREEN_OFF} bits of the suppressed visual effects field.
2790          *     All other suppressed effects will be ignored and reconstituted from the screen on
2791          *     and screen off values.
2792          * <p>
2793          *     Apps that target {@link Build.VERSION_CODES#P} or above can set any
2794          *     suppressed visual effects. However, if any suppressed effects >
2795          *     {@link #SUPPRESSED_EFFECT_SCREEN_ON} are set, {@link #SUPPRESSED_EFFECT_SCREEN_ON}
2796          *     and {@link #SUPPRESSED_EFFECT_SCREEN_OFF} will be ignored and reconstituted from
2797          *     the more specific suppressed visual effect bits. Apps should migrate to targeting
2798          *     specific effects instead of the deprecated {@link #SUPPRESSED_EFFECT_SCREEN_ON} and
2799          *     {@link #SUPPRESSED_EFFECT_SCREEN_OFF} effects.
2800          *
2801          * @param priorityCategories bitmask of categories of notifications that can bypass DND.
2802          * @param priorityCallSenders which callers can bypass DND.
2803          * @param priorityMessageSenders which message senders can bypass DND.
2804          * @param suppressedVisualEffects which visual interruptions should be suppressed from
2805          *                                notifications that are filtered by DND.
2806          */
Policy(int priorityCategories, @PrioritySenders int priorityCallSenders, @PrioritySenders int priorityMessageSenders, int suppressedVisualEffects, @ConversationSenders int priorityConversationSenders)2807         public Policy(int priorityCategories, @PrioritySenders int priorityCallSenders,
2808                 @PrioritySenders int priorityMessageSenders,
2809                 int suppressedVisualEffects, @ConversationSenders int priorityConversationSenders) {
2810             this(priorityCategories, priorityCallSenders, priorityMessageSenders,
2811                     suppressedVisualEffects, STATE_UNSET, priorityConversationSenders);
2812         }
2813 
2814         /** @hide */
Policy(int priorityCategories, int priorityCallSenders, int priorityMessageSenders, int suppressedVisualEffects, int state, int priorityConversationSenders)2815         public Policy(int priorityCategories, int priorityCallSenders, int priorityMessageSenders,
2816                 int suppressedVisualEffects, int state, int priorityConversationSenders) {
2817             this.priorityCategories = priorityCategories;
2818             this.priorityCallSenders = priorityCallSenders;
2819             this.priorityMessageSenders = priorityMessageSenders;
2820             this.suppressedVisualEffects = suppressedVisualEffects;
2821             this.state = state;
2822             this.priorityConversationSenders = priorityConversationSenders;
2823         }
2824 
2825 
2826         /** @hide */
Policy(Parcel source)2827         public Policy(Parcel source) {
2828             this(source.readInt(), source.readInt(), source.readInt(), source.readInt(),
2829                     source.readInt(), source.readInt());
2830         }
2831 
2832         @Override
writeToParcel(Parcel dest, int flags)2833         public void writeToParcel(Parcel dest, int flags) {
2834             dest.writeInt(priorityCategories);
2835             dest.writeInt(priorityCallSenders);
2836             dest.writeInt(priorityMessageSenders);
2837             dest.writeInt(suppressedVisualEffects);
2838             dest.writeInt(state);
2839             dest.writeInt(priorityConversationSenders);
2840         }
2841 
2842         @Override
describeContents()2843         public int describeContents() {
2844             return 0;
2845         }
2846 
2847         @Override
hashCode()2848         public int hashCode() {
2849             return Objects.hash(priorityCategories, priorityCallSenders, priorityMessageSenders,
2850                     suppressedVisualEffects, state, priorityConversationSenders);
2851         }
2852 
2853         @Override
equals(@ullable Object o)2854         public boolean equals(@Nullable Object o) {
2855             if (!(o instanceof Policy)) return false;
2856             if (o == this) return true;
2857             final Policy other = (Policy) o;
2858             return other.priorityCategories == priorityCategories
2859                     && other.priorityCallSenders == priorityCallSenders
2860                     && other.priorityMessageSenders == priorityMessageSenders
2861                     && suppressedVisualEffectsEqual(suppressedVisualEffects,
2862                     other.suppressedVisualEffects)
2863                     && other.state == this.state
2864                     && other.priorityConversationSenders == this.priorityConversationSenders;
2865         }
2866 
suppressedVisualEffectsEqual(int suppressedEffects, int otherSuppressedVisualEffects)2867         private boolean suppressedVisualEffectsEqual(int suppressedEffects,
2868                 int otherSuppressedVisualEffects) {
2869             if (suppressedEffects == otherSuppressedVisualEffects) {
2870                 return true;
2871             }
2872 
2873             if ((suppressedEffects & SUPPRESSED_EFFECT_SCREEN_ON) != 0) {
2874                 suppressedEffects |= SUPPRESSED_EFFECT_PEEK;
2875             }
2876             if ((suppressedEffects & SUPPRESSED_EFFECT_SCREEN_OFF) != 0) {
2877                 suppressedEffects |= SUPPRESSED_EFFECT_FULL_SCREEN_INTENT;
2878                 suppressedEffects |= SUPPRESSED_EFFECT_LIGHTS;
2879                 suppressedEffects |= SUPPRESSED_EFFECT_AMBIENT;
2880             }
2881 
2882             if ((otherSuppressedVisualEffects & SUPPRESSED_EFFECT_SCREEN_ON) != 0) {
2883                 otherSuppressedVisualEffects |= SUPPRESSED_EFFECT_PEEK;
2884             }
2885             if ((otherSuppressedVisualEffects & SUPPRESSED_EFFECT_SCREEN_OFF) != 0) {
2886                 otherSuppressedVisualEffects |= SUPPRESSED_EFFECT_FULL_SCREEN_INTENT;
2887                 otherSuppressedVisualEffects |= SUPPRESSED_EFFECT_LIGHTS;
2888                 otherSuppressedVisualEffects |= SUPPRESSED_EFFECT_AMBIENT;
2889             }
2890 
2891             if ((suppressedEffects & SUPPRESSED_EFFECT_SCREEN_ON)
2892                     != (otherSuppressedVisualEffects & SUPPRESSED_EFFECT_SCREEN_ON)) {
2893                 int currSuppressedEffects = (suppressedEffects & SUPPRESSED_EFFECT_SCREEN_ON) != 0
2894                         ? otherSuppressedVisualEffects : suppressedEffects;
2895                 if ((currSuppressedEffects & SUPPRESSED_EFFECT_PEEK) == 0) {
2896                     return false;
2897                 }
2898             }
2899 
2900             if ((suppressedEffects & SUPPRESSED_EFFECT_SCREEN_OFF)
2901                     != (otherSuppressedVisualEffects & SUPPRESSED_EFFECT_SCREEN_OFF)) {
2902                 int currSuppressedEffects = (suppressedEffects & SUPPRESSED_EFFECT_SCREEN_OFF) != 0
2903                         ? otherSuppressedVisualEffects : suppressedEffects;
2904                 if ((currSuppressedEffects & SUPPRESSED_EFFECT_FULL_SCREEN_INTENT) == 0
2905                         || (currSuppressedEffects & SUPPRESSED_EFFECT_LIGHTS) == 0
2906                         || (currSuppressedEffects & SUPPRESSED_EFFECT_AMBIENT) == 0) {
2907                     return false;
2908                 }
2909             }
2910 
2911             int thisWithoutOldEffects = suppressedEffects
2912                     & ~SUPPRESSED_EFFECT_SCREEN_ON
2913                     & ~SUPPRESSED_EFFECT_SCREEN_OFF;
2914             int otherWithoutOldEffects = otherSuppressedVisualEffects
2915                     & ~SUPPRESSED_EFFECT_SCREEN_ON
2916                     & ~SUPPRESSED_EFFECT_SCREEN_OFF;
2917             return thisWithoutOldEffects == otherWithoutOldEffects;
2918         }
2919 
2920         @Override
toString()2921         public String toString() {
2922             return new StringBuilder().append("NotificationManager.Policy[")
2923                     .append("priorityCategories=")
2924                     .append(priorityCategoriesToString(priorityCategories))
2925                     .append(",priorityCallSenders=")
2926                     .append(prioritySendersToString(priorityCallSenders))
2927                     .append(",priorityMessageSenders=")
2928                     .append(prioritySendersToString(priorityMessageSenders))
2929                     .append(",priorityConvSenders=")
2930                     .append(conversationSendersToString(priorityConversationSenders))
2931                     .append(",suppressedVisualEffects=")
2932                     .append(suppressedEffectsToString(suppressedVisualEffects))
2933                     .append(",hasPriorityChannels=")
2934                     .append((state == STATE_UNSET
2935                             ? "unset"
2936                             : ((state & STATE_HAS_PRIORITY_CHANNELS) != 0)
2937                                     ? "true"
2938                                     : "false"))
2939                     .append(",allowPriorityChannels=")
2940                     .append((state == STATE_UNSET
2941                             ? "unset"
2942                             : (allowPriorityChannels() ? "true" : "false")))
2943                     .append("]")
2944                     .toString();
2945         }
2946 
2947         /** @hide */
dumpDebug(ProtoOutputStream proto, long fieldId)2948         public void dumpDebug(ProtoOutputStream proto, long fieldId) {
2949             final long pToken = proto.start(fieldId);
2950 
2951             bitwiseToProtoEnum(proto, PolicyProto.PRIORITY_CATEGORIES, priorityCategories);
2952             proto.write(PolicyProto.PRIORITY_CALL_SENDER, priorityCallSenders);
2953             proto.write(PolicyProto.PRIORITY_MESSAGE_SENDER, priorityMessageSenders);
2954             bitwiseToProtoEnum(
2955                     proto, PolicyProto.SUPPRESSED_VISUAL_EFFECTS, suppressedVisualEffects);
2956 
2957             proto.end(pToken);
2958         }
2959 
bitwiseToProtoEnum(ProtoOutputStream proto, long fieldId, int data)2960         private static void bitwiseToProtoEnum(ProtoOutputStream proto, long fieldId, int data) {
2961             for (int i = 1; data > 0; ++i, data >>>= 1) {
2962                 if ((data & 1) == 1) {
2963                     proto.write(fieldId, i);
2964                 }
2965             }
2966         }
2967 
2968         /**
2969          * @hide
2970          */
getAllSuppressedVisualEffects()2971         public static int getAllSuppressedVisualEffects() {
2972             int effects = 0;
2973             for (int i = 0; i < ALL_SUPPRESSED_EFFECTS.length; i++) {
2974                 effects |= ALL_SUPPRESSED_EFFECTS[i];
2975             }
2976             return effects;
2977         }
2978 
2979         /**
2980          * @hide
2981          */
areAllVisualEffectsSuppressed(int effects)2982         public static boolean areAllVisualEffectsSuppressed(int effects) {
2983             for (int i = 0; i < ALL_SUPPRESSED_EFFECTS.length; i++) {
2984                 final int effect = ALL_SUPPRESSED_EFFECTS[i];
2985                 if ((effects & effect) == 0) {
2986                     return false;
2987                 }
2988             }
2989             return true;
2990         }
2991 
toggleEffects(int currentEffects, int[] effects, boolean suppress)2992         private static int toggleEffects(int currentEffects, int[] effects, boolean suppress) {
2993             for (int i = 0; i < effects.length; i++) {
2994                 final int effect = effects[i];
2995                 if (suppress) {
2996                     currentEffects |= effect;
2997                 } else {
2998                     currentEffects &= ~effect;
2999                 }
3000             }
3001             return currentEffects;
3002         }
3003 
suppressedEffectsToString(int effects)3004         public static String suppressedEffectsToString(int effects) {
3005             if (effects <= 0) return "";
3006             final StringBuilder sb = new StringBuilder();
3007             for (int i = 0; i < ALL_SUPPRESSED_EFFECTS.length; i++) {
3008                 final int effect = ALL_SUPPRESSED_EFFECTS[i];
3009                 if ((effects & effect) != 0) {
3010                     if (sb.length() > 0) sb.append(',');
3011                     sb.append(effectToString(effect));
3012                 }
3013                 effects &= ~effect;
3014             }
3015             if (effects != 0) {
3016                 if (sb.length() > 0) sb.append(',');
3017                 sb.append("UNKNOWN_").append(effects);
3018             }
3019             return sb.toString();
3020         }
3021 
priorityCategoriesToString(int priorityCategories)3022         public static String priorityCategoriesToString(int priorityCategories) {
3023             if (priorityCategories == 0) return "";
3024             final StringBuilder sb = new StringBuilder();
3025             for (int i = 0; i < ALL_PRIORITY_CATEGORIES.length; i++) {
3026                 final int priorityCategory = ALL_PRIORITY_CATEGORIES[i];
3027                 if ((priorityCategories & priorityCategory) != 0) {
3028                     if (sb.length() > 0) sb.append(',');
3029                     sb.append(priorityCategoryToString(priorityCategory));
3030                 }
3031                 priorityCategories &= ~priorityCategory;
3032             }
3033             if (priorityCategories != 0) {
3034                 if (sb.length() > 0) sb.append(',');
3035                 sb.append("PRIORITY_CATEGORY_UNKNOWN_").append(priorityCategories);
3036             }
3037             return sb.toString();
3038         }
3039 
effectToString(int effect)3040         private static String effectToString(int effect) {
3041             switch (effect) {
3042                 case SUPPRESSED_EFFECT_FULL_SCREEN_INTENT:
3043                     return "SUPPRESSED_EFFECT_FULL_SCREEN_INTENT";
3044                 case SUPPRESSED_EFFECT_LIGHTS:
3045                     return "SUPPRESSED_EFFECT_LIGHTS";
3046                 case SUPPRESSED_EFFECT_PEEK:
3047                     return "SUPPRESSED_EFFECT_PEEK";
3048                 case SUPPRESSED_EFFECT_STATUS_BAR:
3049                     return "SUPPRESSED_EFFECT_STATUS_BAR";
3050                 case SUPPRESSED_EFFECT_BADGE:
3051                     return "SUPPRESSED_EFFECT_BADGE";
3052                 case SUPPRESSED_EFFECT_AMBIENT:
3053                     return "SUPPRESSED_EFFECT_AMBIENT";
3054                 case SUPPRESSED_EFFECT_NOTIFICATION_LIST:
3055                     return "SUPPRESSED_EFFECT_NOTIFICATION_LIST";
3056                 case SUPPRESSED_EFFECT_SCREEN_OFF:
3057                     return "SUPPRESSED_EFFECT_SCREEN_OFF";
3058                 case SUPPRESSED_EFFECT_SCREEN_ON:
3059                     return "SUPPRESSED_EFFECT_SCREEN_ON";
3060                 case SUPPRESSED_EFFECTS_UNSET:
3061                     return "SUPPRESSED_EFFECTS_UNSET";
3062                 default: return "UNKNOWN_" + effect;
3063             }
3064         }
3065 
priorityCategoryToString(int priorityCategory)3066         private static String priorityCategoryToString(int priorityCategory) {
3067             switch (priorityCategory) {
3068                 case PRIORITY_CATEGORY_REMINDERS: return "PRIORITY_CATEGORY_REMINDERS";
3069                 case PRIORITY_CATEGORY_EVENTS: return "PRIORITY_CATEGORY_EVENTS";
3070                 case PRIORITY_CATEGORY_MESSAGES: return "PRIORITY_CATEGORY_MESSAGES";
3071                 case PRIORITY_CATEGORY_CALLS: return "PRIORITY_CATEGORY_CALLS";
3072                 case PRIORITY_CATEGORY_REPEAT_CALLERS: return "PRIORITY_CATEGORY_REPEAT_CALLERS";
3073                 case PRIORITY_CATEGORY_ALARMS: return "PRIORITY_CATEGORY_ALARMS";
3074                 case PRIORITY_CATEGORY_MEDIA: return "PRIORITY_CATEGORY_MEDIA";
3075                 case PRIORITY_CATEGORY_SYSTEM: return "PRIORITY_CATEGORY_SYSTEM";
3076                 case PRIORITY_CATEGORY_CONVERSATIONS: return "PRIORITY_CATEGORY_CONVERSATIONS";
3077                 default: return "PRIORITY_CATEGORY_UNKNOWN_" + priorityCategory;
3078             }
3079         }
3080 
prioritySendersToString(int prioritySenders)3081         public static String prioritySendersToString(int prioritySenders) {
3082             switch (prioritySenders) {
3083                 case PRIORITY_SENDERS_ANY: return "PRIORITY_SENDERS_ANY";
3084                 case PRIORITY_SENDERS_CONTACTS: return "PRIORITY_SENDERS_CONTACTS";
3085                 case PRIORITY_SENDERS_STARRED: return "PRIORITY_SENDERS_STARRED";
3086                 default: return "PRIORITY_SENDERS_UNKNOWN_" + prioritySenders;
3087             }
3088         }
3089 
3090         /**
3091          * @hide
3092          */
conversationSendersToString(int priorityConversationSenders)3093         public static @NonNull String conversationSendersToString(int priorityConversationSenders) {
3094             switch (priorityConversationSenders) {
3095                 case CONVERSATION_SENDERS_ANYONE:
3096                     return "anyone";
3097                 case CONVERSATION_SENDERS_IMPORTANT:
3098                     return "important";
3099                 case CONVERSATION_SENDERS_NONE:
3100                     return "none";
3101                 case CONVERSATION_SENDERS_UNSET:
3102                     return "unset";
3103             }
3104             return "invalidConversationType{" + priorityConversationSenders + "}";
3105         }
3106 
3107         public static final @android.annotation.NonNull Parcelable.Creator<Policy> CREATOR
3108                 = new Parcelable.Creator<Policy>() {
3109             @Override
3110             public Policy createFromParcel(Parcel in) {
3111                 return new Policy(in);
3112             }
3113 
3114             @Override
3115             public Policy[] newArray(int size) {
3116                 return new Policy[size];
3117             }
3118         };
3119 
3120         /** @hide **/
allowAlarms()3121         public boolean allowAlarms() {
3122             return (priorityCategories & PRIORITY_CATEGORY_ALARMS) != 0;
3123         }
3124 
3125         /** @hide **/
allowMedia()3126         public boolean allowMedia() {
3127             return (priorityCategories & PRIORITY_CATEGORY_MEDIA) != 0;
3128         }
3129 
3130         /** @hide **/
allowSystem()3131         public boolean allowSystem() {
3132             return (priorityCategories & PRIORITY_CATEGORY_SYSTEM) != 0;
3133         }
3134 
3135         /** @hide **/
allowRepeatCallers()3136         public boolean allowRepeatCallers() {
3137             return (priorityCategories & PRIORITY_CATEGORY_REPEAT_CALLERS) != 0;
3138         }
3139 
3140         /** @hide **/
allowCalls()3141         public boolean allowCalls() {
3142             return (priorityCategories & PRIORITY_CATEGORY_CALLS) != 0;
3143         }
3144 
3145         /** @hide **/
allowConversations()3146         public boolean allowConversations() {
3147             return (priorityCategories & PRIORITY_CATEGORY_CONVERSATIONS) != 0;
3148         }
3149 
3150         /** @hide **/
allowMessages()3151         public boolean allowMessages() {
3152             return (priorityCategories & PRIORITY_CATEGORY_MESSAGES) != 0;
3153         }
3154 
3155         /** @hide **/
allowEvents()3156         public boolean allowEvents() {
3157             return (priorityCategories & PRIORITY_CATEGORY_EVENTS) != 0;
3158         }
3159 
3160         /** @hide **/
allowReminders()3161         public boolean allowReminders() {
3162             return (priorityCategories & PRIORITY_CATEGORY_REMINDERS) != 0;
3163         }
3164 
3165         /** @hide **/
3166         @PrioritySenders
allowCallsFrom()3167         public int allowCallsFrom() {
3168             return priorityCallSenders;
3169         }
3170 
3171         /** @hide **/
3172         @PrioritySenders
allowMessagesFrom()3173         public int allowMessagesFrom() {
3174             return priorityMessageSenders;
3175         }
3176 
3177         /** @hide **/
3178         @ConversationSenders
allowConversationsFrom()3179         public int allowConversationsFrom() {
3180             return priorityConversationSenders;
3181         }
3182 
3183         /** @hide **/
showFullScreenIntents()3184         public boolean showFullScreenIntents() {
3185             return (suppressedVisualEffects & SUPPRESSED_EFFECT_FULL_SCREEN_INTENT) == 0;
3186         }
3187 
3188         /** @hide **/
showLights()3189         public boolean showLights() {
3190             return (suppressedVisualEffects & SUPPRESSED_EFFECT_LIGHTS) == 0;
3191         }
3192 
3193         /** @hide **/
showPeeking()3194         public boolean showPeeking() {
3195             return (suppressedVisualEffects & SUPPRESSED_EFFECT_PEEK) == 0;
3196         }
3197 
3198         /** @hide **/
showStatusBarIcons()3199         public boolean showStatusBarIcons() {
3200             return (suppressedVisualEffects & SUPPRESSED_EFFECT_STATUS_BAR) == 0;
3201         }
3202 
3203         /** @hide **/
showAmbient()3204         public boolean showAmbient() {
3205             return (suppressedVisualEffects & SUPPRESSED_EFFECT_AMBIENT) == 0;
3206         }
3207 
3208         /** @hide **/
showBadges()3209         public boolean showBadges() {
3210             return (suppressedVisualEffects & SUPPRESSED_EFFECT_BADGE) == 0;
3211         }
3212 
3213         /** @hide **/
showInNotificationList()3214         public boolean showInNotificationList() {
3215             return (suppressedVisualEffects & SUPPRESSED_EFFECT_NOTIFICATION_LIST) == 0;
3216         }
3217 
3218         /** @hide **/
3219         @TestApi // so CTS tests can read this state without having to use implementation detail
allowPriorityChannels()3220         public boolean allowPriorityChannels() {
3221             if (state == STATE_UNSET) {
3222                 return true; // default
3223             }
3224             return (state & STATE_PRIORITY_CHANNELS_BLOCKED) == 0;
3225         }
3226 
3227         /** @hide */
hasPriorityChannels()3228         public boolean hasPriorityChannels() {
3229             return (state & STATE_HAS_PRIORITY_CHANNELS) != 0;
3230         }
3231 
3232         /** @hide **/
policyState(boolean hasPriorityChannels, boolean allowPriorityChannels)3233         public static int policyState(boolean hasPriorityChannels, boolean allowPriorityChannels) {
3234             int state = 0;
3235             if (hasPriorityChannels) {
3236                 state |= STATE_HAS_PRIORITY_CHANNELS;
3237             }
3238             if (!allowPriorityChannels) {
3239                 state |= STATE_PRIORITY_CHANNELS_BLOCKED;
3240             }
3241             return state;
3242         }
3243 
3244         /**
3245          * returns a deep copy of this policy
3246          * @hide
3247          */
copy()3248         public Policy copy() {
3249             final Parcel parcel = Parcel.obtain();
3250             try {
3251                 writeToParcel(parcel, 0);
3252                 parcel.setDataPosition(0);
3253                 return new Policy(parcel);
3254             } finally {
3255                 parcel.recycle();
3256             }
3257         }
3258     }
3259 
3260     /**
3261      * Recover a list of active notifications: ones that have been posted by the calling app that
3262      * have not yet been dismissed by the user or {@link #cancel(String, int)}ed by the app.
3263      *
3264      * <p><Each notification is embedded in a {@link StatusBarNotification} object, including the
3265      * original <code>tag</code> and <code>id</code> supplied to
3266      * {@link #notify(String, int, Notification) notify()}
3267      * (via {@link StatusBarNotification#getTag() getTag()} and
3268      * {@link StatusBarNotification#getId() getId()}) as well as a copy of the original
3269      * {@link Notification} object (via {@link StatusBarNotification#getNotification()}).
3270      * </p>
3271      * <p>From {@link Build.VERSION_CODES#Q}, will also return notifications you've posted as an
3272      * app's notification delegate via
3273      * {@link NotificationManager#notifyAsPackage(String, String, int, Notification)}.
3274      * </p>
3275      *
3276      * @return An array of {@link StatusBarNotification}.
3277      */
getActiveNotifications()3278     public StatusBarNotification[] getActiveNotifications() {
3279         final INotificationManager service = service();
3280         final String pkg = mContext.getPackageName();
3281         try {
3282             final ParceledListSlice<StatusBarNotification> parceledList
3283                     = service.getAppActiveNotifications(pkg, mContext.getUserId());
3284             if (parceledList != null) {
3285                 final List<StatusBarNotification> list = parceledList.getList();
3286                 return list.toArray(new StatusBarNotification[list.size()]);
3287             }
3288         } catch (RemoteException e) {
3289             throw e.rethrowFromSystemServer();
3290         }
3291         return new StatusBarNotification[0];
3292     }
3293 
3294     /**
3295      * Gets the current notification interruption filter.
3296      * <p>
3297      * The interruption filter defines which notifications are allowed to
3298      * interrupt the user (e.g. via sound &amp; vibration) and is applied
3299      * globally.
3300      */
getCurrentInterruptionFilter()3301     public final @InterruptionFilter int getCurrentInterruptionFilter() {
3302         final INotificationManager service = service();
3303         try {
3304             return zenModeToInterruptionFilter(service.getZenMode());
3305         } catch (RemoteException e) {
3306             throw e.rethrowFromSystemServer();
3307         }
3308     }
3309 
3310     /**
3311      * Sets the current notification interruption filter.
3312      * <p>
3313      * The interruption filter defines which notifications are allowed to
3314      * interrupt the user (e.g. via sound &amp; vibration) and is applied
3315      * globally.
3316      *
3317      * <p>Apps targeting {@link Build.VERSION_CODES#VANILLA_ICE_CREAM} and above (with some
3318      * exceptions, such as companion device managers) cannot modify the global interruption filter.
3319      * Calling this method will instead activate or deactivate an {@link AutomaticZenRule}
3320      * associated to the app, using a {@link ZenPolicy} that corresponds to the {@link Policy}
3321      * supplied to {@link #setNotificationPolicy(Policy)} (or the global policy when one wasn't
3322      * provided).
3323      *
3324      * <p> Only available if policy access is granted to this package. See
3325      * {@link #isNotificationPolicyAccessGranted}.
3326      */
setInterruptionFilter(@nterruptionFilter int interruptionFilter)3327     public final void setInterruptionFilter(@InterruptionFilter int interruptionFilter) {
3328         setInterruptionFilter(interruptionFilter, /* fromUser= */ false);
3329     }
3330 
3331     /** @hide */
setInterruptionFilter(@nterruptionFilter int interruptionFilter, boolean fromUser)3332     public final void setInterruptionFilter(@InterruptionFilter int interruptionFilter,
3333             boolean fromUser) {
3334         final INotificationManager service = service();
3335         try {
3336             service.setInterruptionFilter(mContext.getOpPackageName(), interruptionFilter,
3337                     fromUser);
3338         } catch (RemoteException e) {
3339             throw e.rethrowFromSystemServer();
3340         }
3341     }
3342 
3343     /**
3344      * Returns whether a call from the provided URI is permitted to notify the user.
3345      * <p>
3346      * A true return value indicates one of the following: Do Not Disturb is not currently active;
3347      * or the caller is a repeat caller and the current policy allows interruptions from repeat
3348      * callers; or the caller is in the user's set of contacts whose calls are allowed to interrupt
3349      * Do Not Disturb.
3350      * </p>
3351      * <p>
3352      * If Do Not Disturb is enabled and either no interruptions or only alarms are allowed, this
3353      * method will return false regardless of input.
3354      * </p>
3355      * <p>
3356      * The provided URI should be a <code>tel:</code> or <code>mailto:</code> schema URI indicating
3357      * the source of the call. For an accurate answer regarding whether the caller matches the
3358      * user's permitted contacts, the path part of the URI must match an entry the Contacts database
3359      * in the appropriate column.
3360      * </p>
3361      * <p>
3362      * Passing in a {@link android.provider.ContactsContract.Contacts#CONTENT_LOOKUP_URI} is also
3363      * permissible, but should only be used for priority contact interruptions and may not provide
3364      * accurate results in the case of repeat callers.
3365      * </p>
3366      * <p>
3367      * See also {@link Person.Builder#setUri} and
3368      * {@link android.provider.ContactsContract.Contacts#CONTENT_LOOKUP_URI}
3369      * for more information.
3370      * </p>
3371      * <p>
3372      * Callers of this method must have notification listener access, permission to read contacts,
3373      * or have system permissions.
3374      * </p>
3375      * <p>
3376      * NOTE: This method calls into Contacts, which may take some time, and should not be called
3377      * on the main thread.
3378      * </p>
3379      *
3380      * @param uri A URI representing a caller. Must not be null.
3381      * @return A boolean indicating whether a call from the URI provided would be allowed to
3382      *         interrupt the user given the current filter.
3383      */
3384     @WorkerThread
matchesCallFilter(@onNull Uri uri)3385     public boolean matchesCallFilter(@NonNull Uri uri) {
3386         Bundle extras = new Bundle();
3387         ArrayList<Person> pList = new ArrayList<>();
3388         pList.add(new Person.Builder().setUri(uri.toString()).build());
3389         extras.putParcelableArrayList(Notification.EXTRA_PEOPLE_LIST, pList);
3390 
3391         return matchesCallFilter(extras);
3392     }
3393 
3394     /** @hide */
zenModeToInterruptionFilter(int zen)3395     public static int zenModeToInterruptionFilter(int zen) {
3396         switch (zen) {
3397             case Global.ZEN_MODE_OFF: return INTERRUPTION_FILTER_ALL;
3398             case Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS: return INTERRUPTION_FILTER_PRIORITY;
3399             case Global.ZEN_MODE_ALARMS: return INTERRUPTION_FILTER_ALARMS;
3400             case Global.ZEN_MODE_NO_INTERRUPTIONS: return INTERRUPTION_FILTER_NONE;
3401             default: return INTERRUPTION_FILTER_UNKNOWN;
3402         }
3403     }
3404 
3405     /** @hide */
zenModeFromInterruptionFilter(int interruptionFilter, int defValue)3406     public static int zenModeFromInterruptionFilter(int interruptionFilter, int defValue) {
3407         switch (interruptionFilter) {
3408             case INTERRUPTION_FILTER_ALL: return Global.ZEN_MODE_OFF;
3409             case INTERRUPTION_FILTER_PRIORITY: return Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS;
3410             case INTERRUPTION_FILTER_ALARMS: return Global.ZEN_MODE_ALARMS;
3411             case INTERRUPTION_FILTER_NONE:  return Global.ZEN_MODE_NO_INTERRUPTIONS;
3412             default: return defValue;
3413         }
3414     }
3415 
3416     /**
3417      * Callback to receive updates when a call notification has been posted or removed
3418      * @hide
3419      */
3420     @SystemApi
3421     @FlaggedApi(android.service.notification.Flags.FLAG_CALLSTYLE_CALLBACK_API)
3422     public interface CallNotificationEventListener {
3423         /**
3424          *  Called when a call notification was posted by a package this listener
3425          *  has registered for.
3426          * @param packageName package name of the app that posted the removed notification
3427          */
3428         @FlaggedApi(android.service.notification.Flags.FLAG_CALLSTYLE_CALLBACK_API)
onCallNotificationPosted(@onNull String packageName, @NonNull UserHandle userHandle)3429         void onCallNotificationPosted(@NonNull String packageName, @NonNull UserHandle userHandle);
3430 
3431         /**
3432          *  Called when a call notification was removed by a package this listener
3433          *  has registered for.
3434          * @param packageName package name of the app that removed notification
3435          */
3436         @FlaggedApi(android.service.notification.Flags.FLAG_CALLSTYLE_CALLBACK_API)
onCallNotificationRemoved(@onNull String packageName, @NonNull UserHandle userHandle)3437         void onCallNotificationRemoved(@NonNull String packageName, @NonNull UserHandle userHandle);
3438     }
3439 
3440     private static class CallNotificationEventCallbackStub extends
3441             ICallNotificationEventCallback.Stub {
3442         final String mPackageName;
3443         final UserHandle mUserHandle;
3444         final Executor mExecutor;
3445         final CallNotificationEventListener mListener;
3446 
CallNotificationEventCallbackStub(@onNull String packageName, @NonNull UserHandle userHandle, @NonNull @CallbackExecutor Executor executor, @NonNull CallNotificationEventListener listener)3447         CallNotificationEventCallbackStub(@NonNull String packageName,
3448                 @NonNull UserHandle userHandle, @NonNull @CallbackExecutor Executor executor,
3449                 @NonNull CallNotificationEventListener listener) {
3450             mPackageName = packageName;
3451             mUserHandle = userHandle;
3452             mExecutor = executor;
3453             mListener = listener;
3454         }
3455 
3456         @FlaggedApi(android.service.notification.Flags.FLAG_CALLSTYLE_CALLBACK_API)
3457         @Override
onCallNotificationPosted(String packageName, UserHandle userHandle)3458         public void onCallNotificationPosted(String packageName, UserHandle userHandle) {
3459             mExecutor.execute(() -> mListener.onCallNotificationPosted(packageName, userHandle));
3460         }
3461 
3462         @FlaggedApi(android.service.notification.Flags.FLAG_CALLSTYLE_CALLBACK_API)
3463         @Override
onCallNotificationRemoved(String packageName, UserHandle userHandle)3464         public void onCallNotificationRemoved(String packageName, UserHandle userHandle) {
3465             mExecutor.execute(() -> mListener.onCallNotificationRemoved(packageName, userHandle));
3466         }
3467     }
3468 
3469     /**
3470      * Register a listener to be notified when a call notification is posted or removed
3471      * for a specific package and user.
3472      *
3473      * @param packageName Which package to monitor
3474      * @param userHandle Which user to monitor
3475      * @param executor Callback will run on this executor
3476      * @param listener Listener to register
3477      * @hide
3478      */
3479     @SystemApi
3480     @RequiresPermission(allOf = {
3481         android.Manifest.permission.INTERACT_ACROSS_USERS,
3482         android.Manifest.permission.ACCESS_NOTIFICATIONS})
3483     @FlaggedApi(android.service.notification.Flags.FLAG_CALLSTYLE_CALLBACK_API)
3484     @SuppressLint("UserHandle")
registerCallNotificationEventListener(@onNull String packageName, @NonNull UserHandle userHandle, @NonNull @CallbackExecutor Executor executor, @NonNull CallNotificationEventListener listener)3485     public void registerCallNotificationEventListener(@NonNull String packageName,
3486             @NonNull UserHandle userHandle, @NonNull @CallbackExecutor Executor executor,
3487             @NonNull CallNotificationEventListener listener) {
3488         checkRequired("packageName", packageName);
3489         checkRequired("userHandle", userHandle);
3490         checkRequired("executor", executor);
3491         checkRequired("listener", listener);
3492         INotificationManager service = service();
3493         try {
3494             synchronized (mCallNotificationEventCallbacks) {
3495                 CallNotificationEventCallbackStub callbackStub =
3496                         new CallNotificationEventCallbackStub(packageName, userHandle,
3497                                 executor, listener);
3498                 mCallNotificationEventCallbacks.put(listener, callbackStub);
3499 
3500                 service.registerCallNotificationEventListener(packageName, userHandle,
3501                         callbackStub);
3502             }
3503         } catch (RemoteException e) {
3504             throw e.rethrowFromSystemServer();
3505         }
3506     }
3507 
3508     /**
3509      * Unregister a listener that was previously
3510      * registered with {@link #registerCallNotificationEventListener}
3511      *
3512      * @param listener Listener to unregister
3513      * @hide
3514      */
3515     @SystemApi
3516     @FlaggedApi(android.service.notification.Flags.FLAG_CALLSTYLE_CALLBACK_API)
3517     @RequiresPermission(allOf = {
3518         android.Manifest.permission.INTERACT_ACROSS_USERS,
3519         android.Manifest.permission.ACCESS_NOTIFICATIONS})
unregisterCallNotificationEventListener( @onNull CallNotificationEventListener listener)3520     public void unregisterCallNotificationEventListener(
3521             @NonNull CallNotificationEventListener listener) {
3522         checkRequired("listener", listener);
3523         INotificationManager service = service();
3524         try {
3525             synchronized (mCallNotificationEventCallbacks) {
3526                 CallNotificationEventCallbackStub callbackStub =
3527                         mCallNotificationEventCallbacks.remove(listener);
3528                 if (callbackStub != null) {
3529                     service.unregisterCallNotificationEventListener(callbackStub.mPackageName,
3530                             callbackStub.mUserHandle, callbackStub);
3531                 }
3532             }
3533         } catch (RemoteException e) {
3534             throw e.rethrowFromSystemServer();
3535         }
3536     }
3537 
3538     /**
3539      * Returns the list of {@link Adjustment} keys that the current approved
3540      * {@link android.service.notification.NotificationAssistantService} does not support.
3541      * @hide
3542      */
3543     @TestApi
3544     @FlaggedApi(android.service.notification.Flags.FLAG_NOTIFICATION_CLASSIFICATION)
getUnsupportedAdjustmentTypes()3545     public @NonNull Set<String> getUnsupportedAdjustmentTypes() {
3546         INotificationManager service = service();
3547         try {
3548             return new HashSet<>(service.getUnsupportedAdjustmentTypes());
3549         } catch (RemoteException e) {
3550             throw e.rethrowFromSystemServer();
3551         }
3552     }
3553 }
3554