• 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 android.annotation.IntDef;
20 import android.annotation.NonNull;
21 import android.annotation.Nullable;
22 import android.annotation.RequiresPermission;
23 import android.annotation.SdkConstant;
24 import android.annotation.SuppressLint;
25 import android.annotation.SystemApi;
26 import android.annotation.SystemService;
27 import android.annotation.TestApi;
28 import android.annotation.WorkerThread;
29 import android.app.Notification.Builder;
30 import android.compat.annotation.UnsupportedAppUsage;
31 import android.content.ComponentName;
32 import android.content.Context;
33 import android.content.Intent;
34 import android.content.pm.ParceledListSlice;
35 import android.content.pm.ShortcutInfo;
36 import android.graphics.drawable.Icon;
37 import android.net.Uri;
38 import android.os.Binder;
39 import android.os.Build;
40 import android.os.Bundle;
41 import android.os.Handler;
42 import android.os.IBinder;
43 import android.os.Parcel;
44 import android.os.Parcelable;
45 import android.os.RemoteException;
46 import android.os.ServiceManager;
47 import android.os.StrictMode;
48 import android.os.UserHandle;
49 import android.provider.Settings.Global;
50 import android.service.notification.Adjustment;
51 import android.service.notification.Condition;
52 import android.service.notification.StatusBarNotification;
53 import android.service.notification.ZenModeConfig;
54 import android.service.notification.ZenPolicy;
55 import android.util.Log;
56 import android.util.proto.ProtoOutputStream;
57 
58 import java.lang.annotation.Retention;
59 import java.lang.annotation.RetentionPolicy;
60 import java.util.ArrayList;
61 import java.util.Arrays;
62 import java.util.HashMap;
63 import java.util.List;
64 import java.util.Map;
65 import java.util.Objects;
66 
67 /**
68  * Class to notify the user of events that happen.  This is how you tell
69  * the user that something has happened in the background.
70  *
71  * <p>Notifications can take different forms:
72  * <ul>
73  *      <li>A persistent icon that goes in the status bar and is accessible
74  *          through the launcher, (when the user selects it, a designated Intent
75  *          can be launched),</li>
76  *      <li>Turning on or flashing LEDs on the device, or</li>
77  *      <li>Alerting the user by flashing the backlight, playing a sound,
78  *          or vibrating.</li>
79  * </ul>
80  *
81  * <p>
82  * Each of the notify methods takes an int id parameter and optionally a
83  * {@link String} tag parameter, which may be {@code null}.  These parameters
84  * are used to form a pair (tag, id), or ({@code null}, id) if tag is
85  * unspecified.  This pair identifies this notification from your app to the
86  * system, so that pair should be unique within your app.  If you call one
87  * of the notify methods with a (tag, id) pair that is currently active and
88  * a new set of notification parameters, it will be updated.  For example,
89  * if you pass a new status bar icon, the old icon in the status bar will
90  * be replaced with the new one.  This is also the same tag and id you pass
91  * to the {@link #cancel(int)} or {@link #cancel(String, int)} method to clear
92  * this notification.
93  *
94  * <div class="special reference">
95  * <h3>Developer Guides</h3>
96  * <p>For a guide to creating notifications, read the
97  * <a href="{@docRoot}guide/topics/ui/notifiers/notifications.html">Status Bar Notifications</a>
98  * developer guide.</p>
99  * </div>
100  *
101  * @see android.app.Notification
102  */
103 @SystemService(Context.NOTIFICATION_SERVICE)
104 public class NotificationManager {
105     private static String TAG = "NotificationManager";
106     private static boolean localLOGV = false;
107 
108     /**
109      * Intent that is broadcast when an application is blocked or unblocked.
110      *
111      * This broadcast is only sent to the app whose block state has changed.
112      *
113      * Input: nothing
114      * Output: {@link #EXTRA_BLOCKED_STATE}
115      */
116     @SdkConstant(SdkConstant.SdkConstantType.BROADCAST_INTENT_ACTION)
117     public static final String ACTION_APP_BLOCK_STATE_CHANGED =
118             "android.app.action.APP_BLOCK_STATE_CHANGED";
119 
120     /**
121      * Intent that is broadcast when a {@link NotificationChannel} is blocked
122      * (when {@link NotificationChannel#getImportance()} is {@link #IMPORTANCE_NONE}) or unblocked
123      * (when {@link NotificationChannel#getImportance()} is anything other than
124      * {@link #IMPORTANCE_NONE}).
125      *
126      * This broadcast is only sent to the app that owns the channel that has changed.
127      *
128      * Input: nothing
129      * Output: {@link #EXTRA_NOTIFICATION_CHANNEL_ID}
130      * Output: {@link #EXTRA_BLOCKED_STATE}
131      */
132     @SdkConstant(SdkConstant.SdkConstantType.BROADCAST_INTENT_ACTION)
133     public static final String ACTION_NOTIFICATION_CHANNEL_BLOCK_STATE_CHANGED =
134             "android.app.action.NOTIFICATION_CHANNEL_BLOCK_STATE_CHANGED";
135 
136     /**
137      * Activity action: Toggle notification panel of the specified handler.
138      *
139      * <p><strong>Important:</strong>You must protect the activity that handles this action with
140      * the {@link android.Manifest.permission#STATUS_BAR_SERVICE} permission to ensure that only
141      * the SystemUI can launch this activity. Activities that are not properly protected will not
142      * be launched.
143      *
144      * <p class="note">This is currently only used on TV to allow a system app to handle the
145      * notification panel. The package handling the notification panel has to be specified by
146      * config_notificationHandlerPackage in values/config.xml.
147      *
148      * Input: nothing
149      * Output: nothing
150      * @hide
151      */
152     @SystemApi
153     @RequiresPermission(android.Manifest.permission.STATUS_BAR_SERVICE)
154     @SdkConstant(SdkConstant.SdkConstantType.ACTIVITY_INTENT_ACTION)
155     public static final String ACTION_TOGGLE_NOTIFICATION_HANDLER_PANEL =
156             "android.app.action.TOGGLE_NOTIFICATION_HANDLER_PANEL";
157 
158     /**
159      * Activity action: Open notification panel of the specified handler.
160      *
161      * <p><strong>Important:</strong>You must protect the activity that handles this action with
162      * the {@link android.Manifest.permission#STATUS_BAR_SERVICE} permission to ensure that only
163      * the SystemUI can launch this activity. Activities that are not properly protected will
164      * not be launched.
165      *
166      * <p class="note"> This is currently only used on TV to allow a system app to handle the
167      * notification panel. The package handling the notification panel has to be specified by
168      * config_notificationHandlerPackage in values/config.xml.
169      *
170      * Input: nothing
171      * Output: nothing
172      * @hide
173      */
174     @SystemApi
175     @RequiresPermission(android.Manifest.permission.STATUS_BAR_SERVICE)
176     @SdkConstant(SdkConstant.SdkConstantType.ACTIVITY_INTENT_ACTION)
177     public static final String ACTION_OPEN_NOTIFICATION_HANDLER_PANEL =
178             "android.app.action.OPEN_NOTIFICATION_HANDLER_PANEL";
179 
180     /**
181      * Intent that is broadcast when the notification panel of the specified handler is to be
182      * closed.
183      *
184      * <p><strong>Important:</strong>You should protect the receiver that handles this action with
185      * the {@link android.Manifest.permission#STATUS_BAR_SERVICE} permission to ensure that only
186      * the SystemUI can send this broadcast to the notification handler.
187      *
188      * <p class="note"> This is currently only used on TV to allow a system app to handle the
189      * notification panel. The package handling the notification panel has to be specified by
190      * config_notificationHandlerPackage in values/config.xml. This is a protected intent that can
191      * only be sent by the system.
192      *
193      * Input: nothing.
194      * Output: nothing.
195      * @hide
196      */
197     @SystemApi
198     @RequiresPermission(android.Manifest.permission.STATUS_BAR_SERVICE)
199     @SdkConstant(SdkConstant.SdkConstantType.BROADCAST_INTENT_ACTION)
200     public static final String ACTION_CLOSE_NOTIFICATION_HANDLER_PANEL =
201             "android.app.action.CLOSE_NOTIFICATION_HANDLER_PANEL";
202 
203     /**
204      * Extra for {@link #ACTION_NOTIFICATION_CHANNEL_BLOCK_STATE_CHANGED} containing the id of the
205      * {@link NotificationChannel} which has a new blocked state.
206      *
207      * The value will be the {@link NotificationChannel#getId()} of the channel.
208      */
209     public static final String EXTRA_NOTIFICATION_CHANNEL_ID =
210             "android.app.extra.NOTIFICATION_CHANNEL_ID";
211 
212     /**
213      * Extra for {@link #ACTION_NOTIFICATION_CHANNEL_GROUP_BLOCK_STATE_CHANGED} containing the id
214      * of the {@link NotificationChannelGroup} which has a new blocked state.
215      *
216      * The value will be the {@link NotificationChannelGroup#getId()} of the group.
217      */
218     public static final String EXTRA_NOTIFICATION_CHANNEL_GROUP_ID =
219             "android.app.extra.NOTIFICATION_CHANNEL_GROUP_ID";
220 
221 
222     /**
223      * Extra for {@link #ACTION_NOTIFICATION_CHANNEL_BLOCK_STATE_CHANGED} or
224      * {@link #ACTION_NOTIFICATION_CHANNEL_GROUP_BLOCK_STATE_CHANGED} containing the new blocked
225      * state as a boolean.
226      *
227      * The value will be {@code true} if this channel or group is now blocked and {@code false} if
228      * this channel or group is now unblocked.
229      */
230     public static final String EXTRA_BLOCKED_STATE = "android.app.extra.BLOCKED_STATE";
231 
232     /**
233      * Intent that is broadcast when a {@link NotificationChannelGroup} is
234      * {@link NotificationChannelGroup#isBlocked() blocked} or unblocked.
235      *
236      * This broadcast is only sent to the app that owns the channel group that has changed.
237      *
238      * Input: nothing
239      * Output: {@link #EXTRA_NOTIFICATION_CHANNEL_GROUP_ID}
240      * Output: {@link #EXTRA_BLOCKED_STATE}
241      */
242     @SdkConstant(SdkConstant.SdkConstantType.BROADCAST_INTENT_ACTION)
243     public static final String ACTION_NOTIFICATION_CHANNEL_GROUP_BLOCK_STATE_CHANGED =
244             "android.app.action.NOTIFICATION_CHANNEL_GROUP_BLOCK_STATE_CHANGED";
245 
246     /**
247      * Intent that is broadcast when the status of an {@link AutomaticZenRule} has changed.
248      *
249      * <p>Use this to know whether you need to continue monitor to device state in order to
250      * provide up-to-date states (with {@link #setAutomaticZenRuleState(String, Condition)}) for
251      * this rule.</p>
252      *
253      * Input: nothing
254      * Output: {@link #EXTRA_AUTOMATIC_ZEN_RULE_ID}
255      * Output: {@link #EXTRA_AUTOMATIC_ZEN_RULE_STATUS}
256      */
257     @SdkConstant(SdkConstant.SdkConstantType.BROADCAST_INTENT_ACTION)
258     public static final String ACTION_AUTOMATIC_ZEN_RULE_STATUS_CHANGED =
259             "android.app.action.AUTOMATIC_ZEN_RULE_STATUS_CHANGED";
260 
261     /**
262      * Integer extra for {@link #ACTION_AUTOMATIC_ZEN_RULE_STATUS_CHANGED} containing the state of
263      * the {@link AutomaticZenRule}.
264      *
265      * <p>
266      *     The value will be one of {@link #AUTOMATIC_RULE_STATUS_ENABLED},
267      *     {@link #AUTOMATIC_RULE_STATUS_DISABLED}, {@link #AUTOMATIC_RULE_STATUS_REMOVED},
268      *     {@link #AUTOMATIC_RULE_STATUS_UNKNOWN}.
269      * </p>
270      */
271     public static final String EXTRA_AUTOMATIC_ZEN_RULE_STATUS =
272             "android.app.extra.AUTOMATIC_ZEN_RULE_STATUS";
273 
274     /**
275      * String extra for {@link #ACTION_AUTOMATIC_ZEN_RULE_STATUS_CHANGED} containing the id of the
276      * {@link AutomaticZenRule} (see {@link #addAutomaticZenRule(AutomaticZenRule)}) that has
277      * changed.
278      */
279     public static final String EXTRA_AUTOMATIC_ZEN_RULE_ID =
280             "android.app.extra.AUTOMATIC_ZEN_RULE_ID";
281 
282     /** @hide */
283     @IntDef(prefix = { "AUTOMATIC_RULE_STATUS" }, value = {
284             AUTOMATIC_RULE_STATUS_ENABLED, AUTOMATIC_RULE_STATUS_DISABLED,
285             AUTOMATIC_RULE_STATUS_REMOVED, AUTOMATIC_RULE_STATUS_UNKNOWN
286     })
287     @Retention(RetentionPolicy.SOURCE)
288     public @interface AutomaticZenRuleStatus {}
289 
290     /**
291      * Constant value for {@link #EXTRA_AUTOMATIC_ZEN_RULE_STATUS} - the current status of the
292      * rule is unknown at your target sdk version, and you should continue to provide state changes
293      * via {@link #setAutomaticZenRuleState(String, Condition)}.
294      */
295     public static final int AUTOMATIC_RULE_STATUS_UNKNOWN = -1;
296 
297     /**
298      * Constant value for {@link #EXTRA_AUTOMATIC_ZEN_RULE_STATUS} - the given rule currently
299      * exists and is enabled. You should continue to provide state changes via
300      * {@link #setAutomaticZenRuleState(String, Condition)}.
301      */
302     public static final int AUTOMATIC_RULE_STATUS_ENABLED = 1;
303 
304     /**
305      * Constant value for {@link #EXTRA_AUTOMATIC_ZEN_RULE_STATUS} - the given rule currently
306      * exists but is disabled. You do not need to continue to provide state changes via
307      * {@link #setAutomaticZenRuleState(String, Condition)} until the rule is reenabled.
308      */
309     public static final int AUTOMATIC_RULE_STATUS_DISABLED = 2;
310 
311     /**
312      * Constant value for {@link #EXTRA_AUTOMATIC_ZEN_RULE_STATUS} - the given rule has been
313      * deleted. Further calls to {@link #setAutomaticZenRuleState(String, Condition)} will be
314      * ignored.
315      */
316     public static final int AUTOMATIC_RULE_STATUS_REMOVED = 3;
317 
318     /**
319      * Intent that is broadcast when the state of {@link #getEffectsSuppressor()} changes.
320      *
321      * <p>This broadcast is only sent to registered receivers and (starting from
322      * {@link Build.VERSION_CODES#Q}) receivers in packages that have been granted Do Not
323      * Disturb access (see {@link #isNotificationPolicyAccessGranted()}).
324      *
325      * @hide
326      */
327     @SdkConstant(SdkConstant.SdkConstantType.BROADCAST_INTENT_ACTION)
328     public static final String ACTION_EFFECTS_SUPPRESSOR_CHANGED
329             = "android.os.action.ACTION_EFFECTS_SUPPRESSOR_CHANGED";
330 
331     /**
332      * Intent that is broadcast when the state of {@link #isNotificationPolicyAccessGranted()}
333      * changes.
334      *
335      * This broadcast is only sent to registered receivers, and only to the apps that have changed.
336      */
337     @SdkConstant(SdkConstant.SdkConstantType.BROADCAST_INTENT_ACTION)
338     public static final String ACTION_NOTIFICATION_POLICY_ACCESS_GRANTED_CHANGED
339             = "android.app.action.NOTIFICATION_POLICY_ACCESS_GRANTED_CHANGED";
340 
341     /**
342      * Intent that is broadcast when the state of getNotificationPolicy() changes.
343      *
344      * <p>This broadcast is only sent to registered receivers and (starting from
345      * {@link Build.VERSION_CODES#Q}) receivers in packages that have been granted Do Not
346      * Disturb access (see {@link #isNotificationPolicyAccessGranted()}).
347      */
348     @SdkConstant(SdkConstant.SdkConstantType.BROADCAST_INTENT_ACTION)
349     public static final String ACTION_NOTIFICATION_POLICY_CHANGED
350             = "android.app.action.NOTIFICATION_POLICY_CHANGED";
351 
352     /**
353      * Intent that is broadcast when the state of getCurrentInterruptionFilter() changes.
354      *
355      * <p>This broadcast is only sent to registered receivers and (starting from
356      * {@link Build.VERSION_CODES#Q}) receivers in packages that have been granted Do Not
357      * Disturb access (see {@link #isNotificationPolicyAccessGranted()}).
358      */
359     @SdkConstant(SdkConstant.SdkConstantType.BROADCAST_INTENT_ACTION)
360     public static final String ACTION_INTERRUPTION_FILTER_CHANGED
361             = "android.app.action.INTERRUPTION_FILTER_CHANGED";
362 
363     /**
364      * Intent that is broadcast when the state of
365      * {@link #hasEnabledNotificationListener(String, UserHandle)} changes.
366      * @hide
367      */
368     @SdkConstant(SdkConstant.SdkConstantType.BROADCAST_INTENT_ACTION)
369     @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
370     public static final String ACTION_NOTIFICATION_LISTENER_ENABLED_CHANGED =
371             "android.app.action.NOTIFICATION_LISTENER_ENABLED_CHANGED";
372 
373     /**
374      * Intent that is broadcast when the state of getCurrentInterruptionFilter() changes.
375      * @hide
376      */
377     @SdkConstant(SdkConstant.SdkConstantType.BROADCAST_INTENT_ACTION)
378     public static final String ACTION_INTERRUPTION_FILTER_CHANGED_INTERNAL
379             = "android.app.action.INTERRUPTION_FILTER_CHANGED_INTERNAL";
380 
381     /** @hide */
382     @IntDef(prefix = { "INTERRUPTION_FILTER_" }, value = {
383             INTERRUPTION_FILTER_NONE, INTERRUPTION_FILTER_PRIORITY, INTERRUPTION_FILTER_ALARMS,
384             INTERRUPTION_FILTER_ALL, INTERRUPTION_FILTER_UNKNOWN
385     })
386     @Retention(RetentionPolicy.SOURCE)
387     public @interface InterruptionFilter {}
388 
389     /**
390      * {@link #getCurrentInterruptionFilter() Interruption filter} constant -
391      *     Normal interruption filter - no notifications are suppressed.
392      */
393     public static final int INTERRUPTION_FILTER_ALL = 1;
394 
395     /**
396      * {@link #getCurrentInterruptionFilter() Interruption filter} constant -
397      *     Priority interruption filter - all notifications are suppressed except those that match
398      *     the priority criteria. Some audio streams are muted. See
399      *     {@link Policy#priorityCallSenders}, {@link Policy#priorityCategories},
400      *     {@link Policy#priorityMessageSenders} to define or query this criteria. Users can
401      *     additionally specify packages that can bypass this interruption filter.
402      */
403     public static final int INTERRUPTION_FILTER_PRIORITY = 2;
404 
405     /**
406      * {@link #getCurrentInterruptionFilter() Interruption filter} constant -
407      *     No interruptions filter - all notifications are suppressed and all audio streams (except
408      *     those used for phone calls) and vibrations are muted.
409      */
410     public static final int INTERRUPTION_FILTER_NONE = 3;
411 
412     /**
413      * {@link #getCurrentInterruptionFilter() Interruption filter} constant -
414      *     Alarms only interruption filter - all notifications except those of category
415      *     {@link Notification#CATEGORY_ALARM} are suppressed. Some audio streams are muted.
416      */
417     public static final int INTERRUPTION_FILTER_ALARMS = 4;
418 
419     /** {@link #getCurrentInterruptionFilter() Interruption filter} constant - returned when
420      * the value is unavailable for any reason.
421      */
422     public static final int INTERRUPTION_FILTER_UNKNOWN = 0;
423 
424     /** @hide */
425     @IntDef(prefix = { "IMPORTANCE_" }, value = {
426             IMPORTANCE_UNSPECIFIED, IMPORTANCE_NONE,
427             IMPORTANCE_MIN, IMPORTANCE_LOW, IMPORTANCE_DEFAULT, IMPORTANCE_HIGH
428     })
429     @Retention(RetentionPolicy.SOURCE)
430     public @interface Importance {}
431 
432     /** @hide */
433     @IntDef(prefix = { "BUBBLE_PREFERENCE_" }, value = {
434             BUBBLE_PREFERENCE_NONE, BUBBLE_PREFERENCE_SELECTED,
435             BUBBLE_PREFERENCE_ALL
436     })
437     @Retention(RetentionPolicy.SOURCE)
438     public @interface BubblePreference {}
439 
440     /**
441      * Activity Action: Launch an Automatic Zen Rule configuration screen
442      * <p>
443      * Input: Optionally, {@link #EXTRA_AUTOMATIC_RULE_ID}, if the configuration screen for an
444      * existing rule should be displayed. If the rule id is missing or null, apps should display
445      * a configuration screen where users can create a new instance of the rule.
446      * <p>
447      * Output: Nothing
448      * <p>
449      *     You can have multiple activities handling this intent, if you support multiple
450      *     {@link AutomaticZenRule rules}. In order for the system to properly display all of your
451      *     rule types so that users can create new instances or configure existing ones, you need
452      *     to add some extra metadata ({@link #META_DATA_AUTOMATIC_RULE_TYPE})
453      *     to your activity tag in your manifest. If you'd like to limit the number of rules a user
454      *     can create from this flow, you can additionally optionally include
455      *     {@link #META_DATA_RULE_INSTANCE_LIMIT}.
456      *
457      *     For example,
458      *     &lt;meta-data
459      *         android:name="android.app.zen.automatic.ruleType"
460      *         android:value="@string/my_condition_rule">
461      *     &lt;/meta-data>
462      *     &lt;meta-data
463      *         android:name="android.app.zen.automatic.ruleInstanceLimit"
464      *         android:value="1">
465      *     &lt;/meta-data>
466      * </p>
467      * </p>
468      *
469      * @see #addAutomaticZenRule(AutomaticZenRule)
470      */
471     @SdkConstant(SdkConstant.SdkConstantType.ACTIVITY_INTENT_ACTION)
472     public static final String ACTION_AUTOMATIC_ZEN_RULE =
473             "android.app.action.AUTOMATIC_ZEN_RULE";
474 
475     /**
476      * Used as an optional string extra on {@link #ACTION_AUTOMATIC_ZEN_RULE} intents. If
477      * provided, contains the id of the {@link AutomaticZenRule} (as returned from
478      * {@link NotificationManager#addAutomaticZenRule(AutomaticZenRule)}) for which configuration
479      * settings should be displayed.
480      */
481     public static final String EXTRA_AUTOMATIC_RULE_ID = "android.app.extra.AUTOMATIC_RULE_ID";
482 
483     /**
484      * A required {@code meta-data} tag for activities that handle
485      * {@link #ACTION_AUTOMATIC_ZEN_RULE}.
486      *
487      * This tag should contain a localized name of the type of the zen rule provided by the
488      * activity.
489      */
490     public static final String META_DATA_AUTOMATIC_RULE_TYPE =
491             "android.service.zen.automatic.ruleType";
492 
493     /**
494      * An optional {@code meta-data} tag for activities that handle
495      * {@link #ACTION_AUTOMATIC_ZEN_RULE}.
496      *
497      * This tag should contain the maximum number of rule instances that
498      * can be created for this rule type. Omit or enter a value <= 0 to allow unlimited instances.
499      */
500     public static final String META_DATA_RULE_INSTANCE_LIMIT =
501             "android.service.zen.automatic.ruleInstanceLimit";
502 
503     /** Value signifying that the user has not expressed a per-app visibility override value.
504      * @hide */
505     public static final int VISIBILITY_NO_OVERRIDE = -1000;
506 
507     /**
508      * Value signifying that the user has not expressed an importance.
509      *
510      * This value is for persisting preferences, and should never be associated with
511      * an actual notification.
512      */
513     public static final int IMPORTANCE_UNSPECIFIED = -1000;
514 
515     /**
516      * A notification with no importance: does not show in the shade.
517      */
518     public static final int IMPORTANCE_NONE = 0;
519 
520     /**
521      * Min notification importance: only shows in the shade, below the fold.  This should
522      * not be used with {@link Service#startForeground(int, Notification) Service.startForeground}
523      * since a foreground service is supposed to be something the user cares about so it does
524      * not make semantic sense to mark its notification as minimum importance.  If you do this
525      * as of Android version {@link android.os.Build.VERSION_CODES#O}, the system will show
526      * a higher-priority notification about your app running in the background.
527      */
528     public static final int IMPORTANCE_MIN = 1;
529 
530     /**
531      * Low notification importance: Shows in the shade, and potentially in the status bar
532      * (see {@link #shouldHideSilentStatusBarIcons()}), but is not audibly intrusive.
533      */
534     public static final int IMPORTANCE_LOW = 2;
535 
536     /**
537      * Default notification importance: shows everywhere, makes noise, but does not visually
538      * intrude.
539      */
540     public static final int IMPORTANCE_DEFAULT = 3;
541 
542     /**
543      * Higher notification importance: shows everywhere, makes noise and peeks. May use full screen
544      * intents.
545      */
546     public static final int IMPORTANCE_HIGH = 4;
547 
548     /**
549      * Unused.
550      */
551     public static final int IMPORTANCE_MAX = 5;
552 
553     /**
554      * Indicates that the no bubbles are allowed from the app. If the app sends bubbles, only the
555      * notification will appear. The notification will have an affordance allowing the user to
556      * bubble it. If the user selects this affordance, that notification is approved to bubble
557      * and the apps' bubble preference will be upgraded to {@link #BUBBLE_PREFERENCE_SELECTED}.
558      */
559     public static final int BUBBLE_PREFERENCE_NONE = 0;
560 
561     /**
562      * Indicates that all bubbles are allowed from the app. If the app sends bubbles, the bubble
563      * will appear along with the notification.
564      */
565     public static final int BUBBLE_PREFERENCE_ALL = 1;
566 
567     /**
568      * Indicates that only notifications selected by the user will appear as bubbles. If
569      * the app sends bubbles that haven't been selected, only the notification appear. If the
570      * bubble has been approved by the user, it will appear along with the notification.
571      */
572     public static final int BUBBLE_PREFERENCE_SELECTED = 2;
573 
574     @UnsupportedAppUsage
575     private static INotificationManager sService;
576 
577     /** @hide */
578     @UnsupportedAppUsage
getService()579     static public INotificationManager getService()
580     {
581         if (sService != null) {
582             return sService;
583         }
584         IBinder b = ServiceManager.getService("notification");
585         sService = INotificationManager.Stub.asInterface(b);
586         return sService;
587     }
588 
589     @UnsupportedAppUsage
NotificationManager(Context context, Handler handler)590     /*package*/ NotificationManager(Context context, Handler handler)
591     {
592         mContext = context;
593     }
594 
595     /** {@hide} */
596     @UnsupportedAppUsage
from(Context context)597     public static NotificationManager from(Context context) {
598         return (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
599     }
600 
601     /**
602      * Post a notification to be shown in the status bar. If a notification with
603      * the same id has already been posted by your application and has not yet been canceled, it
604      * will be replaced by the updated information.
605      *
606      * @param id An identifier for this notification unique within your
607      *        application.
608      * @param notification A {@link Notification} object describing what to show the user. Must not
609      *        be null.
610      */
notify(int id, Notification notification)611     public void notify(int id, Notification notification)
612     {
613         notify(null, id, notification);
614     }
615 
616     /**
617      * Posts a notification to be shown in the status bar. If a notification with
618      * the same tag and id has already been posted by your application and has not yet been
619      * canceled, it will be replaced by the updated information.
620      *
621      * All {@link android.service.notification.NotificationListenerService listener services} will
622      * be granted {@link Intent#FLAG_GRANT_READ_URI_PERMISSION} access to any {@link Uri uris}
623      * provided on this notification or the
624      * {@link NotificationChannel} this notification is posted to using
625      * {@link Context#grantUriPermission(String, Uri, int)}. Permission will be revoked when the
626      * notification is canceled, or you can revoke permissions with
627      * {@link Context#revokeUriPermission(Uri, int)}.
628      *
629      * @param tag A string identifier for this notification.  May be {@code null}.
630      * @param id An identifier for this notification.  The pair (tag, id) must be unique
631      *        within your application.
632      * @param notification A {@link Notification} object describing what to
633      *        show the user. Must not be null.
634      */
notify(String tag, int id, Notification notification)635     public void notify(String tag, int id, Notification notification)
636     {
637         notifyAsUser(tag, id, notification, mContext.getUser());
638     }
639 
640     /**
641      * Posts a notification as a specified package to be shown in the status bar. If a notification
642      * with the same tag and id has already been posted for that package and has not yet been
643      * canceled, it will be replaced by the updated information.
644      *
645      * All {@link android.service.notification.NotificationListenerService listener services} will
646      * be granted {@link Intent#FLAG_GRANT_READ_URI_PERMISSION} access to any {@link Uri uris}
647      * provided on this notification or the
648      * {@link NotificationChannel} this notification is posted to using
649      * {@link Context#grantUriPermission(String, Uri, int)}. Permission will be revoked when the
650      * notification is canceled, or you can revoke permissions with
651      * {@link Context#revokeUriPermission(Uri, int)}.
652      *
653      * @param targetPackage The package to post the notification as. The package must have granted
654      *                      you access to post notifications on their behalf with
655      *                      {@link #setNotificationDelegate(String)}.
656      * @param tag A string identifier for this notification.  May be {@code null}.
657      * @param id An identifier for this notification.  The pair (tag, id) must be unique
658      *        within your application.
659      * @param notification A {@link Notification} object describing what to
660      *        show the user. Must not be null.
661      */
notifyAsPackage(@onNull String targetPackage, @Nullable String tag, int id, @NonNull Notification notification)662     public void notifyAsPackage(@NonNull String targetPackage, @Nullable String tag, int id,
663             @NonNull Notification notification) {
664         INotificationManager service = getService();
665         String sender = mContext.getPackageName();
666 
667         try {
668             if (localLOGV) Log.v(TAG, sender + ": notify(" + id + ", " + notification + ")");
669             service.enqueueNotificationWithTag(targetPackage, sender, tag, id,
670                     fixNotification(notification), mContext.getUser().getIdentifier());
671         } catch (RemoteException e) {
672             throw e.rethrowFromSystemServer();
673         }
674     }
675 
676     /**
677      * @hide
678      */
679     @UnsupportedAppUsage
notifyAsUser(String tag, int id, Notification notification, UserHandle user)680     public void notifyAsUser(String tag, int id, Notification notification, UserHandle user)
681     {
682         INotificationManager service = getService();
683         String pkg = mContext.getPackageName();
684 
685         try {
686             if (localLOGV) Log.v(TAG, pkg + ": notify(" + id + ", " + notification + ")");
687             service.enqueueNotificationWithTag(pkg, mContext.getOpPackageName(), tag, id,
688                     fixNotification(notification), user.getIdentifier());
689         } catch (RemoteException e) {
690             throw e.rethrowFromSystemServer();
691         }
692     }
693 
fixNotification(Notification notification)694     private Notification fixNotification(Notification notification) {
695         String pkg = mContext.getPackageName();
696         // Fix the notification as best we can.
697         Notification.addFieldsFromContext(mContext, notification);
698 
699         if (notification.sound != null) {
700             notification.sound = notification.sound.getCanonicalUri();
701             if (StrictMode.vmFileUriExposureEnabled()) {
702                 notification.sound.checkFileUriExposed("Notification.sound");
703             }
704 
705         }
706         fixLegacySmallIcon(notification, pkg);
707         if (mContext.getApplicationInfo().targetSdkVersion > Build.VERSION_CODES.LOLLIPOP_MR1) {
708             if (notification.getSmallIcon() == null) {
709                 throw new IllegalArgumentException("Invalid notification (no valid small icon): "
710                         + notification);
711             }
712         }
713 
714         notification.reduceImageSizes(mContext);
715         return Builder.maybeCloneStrippedForDelivery(notification);
716     }
717 
fixLegacySmallIcon(Notification n, String pkg)718     private void fixLegacySmallIcon(Notification n, String pkg) {
719         if (n.getSmallIcon() == null && n.icon != 0) {
720             n.setSmallIcon(Icon.createWithResource(pkg, n.icon));
721         }
722     }
723 
724     /**
725      * Cancels a previously posted notification.
726      *
727      *  <p>If the notification does not currently represent a
728      *  {@link Service#startForeground(int, Notification) foreground service}, it will be
729      *  removed from the UI and live
730      *  {@link android.service.notification.NotificationListenerService notification listeners}
731      *  will be informed so they can remove the notification from their UIs.</p>
732      */
cancel(int id)733     public void cancel(int id)
734     {
735         cancel(null, id);
736     }
737 
738     /**
739      * Cancels a previously posted notification.
740      *
741      *  <p>If the notification does not currently represent a
742      *  {@link Service#startForeground(int, Notification) foreground service}, it will be
743      *  removed from the UI and live
744      *  {@link android.service.notification.NotificationListenerService notification listeners}
745      *  will be informed so they can remove the notification from their UIs.</p>
746      */
cancel(@ullable String tag, int id)747     public void cancel(@Nullable String tag, int id)
748     {
749         cancelAsUser(tag, id, mContext.getUser());
750     }
751 
752     /**
753      * Cancels a previously posted notification.
754      *
755      * <p>If the notification does not currently represent a
756      * {@link Service#startForeground(int, Notification) foreground service}, it will be
757      * removed from the UI and live
758      * {@link android.service.notification.NotificationListenerService notification listeners}
759      * will be informed so they can remove the notification from their UIs.</p>
760      *
761      * <p>This method may be used by {@link #getNotificationDelegate() a notification delegate} to
762      * cancel notifications that they have posted via {@link #notifyAsPackage(String, String, int,
763      * Notification)}.</p>
764      *
765      * @param targetPackage The package to cancel the notification as. If this package is not your
766      *                      package, you can only cancel notifications you posted with
767      *                      {@link #notifyAsPackage(String, String, int, Notification).
768      * @param tag A string identifier for this notification.  May be {@code null}.
769      * @param id An identifier for this notification.
770      */
cancelAsPackage(@onNull String targetPackage, @Nullable String tag, int id)771     public void cancelAsPackage(@NonNull String targetPackage, @Nullable String tag, int id) {
772         INotificationManager service = getService();
773         try {
774             service.cancelNotificationWithTag(targetPackage, mContext.getOpPackageName(),
775                     tag, id, mContext.getUser().getIdentifier());
776         } catch (RemoteException e) {
777             throw e.rethrowFromSystemServer();
778         }
779     }
780 
781     /**
782      * @hide
783      */
784     @UnsupportedAppUsage
cancelAsUser(String tag, int id, UserHandle user)785     public void cancelAsUser(String tag, int id, UserHandle user)
786     {
787         INotificationManager service = getService();
788         String pkg = mContext.getPackageName();
789         if (localLOGV) Log.v(TAG, pkg + ": cancel(" + id + ")");
790         try {
791             service.cancelNotificationWithTag(
792                     pkg, mContext.getOpPackageName(), tag, id, user.getIdentifier());
793         } catch (RemoteException e) {
794             throw e.rethrowFromSystemServer();
795         }
796     }
797 
798     /**
799      * Cancel all previously shown notifications. See {@link #cancel} for the
800      * detailed behavior.
801      */
cancelAll()802     public void cancelAll()
803     {
804         INotificationManager service = getService();
805         String pkg = mContext.getPackageName();
806         if (localLOGV) Log.v(TAG, pkg + ": cancelAll()");
807         try {
808             service.cancelAllNotifications(pkg, mContext.getUserId());
809         } catch (RemoteException e) {
810             throw e.rethrowFromSystemServer();
811         }
812     }
813 
814     /**
815      * Allows a package to post notifications on your behalf using
816      * {@link #notifyAsPackage(String, String, int, Notification)}.
817      *
818      * This can be used to allow persistent processes to post notifications based on messages
819      * received on your behalf from the cloud, without your process having to wake up.
820      *
821      * You can check if you have an allowed delegate with {@link #getNotificationDelegate()} and
822      * revoke your delegate by passing null to this method.
823      *
824      * @param delegate Package name of the app which can send notifications on your behalf.
825      */
setNotificationDelegate(@ullable String delegate)826     public void setNotificationDelegate(@Nullable String delegate) {
827         INotificationManager service = getService();
828         String pkg = mContext.getPackageName();
829         if (localLOGV) Log.v(TAG, pkg + ": cancelAll()");
830         try {
831             service.setNotificationDelegate(pkg, delegate);
832         } catch (RemoteException e) {
833             throw e.rethrowFromSystemServer();
834         }
835     }
836 
837     /**
838      * Returns the {@link #setNotificationDelegate(String) delegate} that can post notifications on
839      * your behalf, if there currently is one.
840      */
getNotificationDelegate()841     public @Nullable String getNotificationDelegate() {
842         INotificationManager service = getService();
843         String pkg = mContext.getPackageName();
844         try {
845             return service.getNotificationDelegate(pkg);
846         } catch (RemoteException e) {
847             throw e.rethrowFromSystemServer();
848         }
849     }
850 
851     /**
852      * Returns whether you are allowed to post notifications on behalf of a given package, with
853      * {@link #notifyAsPackage(String, String, int, Notification)}.
854      *
855      * See {@link #setNotificationDelegate(String)}.
856      */
canNotifyAsPackage(@onNull String pkg)857     public boolean canNotifyAsPackage(@NonNull String pkg) {
858         INotificationManager service = getService();
859         try {
860             return service.canNotifyAsPackage(mContext.getPackageName(), pkg, mContext.getUserId());
861         } catch (RemoteException e) {
862             throw e.rethrowFromSystemServer();
863         }
864     }
865 
866     /**
867      * Creates a group container for {@link NotificationChannel} objects.
868      *
869      * This can be used to rename an existing group.
870      * <p>
871      *     Group information is only used for presentation, not for behavior. Groups are optional
872      *     for channels, and you can have a mix of channels that belong to groups and channels
873      *     that do not.
874      * </p>
875      * <p>
876      *     For example, if your application supports multiple accounts, and those accounts will
877      *     have similar channels, you can create a group for each account with account specific
878      *     labels instead of appending account information to each channel's label.
879      * </p>
880      *
881      * @param group The group to create
882      */
createNotificationChannelGroup(@onNull NotificationChannelGroup group)883     public void createNotificationChannelGroup(@NonNull NotificationChannelGroup group) {
884         createNotificationChannelGroups(Arrays.asList(group));
885     }
886 
887     /**
888      * Creates multiple notification channel groups.
889      *
890      * @param groups The list of groups to create
891      */
createNotificationChannelGroups(@onNull List<NotificationChannelGroup> groups)892     public void createNotificationChannelGroups(@NonNull List<NotificationChannelGroup> groups) {
893         INotificationManager service = getService();
894         try {
895             service.createNotificationChannelGroups(mContext.getPackageName(),
896                     new ParceledListSlice(groups));
897         } catch (RemoteException e) {
898             throw e.rethrowFromSystemServer();
899         }
900     }
901 
902     /**
903      * Creates a notification channel that notifications can be posted to.
904      *
905      * This can also be used to restore a deleted channel and to update an existing channel's
906      * name, description, group, and/or importance.
907      *
908      * <p>The name and description should only be changed if the locale changes
909      * or in response to the user renaming this channel. For example, if a user has a channel
910      * named 'Messages' and the user changes their locale, this channel's name should be updated
911      * with the translation of 'Messages' in the new locale.
912      *
913      * <p>The importance of an existing channel will only be changed if the new importance is lower
914      * than the current value and the user has not altered any settings on this channel.
915      *
916      * <p>The group an existing channel will only be changed if the channel does not already
917      * belong to a group.
918      *
919      * All other fields are ignored for channels that already exist.
920      *
921      * @param channel  the channel to create.  Note that the created channel may differ from this
922      *                 value. If the provided channel is malformed, a RemoteException will be
923      *                 thrown.
924      */
createNotificationChannel(@onNull NotificationChannel channel)925     public void createNotificationChannel(@NonNull NotificationChannel channel) {
926         createNotificationChannels(Arrays.asList(channel));
927     }
928 
929     /**
930      * Creates multiple notification channels that different notifications can be posted to. See
931      * {@link #createNotificationChannel(NotificationChannel)}.
932      *
933      * @param channels the list of channels to attempt to create.
934      */
createNotificationChannels(@onNull List<NotificationChannel> channels)935     public void createNotificationChannels(@NonNull List<NotificationChannel> channels) {
936         INotificationManager service = getService();
937         try {
938             service.createNotificationChannels(mContext.getPackageName(),
939                     new ParceledListSlice(channels));
940         } catch (RemoteException e) {
941             throw e.rethrowFromSystemServer();
942         }
943     }
944 
945     /**
946      * Returns the notification channel settings for a given channel id.
947      *
948      * <p>The channel must belong to your package, or to a package you are an approved notification
949      * delegate for (see {@link #canNotifyAsPackage(String)}), or it will not be returned. To query
950      * a channel as a notification delegate, call this method from a context created for that
951      * package (see {@link Context#createPackageContext(String, int)}).</p>
952      */
getNotificationChannel(String channelId)953     public NotificationChannel getNotificationChannel(String channelId) {
954         INotificationManager service = getService();
955         try {
956             return service.getNotificationChannel(mContext.getOpPackageName(),
957                     mContext.getUserId(), mContext.getPackageName(), channelId);
958         } catch (RemoteException e) {
959             throw e.rethrowFromSystemServer();
960         }
961     }
962 
963     /**
964      * Returns the notification channel settings for a given channel and
965      * {@link ShortcutInfo#getId() conversation id}.
966      *
967      * <p>The channel must belong to your package, or to a package you are an approved notification
968      * delegate for (see {@link #canNotifyAsPackage(String)}), or it will not be returned. To query
969      * a channel as a notification delegate, call this method from a context created for that
970      * package (see {@link Context#createPackageContext(String, int)}).</p>
971      */
getNotificationChannel(@onNull String channelId, @NonNull String conversationId)972     public @Nullable NotificationChannel getNotificationChannel(@NonNull String channelId,
973             @NonNull String conversationId) {
974         INotificationManager service = getService();
975         try {
976             return service.getConversationNotificationChannel(mContext.getOpPackageName(),
977                     mContext.getUserId(), mContext.getPackageName(), channelId, true,
978                     conversationId);
979         } catch (RemoteException e) {
980             throw e.rethrowFromSystemServer();
981         }
982     }
983 
984     /**
985      * Returns all notification channels belonging to the calling package.
986      *
987      * <p>Approved notification delegates (see {@link #canNotifyAsPackage(String)}) can query
988      * notification channels belonging to packages they are the delegate for. To do so, call this
989      * method from a context created for that package (see
990      * {@link Context#createPackageContext(String, int)}).</p>
991      */
getNotificationChannels()992     public List<NotificationChannel> getNotificationChannels() {
993         INotificationManager service = getService();
994         try {
995             return service.getNotificationChannels(mContext.getOpPackageName(),
996                     mContext.getPackageName(), mContext.getUserId()).getList();
997         } catch (RemoteException e) {
998             throw e.rethrowFromSystemServer();
999         }
1000     }
1001 
1002     /**
1003      * Deletes the given notification channel.
1004      *
1005      * <p>If you {@link #createNotificationChannel(NotificationChannel) create} a new channel with
1006      * this same id, the deleted channel will be un-deleted with all of the same settings it
1007      * had before it was deleted.
1008      */
deleteNotificationChannel(String channelId)1009     public void deleteNotificationChannel(String channelId) {
1010         INotificationManager service = getService();
1011         try {
1012             service.deleteNotificationChannel(mContext.getPackageName(), channelId);
1013         } catch (RemoteException e) {
1014             throw e.rethrowFromSystemServer();
1015         }
1016     }
1017 
1018     /**
1019      * Returns the notification channel group settings for a given channel group id.
1020      *
1021      * The channel group must belong to your package, or null will be returned.
1022      */
getNotificationChannelGroup(String channelGroupId)1023     public NotificationChannelGroup getNotificationChannelGroup(String channelGroupId) {
1024         INotificationManager service = getService();
1025         try {
1026             return service.getNotificationChannelGroup(mContext.getPackageName(), channelGroupId);
1027         } catch (RemoteException e) {
1028             throw e.rethrowFromSystemServer();
1029         }
1030     }
1031 
1032     /**
1033      * Returns all notification channel groups belonging to the calling app.
1034      */
getNotificationChannelGroups()1035     public List<NotificationChannelGroup> getNotificationChannelGroups() {
1036         INotificationManager service = getService();
1037         try {
1038             final ParceledListSlice<NotificationChannelGroup> parceledList =
1039                     service.getNotificationChannelGroups(mContext.getPackageName());
1040             if (parceledList != null) {
1041                 return parceledList.getList();
1042             }
1043         } catch (RemoteException e) {
1044             throw e.rethrowFromSystemServer();
1045         }
1046         return new ArrayList<>();
1047     }
1048 
1049     /**
1050      * Deletes the given notification channel group, and all notification channels that
1051      * belong to it.
1052      */
deleteNotificationChannelGroup(String groupId)1053     public void deleteNotificationChannelGroup(String groupId) {
1054         INotificationManager service = getService();
1055         try {
1056             service.deleteNotificationChannelGroup(mContext.getPackageName(), groupId);
1057         } catch (RemoteException e) {
1058             throw e.rethrowFromSystemServer();
1059         }
1060     }
1061 
1062     /**
1063      * @hide
1064      */
1065     @TestApi
updateNotificationChannel(@onNull String pkg, int uid, @NonNull NotificationChannel channel)1066     public void updateNotificationChannel(@NonNull String pkg, int uid,
1067             @NonNull NotificationChannel channel) {
1068         INotificationManager service = getService();
1069         try {
1070             service.updateNotificationChannelForPackage(pkg, uid, channel);
1071         } catch (RemoteException e) {
1072             throw e.rethrowFromSystemServer();
1073         }
1074     }
1075 
1076     /**
1077      * @hide
1078      */
1079     @TestApi
getEffectsSuppressor()1080     public ComponentName getEffectsSuppressor() {
1081         INotificationManager service = getService();
1082         try {
1083             return service.getEffectsSuppressor();
1084         } catch (RemoteException e) {
1085             throw e.rethrowFromSystemServer();
1086         }
1087     }
1088 
1089     /**
1090      * @hide
1091      */
matchesCallFilter(Bundle extras)1092     public boolean matchesCallFilter(Bundle extras) {
1093         INotificationManager service = getService();
1094         try {
1095             return service.matchesCallFilter(extras);
1096         } catch (RemoteException e) {
1097             throw e.rethrowFromSystemServer();
1098         }
1099     }
1100 
1101     /**
1102      * @hide
1103      */
1104     @TestApi
cleanUpCallersAfter(long timeThreshold)1105     public void cleanUpCallersAfter(long timeThreshold) {
1106         INotificationManager service = getService();
1107         try {
1108             service.cleanUpCallersAfter(timeThreshold);
1109         } catch (RemoteException e) {
1110             throw e.rethrowFromSystemServer();
1111         }
1112     }
1113 
1114     /**
1115      * @hide
1116      */
isSystemConditionProviderEnabled(String path)1117     public boolean isSystemConditionProviderEnabled(String path) {
1118         INotificationManager service = getService();
1119         try {
1120             return service.isSystemConditionProviderEnabled(path);
1121         } catch (RemoteException e) {
1122             throw e.rethrowFromSystemServer();
1123         }
1124     }
1125 
1126     /**
1127      * @hide
1128      */
1129     @UnsupportedAppUsage
setZenMode(int mode, Uri conditionId, String reason)1130     public void setZenMode(int mode, Uri conditionId, String reason) {
1131         INotificationManager service = getService();
1132         try {
1133             service.setZenMode(mode, conditionId, reason);
1134         } catch (RemoteException e) {
1135             throw e.rethrowFromSystemServer();
1136         }
1137     }
1138 
1139     /**
1140      * @hide
1141      */
getZenMode()1142     public int getZenMode() {
1143         INotificationManager service = getService();
1144         try {
1145             return service.getZenMode();
1146         } catch (RemoteException e) {
1147             throw e.rethrowFromSystemServer();
1148         }
1149     }
1150 
1151     /**
1152      * @hide
1153      */
1154     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
getZenModeConfig()1155     public ZenModeConfig getZenModeConfig() {
1156         INotificationManager service = getService();
1157         try {
1158             return service.getZenModeConfig();
1159         } catch (RemoteException e) {
1160             throw e.rethrowFromSystemServer();
1161         }
1162     }
1163 
1164     /**
1165      * Returns the currently applied notification policy.
1166      *
1167      * <p>
1168      * If {@link #getCurrentInterruptionFilter} is equal to {@link #INTERRUPTION_FILTER_ALL},
1169      * then the consolidated notification policy will match the default notification policy
1170      * returned by {@link #getNotificationPolicy}.
1171      * </p>
1172      */
getConsolidatedNotificationPolicy()1173     public @NonNull NotificationManager.Policy getConsolidatedNotificationPolicy() {
1174         INotificationManager service = getService();
1175         try {
1176             return service.getConsolidatedNotificationPolicy();
1177         } catch (RemoteException e) {
1178             throw e.rethrowFromSystemServer();
1179         }
1180     }
1181 
1182     /**
1183      * @hide
1184      */
getRuleInstanceCount(ComponentName owner)1185     public int getRuleInstanceCount(ComponentName owner) {
1186         INotificationManager service = getService();
1187         try {
1188             return service.getRuleInstanceCount(owner);
1189         } catch (RemoteException e) {
1190             throw e.rethrowFromSystemServer();
1191         }
1192     }
1193 
1194     /**
1195      * Returns AutomaticZenRules owned by the caller.
1196      *
1197      * <p>
1198      * Throws a SecurityException if policy access is not granted to this package.
1199      * See {@link #isNotificationPolicyAccessGranted}.
1200      */
getAutomaticZenRules()1201     public Map<String, AutomaticZenRule> getAutomaticZenRules() {
1202         INotificationManager service = getService();
1203         try {
1204             List<ZenModeConfig.ZenRule> rules = service.getZenRules();
1205             Map<String, AutomaticZenRule> ruleMap = new HashMap<>();
1206             for (ZenModeConfig.ZenRule rule : rules) {
1207                 AutomaticZenRule azr = new AutomaticZenRule(rule.name, rule.component,
1208                         rule.configurationActivity, rule.conditionId, rule.zenPolicy,
1209                         zenModeToInterruptionFilter(rule.zenMode), rule.enabled,
1210                         rule.creationTime);
1211                 azr.setPackageName(rule.pkg);
1212                 ruleMap.put(rule.id, azr);
1213             }
1214             return ruleMap;
1215         } catch (RemoteException e) {
1216             throw e.rethrowFromSystemServer();
1217         }
1218     }
1219 
1220     /**
1221      * Returns the AutomaticZenRule with the given id, if it exists and the caller has access.
1222      *
1223      * <p>
1224      * Throws a SecurityException if policy access is not granted to this package.
1225      * See {@link #isNotificationPolicyAccessGranted}.
1226      *
1227      * <p>
1228      * Returns null if there are no zen rules that match the given id, or if the calling package
1229      * doesn't own the matching rule. See {@link AutomaticZenRule#getOwner}.
1230      */
getAutomaticZenRule(String id)1231     public AutomaticZenRule getAutomaticZenRule(String id) {
1232         INotificationManager service = getService();
1233         try {
1234             return service.getAutomaticZenRule(id);
1235         } catch (RemoteException e) {
1236             throw e.rethrowFromSystemServer();
1237         }
1238     }
1239 
1240     /**
1241      * Creates the given zen rule.
1242      *
1243      * <p>
1244      * Throws a SecurityException if policy access is not granted to this package.
1245      * See {@link #isNotificationPolicyAccessGranted}.
1246      *
1247      * @param automaticZenRule the rule to create.
1248      * @return The id of the newly created rule; null if the rule could not be created.
1249      */
addAutomaticZenRule(AutomaticZenRule automaticZenRule)1250     public String addAutomaticZenRule(AutomaticZenRule automaticZenRule) {
1251         INotificationManager service = getService();
1252         try {
1253             return service.addAutomaticZenRule(automaticZenRule, mContext.getPackageName());
1254         } catch (RemoteException e) {
1255             throw e.rethrowFromSystemServer();
1256         }
1257     }
1258 
1259     /**
1260      * Updates the given zen rule.
1261      *
1262      * <p>
1263      * Throws a SecurityException if policy access is not granted to this package.
1264      * See {@link #isNotificationPolicyAccessGranted}.
1265      *
1266      * <p>
1267      * Callers can only update rules that they own. See {@link AutomaticZenRule#getOwner}.
1268      * @param id The id of the rule to update
1269      * @param automaticZenRule the rule to update.
1270      * @return Whether the rule was successfully updated.
1271      */
updateAutomaticZenRule(String id, AutomaticZenRule automaticZenRule)1272     public boolean updateAutomaticZenRule(String id, AutomaticZenRule automaticZenRule) {
1273         INotificationManager service = getService();
1274         try {
1275             return service.updateAutomaticZenRule(id, automaticZenRule);
1276         } catch (RemoteException e) {
1277             throw e.rethrowFromSystemServer();
1278         }
1279     }
1280 
1281     /**
1282      * Informs the notification manager that the state of an {@link AutomaticZenRule} has changed.
1283      * Use this method to put the system into Do Not Disturb mode or request that it exits Do Not
1284      * Disturb mode. The calling app must own the provided {@link android.app.AutomaticZenRule}.
1285      * <p>
1286      *     This method can be used in conjunction with or as a replacement to
1287      *     {@link android.service.notification.ConditionProviderService#notifyCondition(Condition)}.
1288      * </p>
1289      * @param id The id of the rule whose state should change
1290      * @param condition The new state of this rule
1291      */
setAutomaticZenRuleState(@onNull String id, @NonNull Condition condition)1292     public void setAutomaticZenRuleState(@NonNull String id, @NonNull Condition condition) {
1293         INotificationManager service = getService();
1294         try {
1295             service.setAutomaticZenRuleState(id, condition);
1296         } catch (RemoteException e) {
1297             throw e.rethrowFromSystemServer();
1298         }
1299     }
1300 
1301     /**
1302      * Deletes the automatic zen rule with the given id.
1303      *
1304      * <p>
1305      * Throws a SecurityException if policy access is not granted to this package.
1306      * See {@link #isNotificationPolicyAccessGranted}.
1307      *
1308      * <p>
1309      * Callers can only delete rules that they own. See {@link AutomaticZenRule#getOwner}.
1310      * @param id the id of the rule to delete.
1311      * @return Whether the rule was successfully deleted.
1312      */
removeAutomaticZenRule(String id)1313     public boolean removeAutomaticZenRule(String id) {
1314         INotificationManager service = getService();
1315         try {
1316             return service.removeAutomaticZenRule(id);
1317         } catch (RemoteException e) {
1318             throw e.rethrowFromSystemServer();
1319         }
1320     }
1321 
1322     /**
1323      * Deletes all automatic zen rules owned by the given package.
1324      *
1325      * @hide
1326      */
removeAutomaticZenRules(String packageName)1327     public boolean removeAutomaticZenRules(String packageName) {
1328         INotificationManager service = getService();
1329         try {
1330             return service.removeAutomaticZenRules(packageName);
1331         } catch (RemoteException e) {
1332             throw e.rethrowFromSystemServer();
1333         }
1334     }
1335 
1336     /**
1337      * Returns the user specified importance for notifications from the calling
1338      * package.
1339      */
getImportance()1340     public @Importance int getImportance() {
1341         INotificationManager service = getService();
1342         try {
1343             return service.getPackageImportance(mContext.getPackageName());
1344         } catch (RemoteException e) {
1345             throw e.rethrowFromSystemServer();
1346         }
1347     }
1348 
1349     /**
1350      * Returns whether notifications from the calling package are blocked.
1351      */
areNotificationsEnabled()1352     public boolean areNotificationsEnabled() {
1353         INotificationManager service = getService();
1354         try {
1355             return service.areNotificationsEnabled(mContext.getPackageName());
1356         } catch (RemoteException e) {
1357             throw e.rethrowFromSystemServer();
1358         }
1359     }
1360 
1361     /**
1362      * Gets whether all notifications posted by this app can appear outside of the
1363      * notification shade, floating over other apps' content.
1364      *
1365      * <p>This value will be ignored for notifications that are posted to channels that do not
1366      * allow bubbles ({@link NotificationChannel#canBubble()}).
1367      *
1368      * @see Notification#getBubbleMetadata()
1369      * @deprecated use {@link #getBubblePreference()} instead.
1370      */
1371     @Deprecated
areBubblesAllowed()1372     public boolean areBubblesAllowed() {
1373         INotificationManager service = getService();
1374         try {
1375             return service.areBubblesAllowed(mContext.getPackageName());
1376         } catch (RemoteException e) {
1377             throw e.rethrowFromSystemServer();
1378         }
1379     }
1380 
1381     /**
1382      * Returns whether bubbles are enabled at the feature level for the current user. When enabled,
1383      * notifications able to bubble will display an affordance allowing the user to bubble them.
1384      *
1385      * @see Notification.Builder#setBubbleMetadata(Notification.BubbleMetadata)
1386      */
areBubblesEnabled()1387     public boolean areBubblesEnabled() {
1388         INotificationManager service = getService();
1389         try {
1390             return service.areBubblesEnabled(mContext.getUser());
1391         } catch (RemoteException e) {
1392             throw e.rethrowFromSystemServer();
1393         }
1394     }
1395 
1396     /**
1397      * Gets the bubble preference for the app. This preference only applies to notifications that
1398      * have been properly configured to bubble.
1399      *
1400      * <p>
1401      * If {@link #BUBBLE_PREFERENCE_ALL}, then any bubble notification will appear as a bubble, as
1402      * long as the user hasn't excluded it ({@link NotificationChannel#canBubble()}).
1403      *
1404      * <p>
1405      * If {@link #BUBBLE_PREFERENCE_SELECTED}, then any bubble notification will appear as a bubble,
1406      * as long as the user has selected it.
1407      *
1408      * <p>
1409      * If {@link #BUBBLE_PREFERENCE_NONE}, then no notification may appear as a bubble from the app.
1410      *
1411      * @see Notification#getBubbleMetadata()
1412      * @return the users' bubble preference for the app.
1413      */
getBubblePreference()1414     public @BubblePreference int getBubblePreference() {
1415         INotificationManager service = getService();
1416         try {
1417             return service.getBubblePreferenceForPackage(mContext.getPackageName(),
1418                     Binder.getCallingUid());
1419         } catch (RemoteException e) {
1420             throw e.rethrowFromSystemServer();
1421         }
1422     }
1423 
1424     /**
1425      * Silences the current notification sound, if ones currently playing.
1426      * <p>
1427      * It is intended to handle use-cases such as silencing a ringing call
1428      * when the user presses the volume button during ringing.
1429      * <p>
1430      * If this method is called prior to when the notification begins playing, the sound will not be
1431      * silenced.  As such it is not intended as a means to avoid playing of a sound.
1432      * @hide
1433      */
silenceNotificationSound()1434     public void silenceNotificationSound() {
1435         INotificationManager service = getService();
1436         try {
1437             service.silenceNotificationSound();
1438         } catch (RemoteException e) {
1439             throw e.rethrowFromSystemServer();
1440         }
1441     }
1442 
1443     /**
1444      * Returns whether notifications from this package are temporarily hidden. This
1445      * could be done because the package was marked as distracting to the user via
1446      * {@code PackageManager#setDistractingPackageRestrictions(String[], int)} or because the
1447      * package is {@code PackageManager#setPackagesSuspended(String[], boolean, PersistableBundle,
1448      * PersistableBundle, SuspendDialogInfo) suspended}.
1449      */
areNotificationsPaused()1450     public boolean areNotificationsPaused() {
1451         INotificationManager service = getService();
1452         try {
1453             return service.isPackagePaused(mContext.getPackageName());
1454         } catch (RemoteException e) {
1455             throw e.rethrowFromSystemServer();
1456         }
1457     }
1458 
1459     /**
1460      * Checks the ability to modify notification do not disturb policy for the calling package.
1461      *
1462      * <p>
1463      * Returns true if the calling package can modify notification policy.
1464      *
1465      * <p>
1466      * Apps can request policy access by sending the user to the activity that matches the system
1467      * intent action {@link android.provider.Settings#ACTION_NOTIFICATION_POLICY_ACCESS_SETTINGS}.
1468      *
1469      * <p>
1470      * Use {@link #ACTION_NOTIFICATION_POLICY_ACCESS_GRANTED_CHANGED} to listen for
1471      * user grant or denial of this access.
1472      */
isNotificationPolicyAccessGranted()1473     public boolean isNotificationPolicyAccessGranted() {
1474         INotificationManager service = getService();
1475         try {
1476             return service.isNotificationPolicyAccessGranted(mContext.getOpPackageName());
1477         } catch (RemoteException e) {
1478             throw e.rethrowFromSystemServer();
1479         }
1480     }
1481 
1482     /**
1483      * Checks whether the user has approved a given
1484      * {@link android.service.notification.NotificationListenerService}.
1485      *
1486      * <p>
1487      * The listener service must belong to the calling app.
1488      *
1489      * <p>
1490      * Apps can request notification listener access by sending the user to the activity that
1491      * matches the system intent action
1492      * {@link android.provider.Settings#ACTION_NOTIFICATION_LISTENER_SETTINGS}.
1493      */
isNotificationListenerAccessGranted(ComponentName listener)1494     public boolean isNotificationListenerAccessGranted(ComponentName listener) {
1495         INotificationManager service = getService();
1496         try {
1497             return service.isNotificationListenerAccessGranted(listener);
1498         } catch (RemoteException e) {
1499             throw e.rethrowFromSystemServer();
1500         }
1501     }
1502 
1503     /**
1504      * Checks whether the user has approved a given
1505      * {@link android.service.notification.NotificationAssistantService}.
1506      *
1507      * <p>
1508      * The assistant service must belong to the calling app.
1509      *
1510      * <p>
1511      * Apps can request notification assistant access by sending the user to the activity that
1512      * matches the system intent action
1513      * TODO: STOPSHIP: Add correct intent
1514      * {@link android.provider.Settings#ACTION_MANAGE_DEFAULT_APPS_SETTINGS}.
1515      * @hide
1516      */
1517     @SystemApi
isNotificationAssistantAccessGranted(@onNull ComponentName assistant)1518     public boolean isNotificationAssistantAccessGranted(@NonNull ComponentName assistant) {
1519         INotificationManager service = getService();
1520         try {
1521             return service.isNotificationAssistantAccessGranted(assistant);
1522         } catch (RemoteException e) {
1523             throw e.rethrowFromSystemServer();
1524         }
1525     }
1526 
1527     /**
1528      * Returns whether the user wants silent notifications (see {@link #IMPORTANCE_LOW} to appear
1529      * in the status bar.
1530      *
1531      * <p>Only available for {@link #isNotificationListenerAccessGranted(ComponentName) notification
1532      * listeners}.
1533      */
shouldHideSilentStatusBarIcons()1534     public boolean shouldHideSilentStatusBarIcons() {
1535         INotificationManager service = getService();
1536         try {
1537             return service.shouldHideSilentStatusIcons(mContext.getOpPackageName());
1538         } catch (RemoteException e) {
1539             throw e.rethrowFromSystemServer();
1540         }
1541     }
1542 
1543     /**
1544      * Returns the list of {@link android.service.notification.Adjustment adjustment keys} that can
1545      * be modified by the current {@link android.service.notification.NotificationAssistantService}.
1546      *
1547      * <p>Only callable by the current
1548      * {@link android.service.notification.NotificationAssistantService}.
1549      * See {@link #isNotificationAssistantAccessGranted(ComponentName)}</p>
1550      * @hide
1551      */
1552     @SystemApi
getAllowedAssistantAdjustments()1553     public @NonNull @Adjustment.Keys List<String> getAllowedAssistantAdjustments() {
1554         INotificationManager service = getService();
1555         try {
1556             return service.getAllowedAssistantAdjustments(mContext.getOpPackageName());
1557         } catch (RemoteException e) {
1558             throw e.rethrowFromSystemServer();
1559         }
1560     }
1561 
1562     /**
1563      * @hide
1564      */
1565     @TestApi
allowAssistantAdjustment(String capability)1566     public void allowAssistantAdjustment(String capability) {
1567         INotificationManager service = getService();
1568         try {
1569             service.allowAssistantAdjustment(capability);
1570         } catch (RemoteException e) {
1571             throw e.rethrowFromSystemServer();
1572         }
1573     }
1574 
1575     /**
1576      * @hide
1577      */
1578     @TestApi
disallowAssistantAdjustment(String capability)1579     public void disallowAssistantAdjustment(String capability) {
1580         INotificationManager service = getService();
1581         try {
1582             service.disallowAssistantAdjustment(capability);
1583         } catch (RemoteException e) {
1584             throw e.rethrowFromSystemServer();
1585         }
1586     }
1587 
1588     /** @hide */
1589     @TestApi
isNotificationPolicyAccessGrantedForPackage(@onNull String pkg)1590     public boolean isNotificationPolicyAccessGrantedForPackage(@NonNull String pkg) {
1591         INotificationManager service = getService();
1592         try {
1593             return service.isNotificationPolicyAccessGrantedForPackage(pkg);
1594         } catch (RemoteException e) {
1595             throw e.rethrowFromSystemServer();
1596         }
1597     }
1598 
1599     /**
1600      * @hide
1601      */
getEnabledNotificationListenerPackages()1602     public List<String> getEnabledNotificationListenerPackages() {
1603         INotificationManager service = getService();
1604         try {
1605             return service.getEnabledNotificationListenerPackages();
1606         } catch (RemoteException e) {
1607             throw e.rethrowFromSystemServer();
1608         }
1609     }
1610 
1611     /**
1612      * Gets the current user-specified default notification policy.
1613      *
1614      * <p>
1615      */
getNotificationPolicy()1616     public Policy getNotificationPolicy() {
1617         INotificationManager service = getService();
1618         try {
1619             return service.getNotificationPolicy(mContext.getOpPackageName());
1620         } catch (RemoteException e) {
1621             throw e.rethrowFromSystemServer();
1622         }
1623     }
1624 
1625     /**
1626      * Sets the current notification policy.
1627      *
1628      * <p>
1629      * Only available if policy access is granted to this package.
1630      * See {@link #isNotificationPolicyAccessGranted}.
1631      *
1632      * @param policy The new desired policy.
1633      */
setNotificationPolicy(@onNull Policy policy)1634     public void setNotificationPolicy(@NonNull Policy policy) {
1635         checkRequired("policy", policy);
1636         INotificationManager service = getService();
1637         try {
1638             service.setNotificationPolicy(mContext.getOpPackageName(), policy);
1639         } catch (RemoteException e) {
1640             throw e.rethrowFromSystemServer();
1641         }
1642     }
1643 
1644     /** @hide */
setNotificationPolicyAccessGranted(String pkg, boolean granted)1645     public void setNotificationPolicyAccessGranted(String pkg, boolean granted) {
1646         INotificationManager service = getService();
1647         try {
1648             service.setNotificationPolicyAccessGranted(pkg, granted);
1649         } catch (RemoteException e) {
1650             throw e.rethrowFromSystemServer();
1651         }
1652     }
1653 
1654     /** @hide */
setNotificationListenerAccessGranted( @onNull ComponentName listener, boolean granted)1655     public void setNotificationListenerAccessGranted(
1656             @NonNull ComponentName listener, boolean granted) {
1657         setNotificationListenerAccessGranted(listener, granted, true);
1658     }
1659 
1660     /**
1661      * Grants/revokes Notification Listener access to the given component for current user.
1662      * To grant access for a particular user, obtain this service by using the {@link Context}
1663      * provided by {@link Context#createPackageContextAsUser}
1664      *
1665      * @param listener Name of component to grant/revoke access
1666      * @param granted Grant/revoke access
1667      * @param userSet Whether the action was triggered explicitly by user
1668      * @hide
1669      */
1670     @SystemApi
1671     @TestApi
1672     @RequiresPermission(android.Manifest.permission.MANAGE_NOTIFICATION_LISTENERS)
setNotificationListenerAccessGranted( @onNull ComponentName listener, boolean granted, boolean userSet)1673     public void setNotificationListenerAccessGranted(
1674             @NonNull ComponentName listener, boolean granted, boolean userSet) {
1675         INotificationManager service = getService();
1676         try {
1677             service.setNotificationListenerAccessGranted(listener, granted, userSet);
1678         } catch (RemoteException e) {
1679             throw e.rethrowFromSystemServer();
1680         }
1681     }
1682 
1683     /** @hide */
setNotificationListenerAccessGrantedForUser(ComponentName listener, int userId, boolean granted)1684     public void setNotificationListenerAccessGrantedForUser(ComponentName listener, int userId,
1685             boolean granted) {
1686         INotificationManager service = getService();
1687         try {
1688             service.setNotificationListenerAccessGrantedForUser(listener, userId, granted, true);
1689         } catch (RemoteException e) {
1690             throw e.rethrowFromSystemServer();
1691         }
1692     }
1693 
1694     /**
1695      * Grants/revokes Notification Assistant access to {@code assistant} for current user.
1696      * To grant access for a particular user, obtain this service by using the {@link Context}
1697      * provided by {@link Context#createPackageContextAsUser}
1698      *
1699      * @param assistant Name of component to grant/revoke access or {@code null} to revoke access to
1700      *                  current assistant
1701      * @param granted Grant/revoke access
1702      * @hide
1703      */
1704     @SystemApi
setNotificationAssistantAccessGranted(@ullable ComponentName assistant, boolean granted)1705     public void setNotificationAssistantAccessGranted(@Nullable ComponentName assistant,
1706             boolean granted) {
1707         INotificationManager service = getService();
1708         try {
1709             service.setNotificationAssistantAccessGranted(assistant, granted);
1710         } catch (RemoteException e) {
1711             throw e.rethrowFromSystemServer();
1712         }
1713     }
1714 
1715     /**
1716      * Gets the list of enabled notification listener components for current user.
1717      * To query for a particular user, obtain this service by using the {@link Context}
1718      * provided by {@link Context#createPackageContextAsUser}
1719      *
1720      * @return the list of {@link ComponentName}s of the notification listeners
1721      * @hide
1722      */
1723     @SystemApi
1724     @RequiresPermission(android.Manifest.permission.MANAGE_NOTIFICATION_LISTENERS)
getEnabledNotificationListeners()1725     public @NonNull List<ComponentName> getEnabledNotificationListeners() {
1726         return getEnabledNotificationListeners(mContext.getUserId());
1727     }
1728 
1729     /** @hide */
getEnabledNotificationListeners(int userId)1730     public List<ComponentName> getEnabledNotificationListeners(int userId) {
1731         INotificationManager service = getService();
1732         try {
1733             return service.getEnabledNotificationListeners(userId);
1734         } catch (RemoteException e) {
1735             throw e.rethrowFromSystemServer();
1736         }
1737     }
1738 
1739     /** @hide */
1740     @SystemApi
getAllowedNotificationAssistant()1741     public @Nullable ComponentName getAllowedNotificationAssistant() {
1742         INotificationManager service = getService();
1743         try {
1744             return service.getAllowedNotificationAssistant();
1745         } catch (RemoteException e) {
1746             throw e.rethrowFromSystemServer();
1747         }
1748     }
1749 
1750     /**
1751      * Whether the given user has an enabled
1752      * {@link android.service.notification.NotificationListenerService} with the given package name.
1753      *
1754      * @param packageName the package name of the NotificationListenerService class
1755      * @param userHandle the handle of the user that set the listener
1756      * @hide
1757      */
1758     @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
1759     @SuppressLint("UserHandle")
hasEnabledNotificationListener(@onNull String packageName, @NonNull UserHandle userHandle)1760     public boolean hasEnabledNotificationListener(@NonNull String packageName,
1761             @NonNull UserHandle userHandle) {
1762         INotificationManager service = getService();
1763         try {
1764             return service.hasEnabledNotificationListener(packageName, userHandle.getIdentifier());
1765         } catch (RemoteException e) {
1766             throw e.rethrowFromSystemServer();
1767         }
1768     }
1769 
1770     private Context mContext;
1771 
checkRequired(String name, Object value)1772     private static void checkRequired(String name, Object value) {
1773         if (value == null) {
1774             throw new IllegalArgumentException(name + " is required");
1775         }
1776     }
1777 
1778     /**
1779      * Controls whether toast rate limiting is enabled for the calling uid.
1780      *
1781      * @param enable true to enable toast rate limiting, false to disable it
1782      * @hide
1783      */
1784     @TestApi
1785     @RequiresPermission(android.Manifest.permission.MANAGE_TOAST_RATE_LIMITING)
setToastRateLimitingEnabled(boolean enable)1786     public void setToastRateLimitingEnabled(boolean enable) {
1787         INotificationManager service = getService();
1788         try {
1789             service.setToastRateLimitingEnabled(enable);
1790         } catch (RemoteException e) {
1791             throw e.rethrowFromSystemServer();
1792         }
1793     }
1794 
1795     /**
1796      * Notification policy configuration.  Represents user-preferences for notification
1797      * filtering.
1798      */
1799     public static class Policy implements android.os.Parcelable {
1800         /** Reminder notifications are prioritized. */
1801         public static final int PRIORITY_CATEGORY_REMINDERS = 1 << 0;
1802         /** Event notifications are prioritized. */
1803         public static final int PRIORITY_CATEGORY_EVENTS = 1 << 1;
1804         /** Message notifications are prioritized. */
1805         public static final int PRIORITY_CATEGORY_MESSAGES = 1 << 2;
1806         /** Calls are prioritized. */
1807         public static final int PRIORITY_CATEGORY_CALLS = 1 << 3;
1808         /** Calls from repeat callers are prioritized. */
1809         public static final int PRIORITY_CATEGORY_REPEAT_CALLERS = 1 << 4;
1810         /** Alarms are prioritized */
1811         public static final int PRIORITY_CATEGORY_ALARMS = 1 << 5;
1812         /** Media, game, voice navigation are prioritized */
1813         public static final int PRIORITY_CATEGORY_MEDIA = 1 << 6;
1814         /**System (catch-all for non-never suppressible sounds) are prioritized */
1815         public static final int PRIORITY_CATEGORY_SYSTEM = 1 << 7;
1816         /**
1817          * Conversations are allowed through DND.
1818          */
1819         public static final int PRIORITY_CATEGORY_CONVERSATIONS = 1 << 8;
1820 
1821         /**
1822          * @hide
1823          */
1824         public static final int[] ALL_PRIORITY_CATEGORIES = {
1825                 PRIORITY_CATEGORY_ALARMS,
1826                 PRIORITY_CATEGORY_MEDIA,
1827                 PRIORITY_CATEGORY_SYSTEM,
1828                 PRIORITY_CATEGORY_REMINDERS,
1829                 PRIORITY_CATEGORY_EVENTS,
1830                 PRIORITY_CATEGORY_MESSAGES,
1831                 PRIORITY_CATEGORY_CALLS,
1832                 PRIORITY_CATEGORY_REPEAT_CALLERS,
1833                 PRIORITY_CATEGORY_CONVERSATIONS,
1834         };
1835 
1836         /** @hide */
1837         @IntDef(prefix = { "PRIORITY_SENDERS_" }, value = {
1838                 PRIORITY_SENDERS_ANY,
1839                 PRIORITY_SENDERS_CONTACTS,
1840                 PRIORITY_SENDERS_STARRED,
1841         })
1842         @Retention(RetentionPolicy.SOURCE)
1843         public @interface PrioritySenders {}
1844 
1845         /** Any sender is prioritized. */
1846         public static final int PRIORITY_SENDERS_ANY = 0;
1847         /** Saved contacts are prioritized. */
1848         public static final int PRIORITY_SENDERS_CONTACTS = 1;
1849         /** Only starred contacts are prioritized. */
1850         public static final int PRIORITY_SENDERS_STARRED = 2;
1851 
1852 
1853         /** @hide */
1854         @IntDef(prefix = { "CONVERSATION_SENDERS_" }, value = {
1855                 CONVERSATION_SENDERS_ANYONE,
1856                 CONVERSATION_SENDERS_IMPORTANT,
1857                 CONVERSATION_SENDERS_NONE,
1858         })
1859         @Retention(RetentionPolicy.SOURCE)
1860         public @interface ConversationSenders {}
1861         /**
1862          * Used to indicate all conversations can bypass dnd.
1863          */
1864         public static final int CONVERSATION_SENDERS_ANYONE = ZenPolicy.CONVERSATION_SENDERS_ANYONE;
1865 
1866         /**
1867          * Used to indicate important conversations can bypass dnd.
1868          */
1869         public static final int CONVERSATION_SENDERS_IMPORTANT =
1870                 ZenPolicy.CONVERSATION_SENDERS_IMPORTANT;
1871 
1872         /**
1873          * Used to indicate no conversations can bypass dnd.
1874          */
1875         public static final int CONVERSATION_SENDERS_NONE = ZenPolicy.CONVERSATION_SENDERS_NONE;
1876 
1877         /** Notification categories to prioritize. Bitmask of PRIORITY_CATEGORY_* constants. */
1878         public final int priorityCategories;
1879 
1880         /** Notification senders to prioritize for calls. One of:
1881          * PRIORITY_SENDERS_ANY, PRIORITY_SENDERS_CONTACTS, PRIORITY_SENDERS_STARRED */
1882         public final int priorityCallSenders;
1883 
1884         /** Notification senders to prioritize for messages. One of:
1885          * PRIORITY_SENDERS_ANY, PRIORITY_SENDERS_CONTACTS, PRIORITY_SENDERS_STARRED */
1886         public final int priorityMessageSenders;
1887 
1888         /**
1889          * Notification senders to prioritize for conversations. One of:
1890          * {@link #CONVERSATION_SENDERS_NONE}, {@link #CONVERSATION_SENDERS_IMPORTANT},
1891          * {@link #CONVERSATION_SENDERS_ANYONE}.
1892          */
1893         public final int priorityConversationSenders;
1894 
1895         /**
1896          * @hide
1897          */
1898         public static final int CONVERSATION_SENDERS_UNSET = -1;
1899 
1900         /**
1901          * @hide
1902          */
1903         public static final int SUPPRESSED_EFFECTS_UNSET = -1;
1904 
1905         /**
1906          * Whether notifications suppressed by DND should not interrupt visually (e.g. with
1907          * notification lights or by turning the screen on) when the screen is off.
1908          *
1909          * @deprecated use {@link #SUPPRESSED_EFFECT_FULL_SCREEN_INTENT} and
1910          * {@link #SUPPRESSED_EFFECT_AMBIENT} and {@link #SUPPRESSED_EFFECT_LIGHTS} individually.
1911          */
1912         @Deprecated
1913         public static final int SUPPRESSED_EFFECT_SCREEN_OFF = 1 << 0;
1914         /**
1915          * Whether notifications suppressed by DND should not interrupt visually when the screen
1916          * is on (e.g. by peeking onto the screen).
1917          *
1918          * @deprecated use {@link #SUPPRESSED_EFFECT_PEEK}.
1919          */
1920         @Deprecated
1921         public static final int SUPPRESSED_EFFECT_SCREEN_ON = 1 << 1;
1922 
1923         /**
1924          * Whether {@link Notification#fullScreenIntent full screen intents} from
1925          * notifications intercepted by DND are blocked.
1926          */
1927         public static final int SUPPRESSED_EFFECT_FULL_SCREEN_INTENT = 1 << 2;
1928 
1929         /**
1930          * Whether {@link NotificationChannel#shouldShowLights() notification lights} from
1931          * notifications intercepted by DND are blocked.
1932          */
1933         public static final int SUPPRESSED_EFFECT_LIGHTS = 1 << 3;
1934 
1935         /**
1936          * Whether notifications intercepted by DND are prevented from peeking.
1937          */
1938         public static final int SUPPRESSED_EFFECT_PEEK = 1 << 4;
1939 
1940         /**
1941          * Whether notifications intercepted by DND are prevented from appearing in the status bar,
1942          * on devices that support status bars.
1943          */
1944         public static final int SUPPRESSED_EFFECT_STATUS_BAR = 1 << 5;
1945 
1946         /**
1947          * Whether {@link NotificationChannel#canShowBadge() badges} from
1948          * notifications intercepted by DND are blocked on devices that support badging.
1949          */
1950         public static final int SUPPRESSED_EFFECT_BADGE = 1 << 6;
1951 
1952         /**
1953          * Whether notification intercepted by DND are prevented from appearing on ambient displays
1954          * on devices that support ambient display.
1955          */
1956         public static final int SUPPRESSED_EFFECT_AMBIENT = 1 << 7;
1957 
1958         /**
1959          * Whether notification intercepted by DND are prevented from appearing in notification
1960          * list views like the notification shade or lockscreen on devices that support those
1961          * views.
1962          */
1963         public static final int SUPPRESSED_EFFECT_NOTIFICATION_LIST = 1 << 8;
1964 
1965         private static final int[] ALL_SUPPRESSED_EFFECTS = {
1966                 SUPPRESSED_EFFECT_SCREEN_OFF,
1967                 SUPPRESSED_EFFECT_SCREEN_ON,
1968                 SUPPRESSED_EFFECT_FULL_SCREEN_INTENT,
1969                 SUPPRESSED_EFFECT_LIGHTS,
1970                 SUPPRESSED_EFFECT_PEEK,
1971                 SUPPRESSED_EFFECT_STATUS_BAR,
1972                 SUPPRESSED_EFFECT_BADGE,
1973                 SUPPRESSED_EFFECT_AMBIENT,
1974                 SUPPRESSED_EFFECT_NOTIFICATION_LIST
1975         };
1976 
1977         /**
1978          * Visual effects to suppress for a notification that is filtered by Do Not Disturb mode.
1979          * Bitmask of SUPPRESSED_EFFECT_* constants.
1980          */
1981         public final int suppressedVisualEffects;
1982 
1983         /**
1984          * @hide
1985          */
1986         public static final int STATE_CHANNELS_BYPASSING_DND = 1 << 0;
1987 
1988         /**
1989          * @hide
1990          */
1991         public static final int STATE_UNSET = -1;
1992 
1993         /**
1994          * Notification state information that is necessary to determine Do Not Disturb behavior.
1995          * Bitmask of STATE_* constants.
1996          * @hide
1997          */
1998         public final int state;
1999 
2000         /**
2001          * Constructs a policy for Do Not Disturb priority mode behavior.
2002          *
2003          * <p>
2004          *     Apps that target API levels below {@link Build.VERSION_CODES#P} cannot
2005          *     change user-designated values to allow or disallow
2006          *     {@link Policy#PRIORITY_CATEGORY_ALARMS}, {@link Policy#PRIORITY_CATEGORY_SYSTEM}, and
2007          *     {@link Policy#PRIORITY_CATEGORY_MEDIA} from bypassing dnd.
2008          *
2009          * @param priorityCategories bitmask of categories of notifications that can bypass DND.
2010          * @param priorityCallSenders which callers can bypass DND.
2011          * @param priorityMessageSenders which message senders can bypass DND.
2012          */
Policy(int priorityCategories, int priorityCallSenders, int priorityMessageSenders)2013         public Policy(int priorityCategories, int priorityCallSenders, int priorityMessageSenders) {
2014             this(priorityCategories, priorityCallSenders, priorityMessageSenders,
2015                     SUPPRESSED_EFFECTS_UNSET, STATE_UNSET, CONVERSATION_SENDERS_UNSET);
2016         }
2017 
2018         /**
2019          * Constructs a policy for Do Not Disturb priority mode behavior.
2020          *
2021          * <p>
2022          *     Apps that target API levels below {@link Build.VERSION_CODES#R} cannot
2023          *     change user-designated values to allow or disallow
2024          *     {@link Policy#PRIORITY_CATEGORY_CONVERSATIONS}, from bypassing dnd.
2025          * <p>
2026          *     Additionally, apps that target API levels below {@link Build.VERSION_CODES#P} can
2027          *     only modify the {@link #SUPPRESSED_EFFECT_SCREEN_ON} and
2028          *     {@link #SUPPRESSED_EFFECT_SCREEN_OFF} bits of the suppressed visual effects field.
2029          *     All other suppressed effects will be ignored and reconstituted from the screen on
2030          *     and screen off values.
2031          * <p>
2032          *     Apps that target {@link Build.VERSION_CODES#P} or above can set any
2033          *     suppressed visual effects. However, if any suppressed effects >
2034          *     {@link #SUPPRESSED_EFFECT_SCREEN_ON} are set, {@link #SUPPRESSED_EFFECT_SCREEN_ON}
2035          *     and {@link #SUPPRESSED_EFFECT_SCREEN_OFF} will be ignored and reconstituted from
2036          *     the more specific suppressed visual effect bits. Apps should migrate to targeting
2037          *     specific effects instead of the deprecated {@link #SUPPRESSED_EFFECT_SCREEN_ON} and
2038          *     {@link #SUPPRESSED_EFFECT_SCREEN_OFF} effects.
2039          *
2040          * @param priorityCategories bitmask of categories of notifications that can bypass DND.
2041          * @param priorityCallSenders which callers can bypass DND.
2042          * @param priorityMessageSenders which message senders can bypass DND.
2043          * @param suppressedVisualEffects which visual interruptions should be suppressed from
2044          *                                notifications that are filtered by DND.
2045          */
Policy(int priorityCategories, int priorityCallSenders, int priorityMessageSenders, int suppressedVisualEffects)2046         public Policy(int priorityCategories, int priorityCallSenders, int priorityMessageSenders,
2047                 int suppressedVisualEffects) {
2048             this(priorityCategories, priorityCallSenders, priorityMessageSenders,
2049                     suppressedVisualEffects, STATE_UNSET, CONVERSATION_SENDERS_UNSET);
2050         }
2051 
2052         /**
2053          * Constructs a policy for Do Not Disturb priority mode behavior.
2054          *
2055          * <p>
2056          *     Apps that target API levels below {@link Build.VERSION_CODES#P} cannot
2057          *     change user-designated values to allow or disallow
2058          *     {@link Policy#PRIORITY_CATEGORY_CONVERSATIONS} from bypassing dnd. If you do need
2059          *     to change them, use a {@link ZenPolicy} associated with an {@link AutomaticZenRule}
2060          *     instead of changing the global setting.
2061          * <p>
2062          *     Apps that target API levels below {@link Build.VERSION_CODES#P} cannot
2063          *     change user-designated values to allow or disallow
2064          *     {@link Policy#PRIORITY_CATEGORY_ALARMS},
2065          *     {@link Policy#PRIORITY_CATEGORY_SYSTEM}, and
2066          *     {@link Policy#PRIORITY_CATEGORY_MEDIA} from bypassing dnd.
2067          * <p>
2068          *     Additionally, apps that target API levels below {@link Build.VERSION_CODES#P} can
2069          *     only modify the {@link #SUPPRESSED_EFFECT_SCREEN_ON} and
2070          *     {@link #SUPPRESSED_EFFECT_SCREEN_OFF} bits of the suppressed visual effects field.
2071          *     All other suppressed effects will be ignored and reconstituted from the screen on
2072          *     and screen off values.
2073          * <p>
2074          *     Apps that target {@link Build.VERSION_CODES#P} or above can set any
2075          *     suppressed visual effects. However, if any suppressed effects >
2076          *     {@link #SUPPRESSED_EFFECT_SCREEN_ON} are set, {@link #SUPPRESSED_EFFECT_SCREEN_ON}
2077          *     and {@link #SUPPRESSED_EFFECT_SCREEN_OFF} will be ignored and reconstituted from
2078          *     the more specific suppressed visual effect bits. Apps should migrate to targeting
2079          *     specific effects instead of the deprecated {@link #SUPPRESSED_EFFECT_SCREEN_ON} and
2080          *     {@link #SUPPRESSED_EFFECT_SCREEN_OFF} effects.
2081          *
2082          * @param priorityCategories bitmask of categories of notifications that can bypass DND.
2083          * @param priorityCallSenders which callers can bypass DND.
2084          * @param priorityMessageSenders which message senders can bypass DND.
2085          * @param suppressedVisualEffects which visual interruptions should be suppressed from
2086          *                                notifications that are filtered by DND.
2087          */
Policy(int priorityCategories, @PrioritySenders int priorityCallSenders, @PrioritySenders int priorityMessageSenders, int suppressedVisualEffects, @ConversationSenders int priorityConversationSenders)2088         public Policy(int priorityCategories, @PrioritySenders int priorityCallSenders,
2089                 @PrioritySenders int priorityMessageSenders,
2090                 int suppressedVisualEffects, @ConversationSenders int priorityConversationSenders) {
2091             this(priorityCategories, priorityCallSenders, priorityMessageSenders,
2092                     suppressedVisualEffects, STATE_UNSET, priorityConversationSenders);
2093         }
2094 
2095         /** @hide */
Policy(int priorityCategories, int priorityCallSenders, int priorityMessageSenders, int suppressedVisualEffects, int state, int priorityConversationSenders)2096         public Policy(int priorityCategories, int priorityCallSenders, int priorityMessageSenders,
2097                 int suppressedVisualEffects, int state, int priorityConversationSenders) {
2098             this.priorityCategories = priorityCategories;
2099             this.priorityCallSenders = priorityCallSenders;
2100             this.priorityMessageSenders = priorityMessageSenders;
2101             this.suppressedVisualEffects = suppressedVisualEffects;
2102             this.state = state;
2103             this.priorityConversationSenders = priorityConversationSenders;
2104         }
2105 
2106 
2107         /** @hide */
Policy(Parcel source)2108         public Policy(Parcel source) {
2109             this(source.readInt(), source.readInt(), source.readInt(), source.readInt(),
2110                     source.readInt(), source.readInt());
2111         }
2112 
2113         @Override
writeToParcel(Parcel dest, int flags)2114         public void writeToParcel(Parcel dest, int flags) {
2115             dest.writeInt(priorityCategories);
2116             dest.writeInt(priorityCallSenders);
2117             dest.writeInt(priorityMessageSenders);
2118             dest.writeInt(suppressedVisualEffects);
2119             dest.writeInt(state);
2120             dest.writeInt(priorityConversationSenders);
2121         }
2122 
2123         @Override
describeContents()2124         public int describeContents() {
2125             return 0;
2126         }
2127 
2128         @Override
hashCode()2129         public int hashCode() {
2130             return Objects.hash(priorityCategories, priorityCallSenders, priorityMessageSenders,
2131                     suppressedVisualEffects, state, priorityConversationSenders);
2132         }
2133 
2134         @Override
equals(@ullable Object o)2135         public boolean equals(@Nullable Object o) {
2136             if (!(o instanceof Policy)) return false;
2137             if (o == this) return true;
2138             final Policy other = (Policy) o;
2139             return other.priorityCategories == priorityCategories
2140                     && other.priorityCallSenders == priorityCallSenders
2141                     && other.priorityMessageSenders == priorityMessageSenders
2142                     && suppressedVisualEffectsEqual(suppressedVisualEffects,
2143                     other.suppressedVisualEffects)
2144                     && other.state == this.state
2145                     && other.priorityConversationSenders == this.priorityConversationSenders;
2146         }
2147 
suppressedVisualEffectsEqual(int suppressedEffects, int otherSuppressedVisualEffects)2148         private boolean suppressedVisualEffectsEqual(int suppressedEffects,
2149                 int otherSuppressedVisualEffects) {
2150             if (suppressedEffects == otherSuppressedVisualEffects) {
2151                 return true;
2152             }
2153 
2154             if ((suppressedEffects & SUPPRESSED_EFFECT_SCREEN_ON) != 0) {
2155                 suppressedEffects |= SUPPRESSED_EFFECT_PEEK;
2156             }
2157             if ((suppressedEffects & SUPPRESSED_EFFECT_SCREEN_OFF) != 0) {
2158                 suppressedEffects |= SUPPRESSED_EFFECT_FULL_SCREEN_INTENT;
2159                 suppressedEffects |= SUPPRESSED_EFFECT_LIGHTS;
2160                 suppressedEffects |= SUPPRESSED_EFFECT_AMBIENT;
2161             }
2162 
2163             if ((otherSuppressedVisualEffects & SUPPRESSED_EFFECT_SCREEN_ON) != 0) {
2164                 otherSuppressedVisualEffects |= SUPPRESSED_EFFECT_PEEK;
2165             }
2166             if ((otherSuppressedVisualEffects & SUPPRESSED_EFFECT_SCREEN_OFF) != 0) {
2167                 otherSuppressedVisualEffects |= SUPPRESSED_EFFECT_FULL_SCREEN_INTENT;
2168                 otherSuppressedVisualEffects |= SUPPRESSED_EFFECT_LIGHTS;
2169                 otherSuppressedVisualEffects |= SUPPRESSED_EFFECT_AMBIENT;
2170             }
2171 
2172             if ((suppressedEffects & SUPPRESSED_EFFECT_SCREEN_ON)
2173                     != (otherSuppressedVisualEffects & SUPPRESSED_EFFECT_SCREEN_ON)) {
2174                 int currSuppressedEffects = (suppressedEffects & SUPPRESSED_EFFECT_SCREEN_ON) != 0
2175                         ? otherSuppressedVisualEffects : suppressedEffects;
2176                 if ((currSuppressedEffects & SUPPRESSED_EFFECT_PEEK) == 0) {
2177                     return false;
2178                 }
2179             }
2180 
2181             if ((suppressedEffects & SUPPRESSED_EFFECT_SCREEN_OFF)
2182                     != (otherSuppressedVisualEffects & SUPPRESSED_EFFECT_SCREEN_OFF)) {
2183                 int currSuppressedEffects = (suppressedEffects & SUPPRESSED_EFFECT_SCREEN_OFF) != 0
2184                         ? otherSuppressedVisualEffects : suppressedEffects;
2185                 if ((currSuppressedEffects & SUPPRESSED_EFFECT_FULL_SCREEN_INTENT) == 0
2186                         || (currSuppressedEffects & SUPPRESSED_EFFECT_LIGHTS) == 0
2187                         || (currSuppressedEffects & SUPPRESSED_EFFECT_AMBIENT) == 0) {
2188                     return false;
2189                 }
2190             }
2191 
2192             int thisWithoutOldEffects = suppressedEffects
2193                     & ~SUPPRESSED_EFFECT_SCREEN_ON
2194                     & ~SUPPRESSED_EFFECT_SCREEN_OFF;
2195             int otherWithoutOldEffects = otherSuppressedVisualEffects
2196                     & ~SUPPRESSED_EFFECT_SCREEN_ON
2197                     & ~SUPPRESSED_EFFECT_SCREEN_OFF;
2198             return thisWithoutOldEffects == otherWithoutOldEffects;
2199         }
2200 
2201         @Override
toString()2202         public String toString() {
2203             return "NotificationManager.Policy["
2204                     + "priorityCategories=" + priorityCategoriesToString(priorityCategories)
2205                     + ",priorityCallSenders=" + prioritySendersToString(priorityCallSenders)
2206                     + ",priorityMessageSenders=" + prioritySendersToString(priorityMessageSenders)
2207                     + ",priorityConvSenders="
2208                     + conversationSendersToString(priorityConversationSenders)
2209                     + ",suppressedVisualEffects="
2210                     + suppressedEffectsToString(suppressedVisualEffects)
2211                     + ",areChannelsBypassingDnd=" + (state == STATE_UNSET
2212                         ? "unset"
2213                         : ((state & STATE_CHANNELS_BYPASSING_DND) != 0)
2214                                 ? "true"
2215                                 : "false")
2216                     + "]";
2217         }
2218 
2219         /** @hide */
dumpDebug(ProtoOutputStream proto, long fieldId)2220         public void dumpDebug(ProtoOutputStream proto, long fieldId) {
2221             final long pToken = proto.start(fieldId);
2222 
2223             bitwiseToProtoEnum(proto, PolicyProto.PRIORITY_CATEGORIES, priorityCategories);
2224             proto.write(PolicyProto.PRIORITY_CALL_SENDER, priorityCallSenders);
2225             proto.write(PolicyProto.PRIORITY_MESSAGE_SENDER, priorityMessageSenders);
2226             bitwiseToProtoEnum(
2227                     proto, PolicyProto.SUPPRESSED_VISUAL_EFFECTS, suppressedVisualEffects);
2228 
2229             proto.end(pToken);
2230         }
2231 
bitwiseToProtoEnum(ProtoOutputStream proto, long fieldId, int data)2232         private static void bitwiseToProtoEnum(ProtoOutputStream proto, long fieldId, int data) {
2233             for (int i = 1; data > 0; ++i, data >>>= 1) {
2234                 if ((data & 1) == 1) {
2235                     proto.write(fieldId, i);
2236                 }
2237             }
2238         }
2239 
2240         /**
2241          * @hide
2242          */
getAllSuppressedVisualEffects()2243         public static int getAllSuppressedVisualEffects() {
2244             int effects = 0;
2245             for (int i = 0; i < ALL_SUPPRESSED_EFFECTS.length; i++) {
2246                 effects |= ALL_SUPPRESSED_EFFECTS[i];
2247             }
2248             return effects;
2249         }
2250 
2251         /**
2252          * @hide
2253          */
areAllVisualEffectsSuppressed(int effects)2254         public static boolean areAllVisualEffectsSuppressed(int effects) {
2255             for (int i = 0; i < ALL_SUPPRESSED_EFFECTS.length; i++) {
2256                 final int effect = ALL_SUPPRESSED_EFFECTS[i];
2257                 if ((effects & effect) == 0) {
2258                     return false;
2259                 }
2260             }
2261             return true;
2262         }
2263 
toggleEffects(int currentEffects, int[] effects, boolean suppress)2264         private static int toggleEffects(int currentEffects, int[] effects, boolean suppress) {
2265             for (int i = 0; i < effects.length; i++) {
2266                 final int effect = effects[i];
2267                 if (suppress) {
2268                     currentEffects |= effect;
2269                 } else {
2270                     currentEffects &= ~effect;
2271                 }
2272             }
2273             return currentEffects;
2274         }
2275 
suppressedEffectsToString(int effects)2276         public static String suppressedEffectsToString(int effects) {
2277             if (effects <= 0) return "";
2278             final StringBuilder sb = new StringBuilder();
2279             for (int i = 0; i < ALL_SUPPRESSED_EFFECTS.length; i++) {
2280                 final int effect = ALL_SUPPRESSED_EFFECTS[i];
2281                 if ((effects & effect) != 0) {
2282                     if (sb.length() > 0) sb.append(',');
2283                     sb.append(effectToString(effect));
2284                 }
2285                 effects &= ~effect;
2286             }
2287             if (effects != 0) {
2288                 if (sb.length() > 0) sb.append(',');
2289                 sb.append("UNKNOWN_").append(effects);
2290             }
2291             return sb.toString();
2292         }
2293 
priorityCategoriesToString(int priorityCategories)2294         public static String priorityCategoriesToString(int priorityCategories) {
2295             if (priorityCategories == 0) return "";
2296             final StringBuilder sb = new StringBuilder();
2297             for (int i = 0; i < ALL_PRIORITY_CATEGORIES.length; i++) {
2298                 final int priorityCategory = ALL_PRIORITY_CATEGORIES[i];
2299                 if ((priorityCategories & priorityCategory) != 0) {
2300                     if (sb.length() > 0) sb.append(',');
2301                     sb.append(priorityCategoryToString(priorityCategory));
2302                 }
2303                 priorityCategories &= ~priorityCategory;
2304             }
2305             if (priorityCategories != 0) {
2306                 if (sb.length() > 0) sb.append(',');
2307                 sb.append("PRIORITY_CATEGORY_UNKNOWN_").append(priorityCategories);
2308             }
2309             return sb.toString();
2310         }
2311 
effectToString(int effect)2312         private static String effectToString(int effect) {
2313             switch (effect) {
2314                 case SUPPRESSED_EFFECT_FULL_SCREEN_INTENT:
2315                     return "SUPPRESSED_EFFECT_FULL_SCREEN_INTENT";
2316                 case SUPPRESSED_EFFECT_LIGHTS:
2317                     return "SUPPRESSED_EFFECT_LIGHTS";
2318                 case SUPPRESSED_EFFECT_PEEK:
2319                     return "SUPPRESSED_EFFECT_PEEK";
2320                 case SUPPRESSED_EFFECT_STATUS_BAR:
2321                     return "SUPPRESSED_EFFECT_STATUS_BAR";
2322                 case SUPPRESSED_EFFECT_BADGE:
2323                     return "SUPPRESSED_EFFECT_BADGE";
2324                 case SUPPRESSED_EFFECT_AMBIENT:
2325                     return "SUPPRESSED_EFFECT_AMBIENT";
2326                 case SUPPRESSED_EFFECT_NOTIFICATION_LIST:
2327                     return "SUPPRESSED_EFFECT_NOTIFICATION_LIST";
2328                 case SUPPRESSED_EFFECT_SCREEN_OFF:
2329                     return "SUPPRESSED_EFFECT_SCREEN_OFF";
2330                 case SUPPRESSED_EFFECT_SCREEN_ON:
2331                     return "SUPPRESSED_EFFECT_SCREEN_ON";
2332                 case SUPPRESSED_EFFECTS_UNSET:
2333                     return "SUPPRESSED_EFFECTS_UNSET";
2334                 default: return "UNKNOWN_" + effect;
2335             }
2336         }
2337 
priorityCategoryToString(int priorityCategory)2338         private static String priorityCategoryToString(int priorityCategory) {
2339             switch (priorityCategory) {
2340                 case PRIORITY_CATEGORY_REMINDERS: return "PRIORITY_CATEGORY_REMINDERS";
2341                 case PRIORITY_CATEGORY_EVENTS: return "PRIORITY_CATEGORY_EVENTS";
2342                 case PRIORITY_CATEGORY_MESSAGES: return "PRIORITY_CATEGORY_MESSAGES";
2343                 case PRIORITY_CATEGORY_CALLS: return "PRIORITY_CATEGORY_CALLS";
2344                 case PRIORITY_CATEGORY_REPEAT_CALLERS: return "PRIORITY_CATEGORY_REPEAT_CALLERS";
2345                 case PRIORITY_CATEGORY_ALARMS: return "PRIORITY_CATEGORY_ALARMS";
2346                 case PRIORITY_CATEGORY_MEDIA: return "PRIORITY_CATEGORY_MEDIA";
2347                 case PRIORITY_CATEGORY_SYSTEM: return "PRIORITY_CATEGORY_SYSTEM";
2348                 case PRIORITY_CATEGORY_CONVERSATIONS: return "PRIORITY_CATEGORY_CONVERSATIONS";
2349                 default: return "PRIORITY_CATEGORY_UNKNOWN_" + priorityCategory;
2350             }
2351         }
2352 
prioritySendersToString(int prioritySenders)2353         public static String prioritySendersToString(int prioritySenders) {
2354             switch (prioritySenders) {
2355                 case PRIORITY_SENDERS_ANY: return "PRIORITY_SENDERS_ANY";
2356                 case PRIORITY_SENDERS_CONTACTS: return "PRIORITY_SENDERS_CONTACTS";
2357                 case PRIORITY_SENDERS_STARRED: return "PRIORITY_SENDERS_STARRED";
2358                 default: return "PRIORITY_SENDERS_UNKNOWN_" + prioritySenders;
2359             }
2360         }
2361 
2362         /**
2363          * @hide
2364          */
conversationSendersToString(int priorityConversationSenders)2365         public static @NonNull String conversationSendersToString(int priorityConversationSenders) {
2366             switch (priorityConversationSenders) {
2367                 case CONVERSATION_SENDERS_ANYONE:
2368                     return "anyone";
2369                 case CONVERSATION_SENDERS_IMPORTANT:
2370                     return "important";
2371                 case CONVERSATION_SENDERS_NONE:
2372                     return "none";
2373                 case CONVERSATION_SENDERS_UNSET:
2374                     return "unset";
2375             }
2376             return "invalidConversationType{" + priorityConversationSenders + "}";
2377         }
2378 
2379         public static final @android.annotation.NonNull Parcelable.Creator<Policy> CREATOR
2380                 = new Parcelable.Creator<Policy>() {
2381             @Override
2382             public Policy createFromParcel(Parcel in) {
2383                 return new Policy(in);
2384             }
2385 
2386             @Override
2387             public Policy[] newArray(int size) {
2388                 return new Policy[size];
2389             }
2390         };
2391 
2392         /** @hide **/
allowAlarms()2393         public boolean allowAlarms() {
2394             return (priorityCategories & PRIORITY_CATEGORY_ALARMS) != 0;
2395         }
2396 
2397         /** @hide **/
allowMedia()2398         public boolean allowMedia() {
2399             return (priorityCategories & PRIORITY_CATEGORY_MEDIA) != 0;
2400         }
2401 
2402         /** @hide **/
allowSystem()2403         public boolean allowSystem() {
2404             return (priorityCategories & PRIORITY_CATEGORY_SYSTEM) != 0;
2405         }
2406 
2407         /** @hide **/
allowRepeatCallers()2408         public boolean allowRepeatCallers() {
2409             return (priorityCategories & PRIORITY_CATEGORY_REPEAT_CALLERS) != 0;
2410         }
2411 
2412         /** @hide **/
allowCalls()2413         public boolean allowCalls() {
2414             return (priorityCategories & PRIORITY_CATEGORY_CALLS) != 0;
2415         }
2416 
2417         /** @hide **/
allowConversations()2418         public boolean allowConversations() {
2419             return (priorityCategories & PRIORITY_CATEGORY_CONVERSATIONS) != 0;
2420         }
2421 
2422         /** @hide **/
allowMessages()2423         public boolean allowMessages() {
2424             return (priorityCategories & PRIORITY_CATEGORY_MESSAGES) != 0;
2425         }
2426 
2427         /** @hide **/
allowEvents()2428         public boolean allowEvents() {
2429             return (priorityCategories & PRIORITY_CATEGORY_EVENTS) != 0;
2430         }
2431 
2432         /** @hide **/
allowReminders()2433         public boolean allowReminders() {
2434             return (priorityCategories & PRIORITY_CATEGORY_REMINDERS) != 0;
2435         }
2436 
2437         /** @hide **/
allowCallsFrom()2438         public int allowCallsFrom() {
2439             return priorityCallSenders;
2440         }
2441 
2442         /** @hide **/
allowMessagesFrom()2443         public int allowMessagesFrom() {
2444             return priorityMessageSenders;
2445         }
2446 
2447         /** @hide **/
allowConversationsFrom()2448         public int allowConversationsFrom() {
2449             return priorityConversationSenders;
2450         }
2451 
2452         /** @hide **/
showFullScreenIntents()2453         public boolean showFullScreenIntents() {
2454             return (suppressedVisualEffects & SUPPRESSED_EFFECT_FULL_SCREEN_INTENT) == 0;
2455         }
2456 
2457         /** @hide **/
showLights()2458         public boolean showLights() {
2459             return (suppressedVisualEffects & SUPPRESSED_EFFECT_LIGHTS) == 0;
2460         }
2461 
2462         /** @hide **/
showPeeking()2463         public boolean showPeeking() {
2464             return (suppressedVisualEffects & SUPPRESSED_EFFECT_PEEK) == 0;
2465         }
2466 
2467         /** @hide **/
showStatusBarIcons()2468         public boolean showStatusBarIcons() {
2469             return (suppressedVisualEffects & SUPPRESSED_EFFECT_STATUS_BAR) == 0;
2470         }
2471 
2472         /** @hide **/
showAmbient()2473         public boolean showAmbient() {
2474             return (suppressedVisualEffects & SUPPRESSED_EFFECT_AMBIENT) == 0;
2475         }
2476 
2477         /** @hide **/
showBadges()2478         public boolean showBadges() {
2479             return (suppressedVisualEffects & SUPPRESSED_EFFECT_BADGE) == 0;
2480         }
2481 
2482         /** @hide **/
showInNotificationList()2483         public boolean showInNotificationList() {
2484             return (suppressedVisualEffects & SUPPRESSED_EFFECT_NOTIFICATION_LIST) == 0;
2485         }
2486 
2487         /**
2488          * returns a deep copy of this policy
2489          * @hide
2490          */
copy()2491         public Policy copy() {
2492             final Parcel parcel = Parcel.obtain();
2493             try {
2494                 writeToParcel(parcel, 0);
2495                 parcel.setDataPosition(0);
2496                 return new Policy(parcel);
2497             } finally {
2498                 parcel.recycle();
2499             }
2500         }
2501     }
2502 
2503     /**
2504      * Recover a list of active notifications: ones that have been posted by the calling app that
2505      * have not yet been dismissed by the user or {@link #cancel(String, int)}ed by the app.
2506      *
2507      * <p><Each notification is embedded in a {@link StatusBarNotification} object, including the
2508      * original <code>tag</code> and <code>id</code> supplied to
2509      * {@link #notify(String, int, Notification) notify()}
2510      * (via {@link StatusBarNotification#getTag() getTag()} and
2511      * {@link StatusBarNotification#getId() getId()}) as well as a copy of the original
2512      * {@link Notification} object (via {@link StatusBarNotification#getNotification()}).
2513      * </p>
2514      * <p>From {@link Build.VERSION_CODES#Q}, will also return notifications you've posted as an
2515      * app's notification delegate via
2516      * {@link NotificationManager#notifyAsPackage(String, String, int, Notification)}.
2517      * </p>
2518      *
2519      * @return An array of {@link StatusBarNotification}.
2520      */
getActiveNotifications()2521     public StatusBarNotification[] getActiveNotifications() {
2522         final INotificationManager service = getService();
2523         final String pkg = mContext.getPackageName();
2524         try {
2525             final ParceledListSlice<StatusBarNotification> parceledList
2526                     = service.getAppActiveNotifications(pkg, mContext.getUserId());
2527             if (parceledList != null) {
2528                 final List<StatusBarNotification> list = parceledList.getList();
2529                 return list.toArray(new StatusBarNotification[list.size()]);
2530             }
2531         } catch (RemoteException e) {
2532             throw e.rethrowFromSystemServer();
2533         }
2534         return new StatusBarNotification[0];
2535     }
2536 
2537     /**
2538      * Gets the current notification interruption filter.
2539      * <p>
2540      * The interruption filter defines which notifications are allowed to
2541      * interrupt the user (e.g. via sound &amp; vibration) and is applied
2542      * globally.
2543      */
getCurrentInterruptionFilter()2544     public final @InterruptionFilter int getCurrentInterruptionFilter() {
2545         final INotificationManager service = getService();
2546         try {
2547             return zenModeToInterruptionFilter(service.getZenMode());
2548         } catch (RemoteException e) {
2549             throw e.rethrowFromSystemServer();
2550         }
2551     }
2552 
2553     /**
2554      * Sets the current notification interruption filter.
2555      * <p>
2556      * The interruption filter defines which notifications are allowed to
2557      * interrupt the user (e.g. via sound &amp; vibration) and is applied
2558      * globally.
2559      * <p>
2560      * Only available if policy access is granted to this package. See
2561      * {@link #isNotificationPolicyAccessGranted}.
2562      */
setInterruptionFilter(@nterruptionFilter int interruptionFilter)2563     public final void setInterruptionFilter(@InterruptionFilter int interruptionFilter) {
2564         final INotificationManager service = getService();
2565         try {
2566             service.setInterruptionFilter(mContext.getOpPackageName(), interruptionFilter);
2567         } catch (RemoteException e) {
2568             throw e.rethrowFromSystemServer();
2569         }
2570     }
2571 
2572     /**
2573      * Returns whether a call from the provided URI is permitted to notify the user.
2574      * <p>
2575      * A true return value indicates one of the following: Do Not Disturb is not currently active;
2576      * or the caller is a repeat caller and the current policy allows interruptions from repeat
2577      * callers; or the caller is in the user's set of contacts whose calls are allowed to interrupt
2578      * Do Not Disturb.
2579      * </p>
2580      * <p>
2581      * If Do Not Disturb is enabled and either no interruptions or only alarms are allowed, this
2582      * method will return false regardless of input.
2583      * </p>
2584      * <p>
2585      * The provided URI should be a <code>tel:</code> or <code>mailto:</code> schema URI indicating
2586      * the source of the call. For an accurate answer regarding whether the caller matches the
2587      * user's permitted contacts, the path part of the URI must match an entry the Contacts database
2588      * in the appropriate column.
2589      * </p>
2590      * <p>
2591      * Passing in a {@link android.provider.ContactsContract.Contacts#CONTENT_LOOKUP_URI} is also
2592      * permissible, but should only be used for priority contact interruptions and may not provide
2593      * accurate results in the case of repeat callers.
2594      * </p>
2595      * <p>
2596      * See also {@link Person.Builder#setUri} and
2597      * {@link android.provider.ContactsContract.Contacts#CONTENT_LOOKUP_URI}
2598      * for more information.
2599      * </p>
2600      * <p>
2601      * Callers of this method must have notification listener access, permission to read contacts,
2602      * or have system permissions.
2603      * </p>
2604      * <p>
2605      * NOTE: This method calls into Contacts, which may take some time, and should not be called
2606      * on the main thread.
2607      * </p>
2608      *
2609      * @param uri A URI representing a caller. Must not be null.
2610      * @return A boolean indicating whether a call from the URI provided would be allowed to
2611      *         interrupt the user given the current filter.
2612      */
2613     @WorkerThread
matchesCallFilter(@onNull Uri uri)2614     public boolean matchesCallFilter(@NonNull Uri uri) {
2615         Bundle extras = new Bundle();
2616         ArrayList<Person> pList = new ArrayList<>();
2617         pList.add(new Person.Builder().setUri(uri.toString()).build());
2618         extras.putParcelableArrayList(Notification.EXTRA_PEOPLE_LIST, pList);
2619 
2620         return matchesCallFilter(extras);
2621     }
2622 
2623     /** @hide */
zenModeToInterruptionFilter(int zen)2624     public static int zenModeToInterruptionFilter(int zen) {
2625         switch (zen) {
2626             case Global.ZEN_MODE_OFF: return INTERRUPTION_FILTER_ALL;
2627             case Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS: return INTERRUPTION_FILTER_PRIORITY;
2628             case Global.ZEN_MODE_ALARMS: return INTERRUPTION_FILTER_ALARMS;
2629             case Global.ZEN_MODE_NO_INTERRUPTIONS: return INTERRUPTION_FILTER_NONE;
2630             default: return INTERRUPTION_FILTER_UNKNOWN;
2631         }
2632     }
2633 
2634     /** @hide */
zenModeFromInterruptionFilter(int interruptionFilter, int defValue)2635     public static int zenModeFromInterruptionFilter(int interruptionFilter, int defValue) {
2636         switch (interruptionFilter) {
2637             case INTERRUPTION_FILTER_ALL: return Global.ZEN_MODE_OFF;
2638             case INTERRUPTION_FILTER_PRIORITY: return Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS;
2639             case INTERRUPTION_FILTER_ALARMS: return Global.ZEN_MODE_ALARMS;
2640             case INTERRUPTION_FILTER_NONE:  return Global.ZEN_MODE_NO_INTERRUPTIONS;
2641             default: return defValue;
2642         }
2643     }
2644 }
2645