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.SdkConstant;
22 import android.annotation.SystemService;
23 import android.annotation.TestApi;
24 import android.app.Notification.Builder;
25 import android.content.ComponentName;
26 import android.content.Context;
27 import android.content.Intent;
28 import android.content.pm.ParceledListSlice;
29 import android.graphics.drawable.Icon;
30 import android.net.Uri;
31 import android.os.Build;
32 import android.os.Bundle;
33 import android.os.Handler;
34 import android.os.IBinder;
35 import android.os.Parcel;
36 import android.os.Parcelable;
37 import android.os.RemoteException;
38 import android.os.ServiceManager;
39 import android.os.StrictMode;
40 import android.os.UserHandle;
41 import android.provider.Settings.Global;
42 import android.service.notification.StatusBarNotification;
43 import android.service.notification.ZenModeConfig;
44 import android.util.Log;
45 import android.util.proto.ProtoOutputStream;
46 
47 import java.lang.annotation.Retention;
48 import java.lang.annotation.RetentionPolicy;
49 import java.util.Arrays;
50 import java.util.HashMap;
51 import java.util.List;
52 import java.util.Map;
53 import java.util.Objects;
54 
55 /**
56  * Class to notify the user of events that happen.  This is how you tell
57  * the user that something has happened in the background. {@more}
58  *
59  * Notifications can take different forms:
60  * <ul>
61  *      <li>A persistent icon that goes in the status bar and is accessible
62  *          through the launcher, (when the user selects it, a designated Intent
63  *          can be launched),</li>
64  *      <li>Turning on or flashing LEDs on the device, or</li>
65  *      <li>Alerting the user by flashing the backlight, playing a sound,
66  *          or vibrating.</li>
67  * </ul>
68  *
69  * <p>
70  * Each of the notify methods takes an int id parameter and optionally a
71  * {@link String} tag parameter, which may be {@code null}.  These parameters
72  * are used to form a pair (tag, id), or ({@code null}, id) if tag is
73  * unspecified.  This pair identifies this notification from your app to the
74  * system, so that pair should be unique within your app.  If you call one
75  * of the notify methods with a (tag, id) pair that is currently active and
76  * a new set of notification parameters, it will be updated.  For example,
77  * if you pass a new status bar icon, the old icon in the status bar will
78  * be replaced with the new one.  This is also the same tag and id you pass
79  * to the {@link #cancel(int)} or {@link #cancel(String, int)} method to clear
80  * this notification.
81  *
82  * <div class="special reference">
83  * <h3>Developer Guides</h3>
84  * <p>For a guide to creating notifications, read the
85  * <a href="{@docRoot}guide/topics/ui/notifiers/notifications.html">Status Bar Notifications</a>
86  * developer guide.</p>
87  * </div>
88  *
89  * @see android.app.Notification
90  */
91 @SystemService(Context.NOTIFICATION_SERVICE)
92 public class NotificationManager {
93     private static String TAG = "NotificationManager";
94     private static boolean localLOGV = false;
95 
96     /**
97      * Intent that is broadcast when an application is blocked or unblocked.
98      *
99      * This broadcast is only sent to the app whose block state has changed.
100      *
101      * Input: nothing
102      * Output: {@link #EXTRA_BLOCKED_STATE}
103      */
104     @SdkConstant(SdkConstant.SdkConstantType.BROADCAST_INTENT_ACTION)
105     public static final String ACTION_APP_BLOCK_STATE_CHANGED =
106             "android.app.action.APP_BLOCK_STATE_CHANGED";
107 
108     /**
109      * Intent that is broadcast when a {@link NotificationChannel} is blocked
110      * (when {@link NotificationChannel#getImportance()} is {@link #IMPORTANCE_NONE}) or unblocked
111      * (when {@link NotificationChannel#getImportance()} is anything other than
112      * {@link #IMPORTANCE_NONE}).
113      *
114      * This broadcast is only sent to the app that owns the channel that has changed.
115      *
116      * Input: nothing
117      * Output: {@link #EXTRA_NOTIFICATION_CHANNEL_ID}
118      * Output: {@link #EXTRA_BLOCKED_STATE}
119      */
120     @SdkConstant(SdkConstant.SdkConstantType.BROADCAST_INTENT_ACTION)
121     public static final String ACTION_NOTIFICATION_CHANNEL_BLOCK_STATE_CHANGED =
122             "android.app.action.NOTIFICATION_CHANNEL_BLOCK_STATE_CHANGED";
123 
124     /**
125      * Extra for {@link #ACTION_NOTIFICATION_CHANNEL_BLOCK_STATE_CHANGED} containing the id of the
126      * {@link NotificationChannel} which has a new blocked state.
127      *
128      * The value will be the {@link NotificationChannel#getId()} of the channel.
129      */
130     public static final String EXTRA_NOTIFICATION_CHANNEL_ID =
131             "android.app.extra.NOTIFICATION_CHANNEL_ID";
132 
133     /**
134      * Extra for {@link #ACTION_NOTIFICATION_CHANNEL_GROUP_BLOCK_STATE_CHANGED} containing the id
135      * of the {@link NotificationChannelGroup} which has a new blocked state.
136      *
137      * The value will be the {@link NotificationChannelGroup#getId()} of the group.
138      */
139     public static final String EXTRA_NOTIFICATION_CHANNEL_GROUP_ID =
140             "android.app.extra.NOTIFICATION_CHANNEL_GROUP_ID";
141 
142 
143     /**
144      * Extra for {@link #ACTION_NOTIFICATION_CHANNEL_BLOCK_STATE_CHANGED} or
145      * {@link #ACTION_NOTIFICATION_CHANNEL_GROUP_BLOCK_STATE_CHANGED} containing the new blocked
146      * state as a boolean.
147      *
148      * The value will be {@code true} if this channel or group is now blocked and {@code false} if
149      * this channel or group is now unblocked.
150      */
151     public static final String EXTRA_BLOCKED_STATE = "android.app.extra.BLOCKED_STATE";
152 
153     /**
154      * Intent that is broadcast when a {@link NotificationChannelGroup} is
155      * {@link NotificationChannelGroup#isBlocked() blocked} or unblocked.
156      *
157      * This broadcast is only sent to the app that owns the channel group that has changed.
158      *
159      * Input: nothing
160      * Output: {@link #EXTRA_NOTIFICATION_CHANNEL_GROUP_ID}
161      * Output: {@link #EXTRA_BLOCKED_STATE}
162      */
163     @SdkConstant(SdkConstant.SdkConstantType.BROADCAST_INTENT_ACTION)
164     public static final String ACTION_NOTIFICATION_CHANNEL_GROUP_BLOCK_STATE_CHANGED =
165             "android.app.action.NOTIFICATION_CHANNEL_GROUP_BLOCK_STATE_CHANGED";
166 
167     /**
168      * Intent that is broadcast when the state of {@link #getEffectsSuppressor()} changes.
169      * This broadcast is only sent to registered receivers.
170      *
171      * @hide
172      */
173     @SdkConstant(SdkConstant.SdkConstantType.BROADCAST_INTENT_ACTION)
174     public static final String ACTION_EFFECTS_SUPPRESSOR_CHANGED
175             = "android.os.action.ACTION_EFFECTS_SUPPRESSOR_CHANGED";
176 
177     /**
178      * Intent that is broadcast when the state of {@link #isNotificationPolicyAccessGranted()}
179      * changes.
180      *
181      * This broadcast is only sent to registered receivers, and only to the apps that have changed.
182      */
183     @SdkConstant(SdkConstant.SdkConstantType.BROADCAST_INTENT_ACTION)
184     public static final String ACTION_NOTIFICATION_POLICY_ACCESS_GRANTED_CHANGED
185             = "android.app.action.NOTIFICATION_POLICY_ACCESS_GRANTED_CHANGED";
186 
187     /**
188      * Intent that is broadcast when the state of getNotificationPolicy() changes.
189      * This broadcast is only sent to registered receivers.
190      */
191     @SdkConstant(SdkConstant.SdkConstantType.BROADCAST_INTENT_ACTION)
192     public static final String ACTION_NOTIFICATION_POLICY_CHANGED
193             = "android.app.action.NOTIFICATION_POLICY_CHANGED";
194 
195     /**
196      * Intent that is broadcast when the state of getCurrentInterruptionFilter() changes.
197      * This broadcast is only sent to registered receivers.
198      */
199     @SdkConstant(SdkConstant.SdkConstantType.BROADCAST_INTENT_ACTION)
200     public static final String ACTION_INTERRUPTION_FILTER_CHANGED
201             = "android.app.action.INTERRUPTION_FILTER_CHANGED";
202 
203     /**
204      * Intent that is broadcast when the state of getCurrentInterruptionFilter() changes.
205      * @hide
206      */
207     @SdkConstant(SdkConstant.SdkConstantType.BROADCAST_INTENT_ACTION)
208     public static final String ACTION_INTERRUPTION_FILTER_CHANGED_INTERNAL
209             = "android.app.action.INTERRUPTION_FILTER_CHANGED_INTERNAL";
210 
211     /** @hide */
212     @IntDef(prefix = { "INTERRUPTION_FILTER_" }, value = {
213             INTERRUPTION_FILTER_NONE, INTERRUPTION_FILTER_PRIORITY, INTERRUPTION_FILTER_ALARMS,
214             INTERRUPTION_FILTER_ALL, INTERRUPTION_FILTER_UNKNOWN
215     })
216     @Retention(RetentionPolicy.SOURCE)
217     public @interface InterruptionFilter {}
218 
219     /**
220      * {@link #getCurrentInterruptionFilter() Interruption filter} constant -
221      *     Normal interruption filter - no notifications are suppressed.
222      */
223     public static final int INTERRUPTION_FILTER_ALL = 1;
224 
225     /**
226      * {@link #getCurrentInterruptionFilter() Interruption filter} constant -
227      *     Priority interruption filter - all notifications are suppressed except those that match
228      *     the priority criteria. Some audio streams are muted. See
229      *     {@link Policy#priorityCallSenders}, {@link Policy#priorityCategories},
230      *     {@link Policy#priorityMessageSenders} to define or query this criteria. Users can
231      *     additionally specify packages that can bypass this interruption filter.
232      */
233     public static final int INTERRUPTION_FILTER_PRIORITY = 2;
234 
235     /**
236      * {@link #getCurrentInterruptionFilter() Interruption filter} constant -
237      *     No interruptions filter - all notifications are suppressed and all audio streams (except
238      *     those used for phone calls) and vibrations are muted.
239      */
240     public static final int INTERRUPTION_FILTER_NONE = 3;
241 
242     /**
243      * {@link #getCurrentInterruptionFilter() Interruption filter} constant -
244      *     Alarms only interruption filter - all notifications except those of category
245      *     {@link Notification#CATEGORY_ALARM} are suppressed. Some audio streams are muted.
246      */
247     public static final int INTERRUPTION_FILTER_ALARMS = 4;
248 
249     /** {@link #getCurrentInterruptionFilter() Interruption filter} constant - returned when
250      * the value is unavailable for any reason.
251      */
252     public static final int INTERRUPTION_FILTER_UNKNOWN = 0;
253 
254     /** @hide */
255     @IntDef(prefix = { "IMPORTANCE_" }, value = {
256             IMPORTANCE_UNSPECIFIED, IMPORTANCE_NONE,
257             IMPORTANCE_MIN, IMPORTANCE_LOW, IMPORTANCE_DEFAULT, IMPORTANCE_HIGH
258     })
259     @Retention(RetentionPolicy.SOURCE)
260     public @interface Importance {}
261 
262     /** Value signifying that the user has not expressed a per-app visibility override value.
263      * @hide */
264     public static final int VISIBILITY_NO_OVERRIDE = -1000;
265 
266     /**
267      * Value signifying that the user has not expressed an importance.
268      *
269      * This value is for persisting preferences, and should never be associated with
270      * an actual notification.
271      */
272     public static final int IMPORTANCE_UNSPECIFIED = -1000;
273 
274     /**
275      * A notification with no importance: does not show in the shade.
276      */
277     public static final int IMPORTANCE_NONE = 0;
278 
279     /**
280      * Min notification importance: only shows in the shade, below the fold.  This should
281      * not be used with {@link Service#startForeground(int, Notification) Service.startForeground}
282      * since a foreground service is supposed to be something the user cares about so it does
283      * not make semantic sense to mark its notification as minimum importance.  If you do this
284      * as of Android version {@link android.os.Build.VERSION_CODES#O}, the system will show
285      * a higher-priority notification about your app running in the background.
286      */
287     public static final int IMPORTANCE_MIN = 1;
288 
289     /**
290      * Low notification importance: shows everywhere, but is not intrusive.
291      */
292     public static final int IMPORTANCE_LOW = 2;
293 
294     /**
295      * Default notification importance: shows everywhere, makes noise, but does not visually
296      * intrude.
297      */
298     public static final int IMPORTANCE_DEFAULT = 3;
299 
300     /**
301      * Higher notification importance: shows everywhere, makes noise and peeks. May use full screen
302      * intents.
303      */
304     public static final int IMPORTANCE_HIGH = 4;
305 
306     /**
307      * Unused.
308      */
309     public static final int IMPORTANCE_MAX = 5;
310 
311     private static INotificationManager sService;
312 
313     /** @hide */
getService()314     static public INotificationManager getService()
315     {
316         if (sService != null) {
317             return sService;
318         }
319         IBinder b = ServiceManager.getService("notification");
320         sService = INotificationManager.Stub.asInterface(b);
321         return sService;
322     }
323 
NotificationManager(Context context, Handler handler)324     /*package*/ NotificationManager(Context context, Handler handler)
325     {
326         mContext = context;
327     }
328 
329     /** {@hide} */
from(Context context)330     public static NotificationManager from(Context context) {
331         return (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
332     }
333 
334     /**
335      * Post a notification to be shown in the status bar. If a notification with
336      * the same id has already been posted by your application and has not yet been canceled, it
337      * will be replaced by the updated information.
338      *
339      * @param id An identifier for this notification unique within your
340      *        application.
341      * @param notification A {@link Notification} object describing what to show the user. Must not
342      *        be null.
343      */
notify(int id, Notification notification)344     public void notify(int id, Notification notification)
345     {
346         notify(null, id, notification);
347     }
348 
349     /**
350      * Post a notification to be shown in the status bar. If a notification with
351      * the same tag and id has already been posted by your application and has not yet been
352      * canceled, it will be replaced by the updated information.
353      *
354      * All {@link android.service.notification.NotificationListenerService listener services} will
355      * be granted {@link Intent#FLAG_GRANT_READ_URI_PERMISSION} access to any {@link Uri uris}
356      * provided on this notification or the
357      * {@link NotificationChannel} this notification is posted to using
358      * {@link Context#grantUriPermission(String, Uri, int)}. Permission will be revoked when the
359      * notification is canceled, or you can revoke permissions with
360      * {@link Context#revokeUriPermission(Uri, int)}.
361      *
362      * @param tag A string identifier for this notification.  May be {@code null}.
363      * @param id An identifier for this notification.  The pair (tag, id) must be unique
364      *        within your application.
365      * @param notification A {@link Notification} object describing what to
366      *        show the user. Must not be null.
367      */
notify(String tag, int id, Notification notification)368     public void notify(String tag, int id, Notification notification)
369     {
370         notifyAsUser(tag, id, notification, mContext.getUser());
371     }
372 
373     /**
374      * @hide
375      */
notifyAsUser(String tag, int id, Notification notification, UserHandle user)376     public void notifyAsUser(String tag, int id, Notification notification, UserHandle user)
377     {
378         INotificationManager service = getService();
379         String pkg = mContext.getPackageName();
380         // Fix the notification as best we can.
381         Notification.addFieldsFromContext(mContext, notification);
382 
383         if (notification.sound != null) {
384             notification.sound = notification.sound.getCanonicalUri();
385             if (StrictMode.vmFileUriExposureEnabled()) {
386                 notification.sound.checkFileUriExposed("Notification.sound");
387             }
388 
389         }
390         fixLegacySmallIcon(notification, pkg);
391         if (mContext.getApplicationInfo().targetSdkVersion > Build.VERSION_CODES.LOLLIPOP_MR1) {
392             if (notification.getSmallIcon() == null) {
393                 throw new IllegalArgumentException("Invalid notification (no valid small icon): "
394                         + notification);
395             }
396         }
397         if (localLOGV) Log.v(TAG, pkg + ": notify(" + id + ", " + notification + ")");
398         notification.reduceImageSizes(mContext);
399 
400         ActivityManager am = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
401         boolean isLowRam = am.isLowRamDevice();
402         final Notification copy = Builder.maybeCloneStrippedForDelivery(notification, isLowRam,
403                 mContext);
404         try {
405             service.enqueueNotificationWithTag(pkg, mContext.getOpPackageName(), tag, id,
406                     copy, user.getIdentifier());
407         } catch (RemoteException e) {
408             throw e.rethrowFromSystemServer();
409         }
410     }
411 
fixLegacySmallIcon(Notification n, String pkg)412     private void fixLegacySmallIcon(Notification n, String pkg) {
413         if (n.getSmallIcon() == null && n.icon != 0) {
414             n.setSmallIcon(Icon.createWithResource(pkg, n.icon));
415         }
416     }
417 
418     /**
419      * Cancel a previously shown notification.  If it's transient, the view
420      * will be hidden.  If it's persistent, it will be removed from the status
421      * bar.
422      */
cancel(int id)423     public void cancel(int id)
424     {
425         cancel(null, id);
426     }
427 
428     /**
429      * Cancel a previously shown notification.  If it's transient, the view
430      * will be hidden.  If it's persistent, it will be removed from the status
431      * bar.
432      */
cancel(String tag, int id)433     public void cancel(String tag, int id)
434     {
435         cancelAsUser(tag, id, mContext.getUser());
436     }
437 
438     /**
439      * @hide
440      */
cancelAsUser(String tag, int id, UserHandle user)441     public void cancelAsUser(String tag, int id, UserHandle user)
442     {
443         INotificationManager service = getService();
444         String pkg = mContext.getPackageName();
445         if (localLOGV) Log.v(TAG, pkg + ": cancel(" + id + ")");
446         try {
447             service.cancelNotificationWithTag(pkg, tag, id, user.getIdentifier());
448         } catch (RemoteException e) {
449             throw e.rethrowFromSystemServer();
450         }
451     }
452 
453     /**
454      * Cancel all previously shown notifications. See {@link #cancel} for the
455      * detailed behavior.
456      */
cancelAll()457     public void cancelAll()
458     {
459         INotificationManager service = getService();
460         String pkg = mContext.getPackageName();
461         if (localLOGV) Log.v(TAG, pkg + ": cancelAll()");
462         try {
463             service.cancelAllNotifications(pkg, mContext.getUserId());
464         } catch (RemoteException e) {
465             throw e.rethrowFromSystemServer();
466         }
467     }
468 
469     /**
470      * Creates a group container for {@link NotificationChannel} objects.
471      *
472      * This can be used to rename an existing group.
473      * <p>
474      *     Group information is only used for presentation, not for behavior. Groups are optional
475      *     for channels, and you can have a mix of channels that belong to groups and channels
476      *     that do not.
477      * </p>
478      * <p>
479      *     For example, if your application supports multiple accounts, and those accounts will
480      *     have similar channels, you can create a group for each account with account specific
481      *     labels instead of appending account information to each channel's label.
482      * </p>
483      *
484      * @param group The group to create
485      */
createNotificationChannelGroup(@onNull NotificationChannelGroup group)486     public void createNotificationChannelGroup(@NonNull NotificationChannelGroup group) {
487         createNotificationChannelGroups(Arrays.asList(group));
488     }
489 
490     /**
491      * Creates multiple notification channel groups.
492      *
493      * @param groups The list of groups to create
494      */
createNotificationChannelGroups(@onNull List<NotificationChannelGroup> groups)495     public void createNotificationChannelGroups(@NonNull List<NotificationChannelGroup> groups) {
496         INotificationManager service = getService();
497         try {
498             service.createNotificationChannelGroups(mContext.getPackageName(),
499                     new ParceledListSlice(groups));
500         } catch (RemoteException e) {
501             throw e.rethrowFromSystemServer();
502         }
503     }
504 
505     /**
506      * Creates a notification channel that notifications can be posted to.
507      *
508      * This can also be used to restore a deleted channel and to update an existing channel's
509      * name, description, group, and/or importance.
510      *
511      * <p>The name and description should only be changed if the locale changes
512      * or in response to the user renaming this channel. For example, if a user has a channel
513      * named 'John Doe' that represents messages from a 'John Doe', and 'John Doe' changes his name
514      * to 'John Smith,' the channel can be renamed to match.
515      *
516      * <p>The importance of an existing channel will only be changed if the new importance is lower
517      * than the current value and the user has not altered any settings on this channel.
518      *
519      * <p>The group an existing channel will only be changed if the channel does not already
520      * belong to a group.
521      *
522      * All other fields are ignored for channels that already exist.
523      *
524      * @param channel  the channel to create.  Note that the created channel may differ from this
525      *                 value. If the provided channel is malformed, a RemoteException will be
526      *                 thrown.
527      */
createNotificationChannel(@onNull NotificationChannel channel)528     public void createNotificationChannel(@NonNull NotificationChannel channel) {
529         createNotificationChannels(Arrays.asList(channel));
530     }
531 
532     /**
533      * Creates multiple notification channels that different notifications can be posted to. See
534      * {@link #createNotificationChannel(NotificationChannel)}.
535      *
536      * @param channels the list of channels to attempt to create.
537      */
createNotificationChannels(@onNull List<NotificationChannel> channels)538     public void createNotificationChannels(@NonNull List<NotificationChannel> channels) {
539         INotificationManager service = getService();
540         try {
541             service.createNotificationChannels(mContext.getPackageName(),
542                     new ParceledListSlice(channels));
543         } catch (RemoteException e) {
544             throw e.rethrowFromSystemServer();
545         }
546     }
547 
548     /**
549      * Returns the notification channel settings for a given channel id.
550      *
551      * The channel must belong to your package, or it will not be returned.
552      */
getNotificationChannel(String channelId)553     public NotificationChannel getNotificationChannel(String channelId) {
554         INotificationManager service = getService();
555         try {
556             return service.getNotificationChannel(mContext.getPackageName(), channelId);
557         } catch (RemoteException e) {
558             throw e.rethrowFromSystemServer();
559         }
560     }
561 
562     /**
563      * Returns all notification channels belonging to the calling package.
564      */
getNotificationChannels()565     public List<NotificationChannel> getNotificationChannels() {
566         INotificationManager service = getService();
567         try {
568             return service.getNotificationChannels(mContext.getPackageName()).getList();
569         } catch (RemoteException e) {
570             throw e.rethrowFromSystemServer();
571         }
572     }
573 
574     /**
575      * Deletes the given notification channel.
576      *
577      * <p>If you {@link #createNotificationChannel(NotificationChannel) create} a new channel with
578      * this same id, the deleted channel will be un-deleted with all of the same settings it
579      * had before it was deleted.
580      */
deleteNotificationChannel(String channelId)581     public void deleteNotificationChannel(String channelId) {
582         INotificationManager service = getService();
583         try {
584             service.deleteNotificationChannel(mContext.getPackageName(), channelId);
585         } catch (RemoteException e) {
586             throw e.rethrowFromSystemServer();
587         }
588     }
589 
590     /**
591      * Returns the notification channel group settings for a given channel group id.
592      *
593      * The channel group must belong to your package, or null will be returned.
594      */
getNotificationChannelGroup(String channelGroupId)595     public NotificationChannelGroup getNotificationChannelGroup(String channelGroupId) {
596         INotificationManager service = getService();
597         try {
598             return service.getNotificationChannelGroup(mContext.getPackageName(), channelGroupId);
599         } catch (RemoteException e) {
600             throw e.rethrowFromSystemServer();
601         }
602     }
603 
604     /**
605      * Returns all notification channel groups belonging to the calling app.
606      */
getNotificationChannelGroups()607     public List<NotificationChannelGroup> getNotificationChannelGroups() {
608         INotificationManager service = getService();
609         try {
610             return service.getNotificationChannelGroups(mContext.getPackageName()).getList();
611         } catch (RemoteException e) {
612             throw e.rethrowFromSystemServer();
613         }
614     }
615 
616     /**
617      * Deletes the given notification channel group, and all notification channels that
618      * belong to it.
619      */
deleteNotificationChannelGroup(String groupId)620     public void deleteNotificationChannelGroup(String groupId) {
621         INotificationManager service = getService();
622         try {
623             service.deleteNotificationChannelGroup(mContext.getPackageName(), groupId);
624         } catch (RemoteException e) {
625             throw e.rethrowFromSystemServer();
626         }
627     }
628 
629     /**
630      * @hide
631      */
632     @TestApi
getEffectsSuppressor()633     public ComponentName getEffectsSuppressor() {
634         INotificationManager service = getService();
635         try {
636             return service.getEffectsSuppressor();
637         } catch (RemoteException e) {
638             throw e.rethrowFromSystemServer();
639         }
640     }
641 
642     /**
643      * @hide
644      */
matchesCallFilter(Bundle extras)645     public boolean matchesCallFilter(Bundle extras) {
646         INotificationManager service = getService();
647         try {
648             return service.matchesCallFilter(extras);
649         } catch (RemoteException e) {
650             throw e.rethrowFromSystemServer();
651         }
652     }
653 
654     /**
655      * @hide
656      */
isSystemConditionProviderEnabled(String path)657     public boolean isSystemConditionProviderEnabled(String path) {
658         INotificationManager service = getService();
659         try {
660             return service.isSystemConditionProviderEnabled(path);
661         } catch (RemoteException e) {
662             throw e.rethrowFromSystemServer();
663         }
664     }
665 
666     /**
667      * @hide
668      */
setZenMode(int mode, Uri conditionId, String reason)669     public void setZenMode(int mode, Uri conditionId, String reason) {
670         INotificationManager service = getService();
671         try {
672             service.setZenMode(mode, conditionId, reason);
673         } catch (RemoteException e) {
674             throw e.rethrowFromSystemServer();
675         }
676     }
677 
678     /**
679      * @hide
680      */
getZenMode()681     public int getZenMode() {
682         INotificationManager service = getService();
683         try {
684             return service.getZenMode();
685         } catch (RemoteException e) {
686             throw e.rethrowFromSystemServer();
687         }
688     }
689 
690     /**
691      * @hide
692      */
getZenModeConfig()693     public ZenModeConfig getZenModeConfig() {
694         INotificationManager service = getService();
695         try {
696             return service.getZenModeConfig();
697         } catch (RemoteException e) {
698             throw e.rethrowFromSystemServer();
699         }
700     }
701 
702     /**
703      * @hide
704      */
getRuleInstanceCount(ComponentName owner)705     public int getRuleInstanceCount(ComponentName owner) {
706         INotificationManager service = getService();
707         try {
708             return service.getRuleInstanceCount(owner);
709         } catch (RemoteException e) {
710             throw e.rethrowFromSystemServer();
711         }
712     }
713 
714     /**
715      * Returns AutomaticZenRules owned by the caller.
716      *
717      * <p>
718      * Throws a SecurityException if policy access is granted to this package.
719      * See {@link #isNotificationPolicyAccessGranted}.
720      */
getAutomaticZenRules()721     public Map<String, AutomaticZenRule> getAutomaticZenRules() {
722         INotificationManager service = getService();
723         try {
724             List<ZenModeConfig.ZenRule> rules = service.getZenRules();
725             Map<String, AutomaticZenRule> ruleMap = new HashMap<>();
726             for (ZenModeConfig.ZenRule rule : rules) {
727                 ruleMap.put(rule.id, new AutomaticZenRule(rule.name, rule.component,
728                         rule.conditionId, zenModeToInterruptionFilter(rule.zenMode), rule.enabled,
729                         rule.creationTime));
730             }
731             return ruleMap;
732         } catch (RemoteException e) {
733             throw e.rethrowFromSystemServer();
734         }
735     }
736 
737     /**
738      * Returns the AutomaticZenRule with the given id, if it exists and the caller has access.
739      *
740      * <p>
741      * Throws a SecurityException if policy access is granted to this package.
742      * See {@link #isNotificationPolicyAccessGranted}.
743      *
744      * <p>
745      * Returns null if there are no zen rules that match the given id, or if the calling package
746      * doesn't own the matching rule. See {@link AutomaticZenRule#getOwner}.
747      */
getAutomaticZenRule(String id)748     public AutomaticZenRule getAutomaticZenRule(String id) {
749         INotificationManager service = getService();
750         try {
751             return service.getAutomaticZenRule(id);
752         } catch (RemoteException e) {
753             throw e.rethrowFromSystemServer();
754         }
755     }
756 
757     /**
758      * Creates the given zen rule.
759      *
760      * <p>
761      * Throws a SecurityException if policy access is granted to this package.
762      * See {@link #isNotificationPolicyAccessGranted}.
763      *
764      * @param automaticZenRule the rule to create.
765      * @return The id of the newly created rule; null if the rule could not be created.
766      */
addAutomaticZenRule(AutomaticZenRule automaticZenRule)767     public String addAutomaticZenRule(AutomaticZenRule automaticZenRule) {
768         INotificationManager service = getService();
769         try {
770             return service.addAutomaticZenRule(automaticZenRule);
771         } catch (RemoteException e) {
772             throw e.rethrowFromSystemServer();
773         }
774     }
775 
776     /**
777      * Updates the given zen rule.
778      *
779      * <p>
780      * Throws a SecurityException if policy access is granted to this package.
781      * See {@link #isNotificationPolicyAccessGranted}.
782      *
783      * <p>
784      * Callers can only update rules that they own. See {@link AutomaticZenRule#getOwner}.
785      * @param id The id of the rule to update
786      * @param automaticZenRule the rule to update.
787      * @return Whether the rule was successfully updated.
788      */
updateAutomaticZenRule(String id, AutomaticZenRule automaticZenRule)789     public boolean updateAutomaticZenRule(String id, AutomaticZenRule automaticZenRule) {
790         INotificationManager service = getService();
791         try {
792             return service.updateAutomaticZenRule(id, automaticZenRule);
793         } catch (RemoteException e) {
794             throw e.rethrowFromSystemServer();
795         }
796     }
797 
798     /**
799      * Deletes the automatic zen rule with the given id.
800      *
801      * <p>
802      * Throws a SecurityException if policy access is granted to this package.
803      * See {@link #isNotificationPolicyAccessGranted}.
804      *
805      * <p>
806      * Callers can only delete rules that they own. See {@link AutomaticZenRule#getOwner}.
807      * @param id the id of the rule to delete.
808      * @return Whether the rule was successfully deleted.
809      */
removeAutomaticZenRule(String id)810     public boolean removeAutomaticZenRule(String id) {
811         INotificationManager service = getService();
812         try {
813             return service.removeAutomaticZenRule(id);
814         } catch (RemoteException e) {
815             throw e.rethrowFromSystemServer();
816         }
817     }
818 
819     /**
820      * Deletes all automatic zen rules owned by the given package.
821      *
822      * @hide
823      */
removeAutomaticZenRules(String packageName)824     public boolean removeAutomaticZenRules(String packageName) {
825         INotificationManager service = getService();
826         try {
827             return service.removeAutomaticZenRules(packageName);
828         } catch (RemoteException e) {
829             throw e.rethrowFromSystemServer();
830         }
831     }
832 
833     /**
834      * Returns the user specified importance for notifications from the calling
835      * package.
836      */
getImportance()837     public @Importance int getImportance() {
838         INotificationManager service = getService();
839         try {
840             return service.getPackageImportance(mContext.getPackageName());
841         } catch (RemoteException e) {
842             throw e.rethrowFromSystemServer();
843         }
844     }
845 
846     /**
847      * Returns whether notifications from the calling package are blocked.
848      */
areNotificationsEnabled()849     public boolean areNotificationsEnabled() {
850         INotificationManager service = getService();
851         try {
852             return service.areNotificationsEnabled(mContext.getPackageName());
853         } catch (RemoteException e) {
854             throw e.rethrowFromSystemServer();
855         }
856     }
857 
858     /**
859      * Checks the ability to modify notification do not disturb policy for the calling package.
860      *
861      * <p>
862      * Returns true if the calling package can modify notification policy.
863      *
864      * <p>
865      * Apps can request policy access by sending the user to the activity that matches the system
866      * intent action {@link android.provider.Settings#ACTION_NOTIFICATION_POLICY_ACCESS_SETTINGS}.
867      *
868      * <p>
869      * Use {@link #ACTION_NOTIFICATION_POLICY_ACCESS_GRANTED_CHANGED} to listen for
870      * user grant or denial of this access.
871      */
isNotificationPolicyAccessGranted()872     public boolean isNotificationPolicyAccessGranted() {
873         INotificationManager service = getService();
874         try {
875             return service.isNotificationPolicyAccessGranted(mContext.getOpPackageName());
876         } catch (RemoteException e) {
877             throw e.rethrowFromSystemServer();
878         }
879     }
880 
881     /**
882      * Checks whether the user has approved a given
883      * {@link android.service.notification.NotificationListenerService}.
884      *
885      * <p>
886      * The listener service must belong to the calling app.
887      *
888      * <p>
889      * Apps can request notification listener access by sending the user to the activity that
890      * matches the system intent action
891      * {@link android.provider.Settings#ACTION_NOTIFICATION_LISTENER_SETTINGS}.
892      */
isNotificationListenerAccessGranted(ComponentName listener)893     public boolean isNotificationListenerAccessGranted(ComponentName listener) {
894         INotificationManager service = getService();
895         try {
896             return service.isNotificationListenerAccessGranted(listener);
897         } catch (RemoteException e) {
898             throw e.rethrowFromSystemServer();
899         }
900     }
901 
902     /**
903      * @hide
904      */
isNotificationAssistantAccessGranted(ComponentName assistant)905     public boolean isNotificationAssistantAccessGranted(ComponentName assistant) {
906         INotificationManager service = getService();
907         try {
908             return service.isNotificationAssistantAccessGranted(assistant);
909         } catch (RemoteException e) {
910             throw e.rethrowFromSystemServer();
911         }
912     }
913 
914     /** @hide */
isNotificationPolicyAccessGrantedForPackage(String pkg)915     public boolean isNotificationPolicyAccessGrantedForPackage(String pkg) {
916         INotificationManager service = getService();
917         try {
918             return service.isNotificationPolicyAccessGrantedForPackage(pkg);
919         } catch (RemoteException e) {
920             throw e.rethrowFromSystemServer();
921         }
922     }
923 
924     /**
925      * @hide
926      */
getEnabledNotificationListenerPackages()927     public List<String> getEnabledNotificationListenerPackages() {
928         INotificationManager service = getService();
929         try {
930             return service.getEnabledNotificationListenerPackages();
931         } catch (RemoteException e) {
932             throw e.rethrowFromSystemServer();
933         }
934     }
935 
936     /**
937      * Gets the current notification policy.
938      *
939      * <p>
940      */
getNotificationPolicy()941     public Policy getNotificationPolicy() {
942         INotificationManager service = getService();
943         try {
944             return service.getNotificationPolicy(mContext.getOpPackageName());
945         } catch (RemoteException e) {
946             throw e.rethrowFromSystemServer();
947         }
948     }
949 
950     /**
951      * Sets the current notification policy.
952      *
953      * <p>
954      * Only available if policy access is granted to this package.
955      * See {@link #isNotificationPolicyAccessGranted}.
956      *
957      * @param policy The new desired policy.
958      */
setNotificationPolicy(@onNull Policy policy)959     public void setNotificationPolicy(@NonNull Policy policy) {
960         checkRequired("policy", policy);
961         INotificationManager service = getService();
962         try {
963             service.setNotificationPolicy(mContext.getOpPackageName(), policy);
964         } catch (RemoteException e) {
965             throw e.rethrowFromSystemServer();
966         }
967     }
968 
969     /** @hide */
setNotificationPolicyAccessGranted(String pkg, boolean granted)970     public void setNotificationPolicyAccessGranted(String pkg, boolean granted) {
971         INotificationManager service = getService();
972         try {
973             service.setNotificationPolicyAccessGranted(pkg, granted);
974         } catch (RemoteException e) {
975             throw e.rethrowFromSystemServer();
976         }
977     }
978 
979     /** @hide */
setNotificationListenerAccessGranted(ComponentName listener, boolean granted)980     public void setNotificationListenerAccessGranted(ComponentName listener, boolean granted) {
981         INotificationManager service = getService();
982         try {
983             service.setNotificationListenerAccessGranted(listener, granted);
984         } catch (RemoteException e) {
985             throw e.rethrowFromSystemServer();
986         }
987     }
988 
989     /** @hide */
setNotificationListenerAccessGrantedForUser(ComponentName listener, int userId, boolean granted)990     public void setNotificationListenerAccessGrantedForUser(ComponentName listener, int userId,
991             boolean granted) {
992         INotificationManager service = getService();
993         try {
994             service.setNotificationListenerAccessGrantedForUser(listener, userId, granted);
995         } catch (RemoteException e) {
996             throw e.rethrowFromSystemServer();
997         }
998     }
999 
1000     /** @hide */
getEnabledNotificationListeners(int userId)1001     public List<ComponentName> getEnabledNotificationListeners(int userId) {
1002         INotificationManager service = getService();
1003         try {
1004             return service.getEnabledNotificationListeners(userId);
1005         } catch (RemoteException e) {
1006             throw e.rethrowFromSystemServer();
1007         }
1008     }
1009 
1010     private Context mContext;
1011 
checkRequired(String name, Object value)1012     private static void checkRequired(String name, Object value) {
1013         if (value == null) {
1014             throw new IllegalArgumentException(name + " is required");
1015         }
1016     }
1017 
1018     /**
1019      * Notification policy configuration.  Represents user-preferences for notification
1020      * filtering.
1021      */
1022     public static class Policy implements android.os.Parcelable {
1023         /** Reminder notifications are prioritized. */
1024         public static final int PRIORITY_CATEGORY_REMINDERS = 1 << 0;
1025         /** Event notifications are prioritized. */
1026         public static final int PRIORITY_CATEGORY_EVENTS = 1 << 1;
1027         /** Message notifications are prioritized. */
1028         public static final int PRIORITY_CATEGORY_MESSAGES = 1 << 2;
1029         /** Calls are prioritized. */
1030         public static final int PRIORITY_CATEGORY_CALLS = 1 << 3;
1031         /** Calls from repeat callers are prioritized. */
1032         public static final int PRIORITY_CATEGORY_REPEAT_CALLERS = 1 << 4;
1033         /** Alarms are prioritized */
1034         public static final int PRIORITY_CATEGORY_ALARMS = 1 << 5;
1035         /** Media, game, voice navigation are prioritized */
1036         public static final int PRIORITY_CATEGORY_MEDIA = 1 << 6;
1037         /**System (catch-all for non-never suppressible sounds) are prioritized */
1038         public static final int PRIORITY_CATEGORY_SYSTEM = 1 << 7;
1039 
1040         /**
1041          * @hide
1042          */
1043         public static final int[] ALL_PRIORITY_CATEGORIES = {
1044             PRIORITY_CATEGORY_ALARMS,
1045             PRIORITY_CATEGORY_MEDIA,
1046             PRIORITY_CATEGORY_SYSTEM,
1047             PRIORITY_CATEGORY_REMINDERS,
1048             PRIORITY_CATEGORY_EVENTS,
1049             PRIORITY_CATEGORY_MESSAGES,
1050             PRIORITY_CATEGORY_CALLS,
1051             PRIORITY_CATEGORY_REPEAT_CALLERS,
1052         };
1053 
1054         /** Any sender is prioritized. */
1055         public static final int PRIORITY_SENDERS_ANY = 0;
1056         /** Saved contacts are prioritized. */
1057         public static final int PRIORITY_SENDERS_CONTACTS = 1;
1058         /** Only starred contacts are prioritized. */
1059         public static final int PRIORITY_SENDERS_STARRED = 2;
1060 
1061         /** Notification categories to prioritize. Bitmask of PRIORITY_CATEGORY_* constants. */
1062         public final int priorityCategories;
1063 
1064         /** Notification senders to prioritize for calls. One of:
1065          * PRIORITY_SENDERS_ANY, PRIORITY_SENDERS_CONTACTS, PRIORITY_SENDERS_STARRED */
1066         public final int priorityCallSenders;
1067 
1068         /** Notification senders to prioritize for messages. One of:
1069          * PRIORITY_SENDERS_ANY, PRIORITY_SENDERS_CONTACTS, PRIORITY_SENDERS_STARRED */
1070         public final int priorityMessageSenders;
1071 
1072         /**
1073          * @hide
1074          */
1075         public static final int SUPPRESSED_EFFECTS_UNSET = -1;
1076 
1077         /**
1078          * Whether notifications suppressed by DND should not interrupt visually (e.g. with
1079          * notification lights or by turning the screen on) when the screen is off.
1080          *
1081          * @deprecated use {@link #SUPPRESSED_EFFECT_FULL_SCREEN_INTENT} and
1082          * {@link #SUPPRESSED_EFFECT_AMBIENT} and {@link #SUPPRESSED_EFFECT_LIGHTS} individually.
1083          */
1084         @Deprecated
1085         public static final int SUPPRESSED_EFFECT_SCREEN_OFF = 1 << 0;
1086         /**
1087          * Whether notifications suppressed by DND should not interrupt visually when the screen
1088          * is on (e.g. by peeking onto the screen).
1089          *
1090          * @deprecated use {@link #SUPPRESSED_EFFECT_PEEK}.
1091          */
1092         @Deprecated
1093         public static final int SUPPRESSED_EFFECT_SCREEN_ON = 1 << 1;
1094 
1095         /**
1096          * Whether {@link Notification#fullScreenIntent full screen intents} from
1097          * notifications intercepted by DND are blocked.
1098          */
1099         public static final int SUPPRESSED_EFFECT_FULL_SCREEN_INTENT = 1 << 2;
1100 
1101         /**
1102          * Whether {@link NotificationChannel#shouldShowLights() notification lights} from
1103          * notifications intercepted by DND are blocked.
1104          */
1105         public static final int SUPPRESSED_EFFECT_LIGHTS = 1 << 3;
1106 
1107         /**
1108          * Whether notifications intercepted by DND are prevented from peeking.
1109          */
1110         public static final int SUPPRESSED_EFFECT_PEEK = 1 << 4;
1111 
1112         /**
1113          * Whether notifications intercepted by DND are prevented from appearing in the status bar,
1114          * on devices that support status bars.
1115          */
1116         public static final int SUPPRESSED_EFFECT_STATUS_BAR = 1 << 5;
1117 
1118         /**
1119          * Whether {@link NotificationChannel#canShowBadge() badges} from
1120          * notifications intercepted by DND are blocked on devices that support badging.
1121          */
1122         public static final int SUPPRESSED_EFFECT_BADGE = 1 << 6;
1123 
1124         /**
1125          * Whether notification intercepted by DND are prevented from appearing on ambient displays
1126          * on devices that support ambient display.
1127          */
1128         public static final int SUPPRESSED_EFFECT_AMBIENT = 1 << 7;
1129 
1130         /**
1131          * Whether notification intercepted by DND are prevented from appearing in notification
1132          * list views like the notification shade or lockscreen on devices that support those
1133          * views.
1134          */
1135         public static final int SUPPRESSED_EFFECT_NOTIFICATION_LIST = 1 << 8;
1136 
1137         private static final int[] ALL_SUPPRESSED_EFFECTS = {
1138                 SUPPRESSED_EFFECT_SCREEN_OFF,
1139                 SUPPRESSED_EFFECT_SCREEN_ON,
1140                 SUPPRESSED_EFFECT_FULL_SCREEN_INTENT,
1141                 SUPPRESSED_EFFECT_LIGHTS,
1142                 SUPPRESSED_EFFECT_PEEK,
1143                 SUPPRESSED_EFFECT_STATUS_BAR,
1144                 SUPPRESSED_EFFECT_BADGE,
1145                 SUPPRESSED_EFFECT_AMBIENT,
1146                 SUPPRESSED_EFFECT_NOTIFICATION_LIST
1147         };
1148 
1149         private static final int[] SCREEN_OFF_SUPPRESSED_EFFECTS = {
1150                 SUPPRESSED_EFFECT_SCREEN_OFF,
1151                 SUPPRESSED_EFFECT_FULL_SCREEN_INTENT,
1152                 SUPPRESSED_EFFECT_LIGHTS,
1153                 SUPPRESSED_EFFECT_AMBIENT,
1154         };
1155 
1156         private static final int[] SCREEN_ON_SUPPRESSED_EFFECTS = {
1157                 SUPPRESSED_EFFECT_SCREEN_ON,
1158                 SUPPRESSED_EFFECT_PEEK,
1159                 SUPPRESSED_EFFECT_STATUS_BAR,
1160                 SUPPRESSED_EFFECT_BADGE,
1161                 SUPPRESSED_EFFECT_NOTIFICATION_LIST
1162         };
1163 
1164         /**
1165          * Visual effects to suppress for a notification that is filtered by Do Not Disturb mode.
1166          * Bitmask of SUPPRESSED_EFFECT_* constants.
1167          */
1168         public final int suppressedVisualEffects;
1169 
1170         /**
1171          * @hide
1172          */
1173         public static final int STATE_CHANNELS_BYPASSING_DND = 1 << 0;
1174 
1175         /**
1176          * @hide
1177          */
1178         public static final int STATE_UNSET = -1;
1179 
1180         /**
1181          * Notification state information that is necessary to determine Do Not Disturb behavior.
1182          * Bitmask of STATE_* constants.
1183          * @hide
1184          */
1185         public final int state;
1186 
1187         /**
1188          * Constructs a policy for Do Not Disturb priority mode behavior.
1189          *
1190          * <p>
1191          *     Apps that target API levels below {@link Build.VERSION_CODES#P} cannot
1192          *     change user-designated values to allow or disallow
1193          *     {@link Policy#PRIORITY_CATEGORY_ALARMS}, {@link Policy#PRIORITY_CATEGORY_SYSTEM}, and
1194          *     {@link Policy#PRIORITY_CATEGORY_MEDIA} from bypassing dnd.
1195          *
1196          * @param priorityCategories bitmask of categories of notifications that can bypass DND.
1197          * @param priorityCallSenders which callers can bypass DND.
1198          * @param priorityMessageSenders which message senders can bypass DND.
1199          */
Policy(int priorityCategories, int priorityCallSenders, int priorityMessageSenders)1200         public Policy(int priorityCategories, int priorityCallSenders, int priorityMessageSenders) {
1201             this(priorityCategories, priorityCallSenders, priorityMessageSenders,
1202                     SUPPRESSED_EFFECTS_UNSET, STATE_UNSET);
1203         }
1204 
1205         /**
1206          * Constructs a policy for Do Not Disturb priority mode behavior.
1207          *
1208          * <p>
1209          *     Apps that target API levels below {@link Build.VERSION_CODES#P} cannot
1210          *     change user-designated values to allow or disallow
1211          *     {@link Policy#PRIORITY_CATEGORY_ALARMS}, {@link Policy#PRIORITY_CATEGORY_SYSTEM}, and
1212          *     {@link Policy#PRIORITY_CATEGORY_MEDIA} from bypassing dnd.
1213          * <p>
1214          *     Additionally, apps that target API levels below {@link Build.VERSION_CODES#P} can
1215          *     only modify the {@link #SUPPRESSED_EFFECT_SCREEN_ON} and
1216          *     {@link #SUPPRESSED_EFFECT_SCREEN_OFF} bits of the suppressed visual effects field.
1217          *     All other suppressed effects will be ignored and reconstituted from the screen on
1218          *     and screen off values.
1219          * <p>
1220          *     Apps that target {@link Build.VERSION_CODES#P} or above can set any
1221          *     suppressed visual effects. However, if any suppressed effects >
1222          *     {@link #SUPPRESSED_EFFECT_SCREEN_ON} are set, {@link #SUPPRESSED_EFFECT_SCREEN_ON}
1223          *     and {@link #SUPPRESSED_EFFECT_SCREEN_OFF} will be ignored and reconstituted from
1224          *     the more specific suppressed visual effect bits. Apps should migrate to targeting
1225          *     specific effects instead of the deprecated {@link #SUPPRESSED_EFFECT_SCREEN_ON} and
1226          *     {@link #SUPPRESSED_EFFECT_SCREEN_OFF} effects.
1227          *
1228          * @param priorityCategories bitmask of categories of notifications that can bypass DND.
1229          * @param priorityCallSenders which callers can bypass DND.
1230          * @param priorityMessageSenders which message senders can bypass DND.
1231          * @param suppressedVisualEffects which visual interruptions should be suppressed from
1232          *                                notifications that are filtered by DND.
1233          */
Policy(int priorityCategories, int priorityCallSenders, int priorityMessageSenders, int suppressedVisualEffects)1234         public Policy(int priorityCategories, int priorityCallSenders, int priorityMessageSenders,
1235                 int suppressedVisualEffects) {
1236             this.priorityCategories = priorityCategories;
1237             this.priorityCallSenders = priorityCallSenders;
1238             this.priorityMessageSenders = priorityMessageSenders;
1239             this.suppressedVisualEffects = suppressedVisualEffects;
1240             this.state = STATE_UNSET;
1241         }
1242 
1243         /** @hide */
Policy(int priorityCategories, int priorityCallSenders, int priorityMessageSenders, int suppressedVisualEffects, int state)1244         public Policy(int priorityCategories, int priorityCallSenders, int priorityMessageSenders,
1245                 int suppressedVisualEffects, int state) {
1246             this.priorityCategories = priorityCategories;
1247             this.priorityCallSenders = priorityCallSenders;
1248             this.priorityMessageSenders = priorityMessageSenders;
1249             this.suppressedVisualEffects = suppressedVisualEffects;
1250             this.state = state;
1251         }
1252 
1253         /** @hide */
Policy(Parcel source)1254         public Policy(Parcel source) {
1255             this(source.readInt(), source.readInt(), source.readInt(), source.readInt(),
1256                     source.readInt());
1257         }
1258 
1259         @Override
writeToParcel(Parcel dest, int flags)1260         public void writeToParcel(Parcel dest, int flags) {
1261             dest.writeInt(priorityCategories);
1262             dest.writeInt(priorityCallSenders);
1263             dest.writeInt(priorityMessageSenders);
1264             dest.writeInt(suppressedVisualEffects);
1265             dest.writeInt(state);
1266         }
1267 
1268         @Override
describeContents()1269         public int describeContents() {
1270             return 0;
1271         }
1272 
1273         @Override
hashCode()1274         public int hashCode() {
1275             return Objects.hash(priorityCategories, priorityCallSenders, priorityMessageSenders,
1276                     suppressedVisualEffects);
1277         }
1278 
1279         @Override
equals(Object o)1280         public boolean equals(Object o) {
1281             if (!(o instanceof Policy)) return false;
1282             if (o == this) return true;
1283             final Policy other = (Policy) o;
1284             return other.priorityCategories == priorityCategories
1285                     && other.priorityCallSenders == priorityCallSenders
1286                     && other.priorityMessageSenders == priorityMessageSenders
1287                     && other.suppressedVisualEffects == suppressedVisualEffects;
1288         }
1289 
1290         @Override
toString()1291         public String toString() {
1292             return "NotificationManager.Policy["
1293                     + "priorityCategories=" + priorityCategoriesToString(priorityCategories)
1294                     + ",priorityCallSenders=" + prioritySendersToString(priorityCallSenders)
1295                     + ",priorityMessageSenders=" + prioritySendersToString(priorityMessageSenders)
1296                     + ",suppressedVisualEffects="
1297                     + suppressedEffectsToString(suppressedVisualEffects)
1298                     + ",areChannelsBypassingDnd=" + (((state & STATE_CHANNELS_BYPASSING_DND) != 0)
1299                         ? "true" : "false")
1300                     + "]";
1301         }
1302 
1303         /** @hide */
writeToProto(ProtoOutputStream proto, long fieldId)1304         public void writeToProto(ProtoOutputStream proto, long fieldId) {
1305             final long pToken = proto.start(fieldId);
1306 
1307             bitwiseToProtoEnum(proto, PolicyProto.PRIORITY_CATEGORIES, priorityCategories);
1308             proto.write(PolicyProto.PRIORITY_CALL_SENDER, priorityCallSenders);
1309             proto.write(PolicyProto.PRIORITY_MESSAGE_SENDER, priorityMessageSenders);
1310             bitwiseToProtoEnum(
1311                     proto, PolicyProto.SUPPRESSED_VISUAL_EFFECTS, suppressedVisualEffects);
1312 
1313             proto.end(pToken);
1314         }
1315 
bitwiseToProtoEnum(ProtoOutputStream proto, long fieldId, int data)1316         private static void bitwiseToProtoEnum(ProtoOutputStream proto, long fieldId, int data) {
1317             for (int i = 1; data > 0; ++i, data >>>= 1) {
1318                 if ((data & 1) == 1) {
1319                     proto.write(fieldId, i);
1320                 }
1321             }
1322         }
1323 
1324         /**
1325          * @hide
1326          */
getAllSuppressedVisualEffects()1327         public static int getAllSuppressedVisualEffects() {
1328             int effects = 0;
1329             for (int i = 0; i < ALL_SUPPRESSED_EFFECTS.length; i++) {
1330                 effects |= ALL_SUPPRESSED_EFFECTS[i];
1331             }
1332             return effects;
1333         }
1334 
1335         /**
1336          * @hide
1337          */
areAllVisualEffectsSuppressed(int effects)1338         public static boolean areAllVisualEffectsSuppressed(int effects) {
1339             for (int i = 0; i < ALL_SUPPRESSED_EFFECTS.length; i++) {
1340                 final int effect = ALL_SUPPRESSED_EFFECTS[i];
1341                 if ((effects & effect) == 0) {
1342                     return false;
1343                 }
1344             }
1345             return true;
1346         }
1347 
1348         /**
1349          * @hide
1350          */
areAnyScreenOffEffectsSuppressed(int effects)1351         public static boolean areAnyScreenOffEffectsSuppressed(int effects) {
1352             for (int i = 0; i < SCREEN_OFF_SUPPRESSED_EFFECTS.length; i++) {
1353                 final int effect = SCREEN_OFF_SUPPRESSED_EFFECTS[i];
1354                 if ((effects & effect) != 0) {
1355                     return true;
1356                 }
1357             }
1358             return false;
1359         }
1360 
1361         /**
1362          * @hide
1363          */
areAnyScreenOnEffectsSuppressed(int effects)1364         public static boolean areAnyScreenOnEffectsSuppressed(int effects) {
1365             for (int i = 0; i < SCREEN_ON_SUPPRESSED_EFFECTS.length; i++) {
1366                 final int effect = SCREEN_ON_SUPPRESSED_EFFECTS[i];
1367                 if ((effects & effect) != 0) {
1368                     return true;
1369                 }
1370             }
1371             return false;
1372         }
1373 
1374         /**
1375          * @hide
1376          */
toggleScreenOffEffectsSuppressed(int currentEffects, boolean suppress)1377         public static int toggleScreenOffEffectsSuppressed(int currentEffects, boolean suppress) {
1378             return toggleEffects(currentEffects, SCREEN_OFF_SUPPRESSED_EFFECTS, suppress);
1379         }
1380 
1381         /**
1382          * @hide
1383          */
toggleScreenOnEffectsSuppressed(int currentEffects, boolean suppress)1384         public static int toggleScreenOnEffectsSuppressed(int currentEffects, boolean suppress) {
1385             return toggleEffects(currentEffects, SCREEN_ON_SUPPRESSED_EFFECTS, suppress);
1386         }
1387 
toggleEffects(int currentEffects, int[] effects, boolean suppress)1388         private static int toggleEffects(int currentEffects, int[] effects, boolean suppress) {
1389             for (int i = 0; i < effects.length; i++) {
1390                 final int effect = effects[i];
1391                 if (suppress) {
1392                     currentEffects |= effect;
1393                 } else {
1394                     currentEffects &= ~effect;
1395                 }
1396             }
1397             return currentEffects;
1398         }
1399 
suppressedEffectsToString(int effects)1400         public static String suppressedEffectsToString(int effects) {
1401             if (effects <= 0) return "";
1402             final StringBuilder sb = new StringBuilder();
1403             for (int i = 0; i < ALL_SUPPRESSED_EFFECTS.length; i++) {
1404                 final int effect = ALL_SUPPRESSED_EFFECTS[i];
1405                 if ((effects & effect) != 0) {
1406                     if (sb.length() > 0) sb.append(',');
1407                     sb.append(effectToString(effect));
1408                 }
1409                 effects &= ~effect;
1410             }
1411             if (effects != 0) {
1412                 if (sb.length() > 0) sb.append(',');
1413                 sb.append("UNKNOWN_").append(effects);
1414             }
1415             return sb.toString();
1416         }
1417 
priorityCategoriesToString(int priorityCategories)1418         public static String priorityCategoriesToString(int priorityCategories) {
1419             if (priorityCategories == 0) return "";
1420             final StringBuilder sb = new StringBuilder();
1421             for (int i = 0; i < ALL_PRIORITY_CATEGORIES.length; i++) {
1422                 final int priorityCategory = ALL_PRIORITY_CATEGORIES[i];
1423                 if ((priorityCategories & priorityCategory) != 0) {
1424                     if (sb.length() > 0) sb.append(',');
1425                     sb.append(priorityCategoryToString(priorityCategory));
1426                 }
1427                 priorityCategories &= ~priorityCategory;
1428             }
1429             if (priorityCategories != 0) {
1430                 if (sb.length() > 0) sb.append(',');
1431                 sb.append("PRIORITY_CATEGORY_UNKNOWN_").append(priorityCategories);
1432             }
1433             return sb.toString();
1434         }
1435 
effectToString(int effect)1436         private static String effectToString(int effect) {
1437             switch (effect) {
1438                 case SUPPRESSED_EFFECT_FULL_SCREEN_INTENT:
1439                     return "SUPPRESSED_EFFECT_FULL_SCREEN_INTENT";
1440                 case SUPPRESSED_EFFECT_LIGHTS:
1441                     return "SUPPRESSED_EFFECT_LIGHTS";
1442                 case SUPPRESSED_EFFECT_PEEK:
1443                     return "SUPPRESSED_EFFECT_PEEK";
1444                 case SUPPRESSED_EFFECT_STATUS_BAR:
1445                     return "SUPPRESSED_EFFECT_STATUS_BAR";
1446                 case SUPPRESSED_EFFECT_BADGE:
1447                     return "SUPPRESSED_EFFECT_BADGE";
1448                 case SUPPRESSED_EFFECT_AMBIENT:
1449                     return "SUPPRESSED_EFFECT_AMBIENT";
1450                 case SUPPRESSED_EFFECT_NOTIFICATION_LIST:
1451                     return "SUPPRESSED_EFFECT_NOTIFICATION_LIST";
1452                 case SUPPRESSED_EFFECT_SCREEN_OFF:
1453                     return "SUPPRESSED_EFFECT_SCREEN_OFF";
1454                 case SUPPRESSED_EFFECT_SCREEN_ON:
1455                     return "SUPPRESSED_EFFECT_SCREEN_ON";
1456                 case SUPPRESSED_EFFECTS_UNSET:
1457                     return "SUPPRESSED_EFFECTS_UNSET";
1458                 default: return "UNKNOWN_" + effect;
1459             }
1460         }
1461 
priorityCategoryToString(int priorityCategory)1462         private static String priorityCategoryToString(int priorityCategory) {
1463             switch (priorityCategory) {
1464                 case PRIORITY_CATEGORY_REMINDERS: return "PRIORITY_CATEGORY_REMINDERS";
1465                 case PRIORITY_CATEGORY_EVENTS: return "PRIORITY_CATEGORY_EVENTS";
1466                 case PRIORITY_CATEGORY_MESSAGES: return "PRIORITY_CATEGORY_MESSAGES";
1467                 case PRIORITY_CATEGORY_CALLS: return "PRIORITY_CATEGORY_CALLS";
1468                 case PRIORITY_CATEGORY_REPEAT_CALLERS: return "PRIORITY_CATEGORY_REPEAT_CALLERS";
1469                 case PRIORITY_CATEGORY_ALARMS: return "PRIORITY_CATEGORY_ALARMS";
1470                 case PRIORITY_CATEGORY_MEDIA: return "PRIORITY_CATEGORY_MEDIA";
1471                 case PRIORITY_CATEGORY_SYSTEM: return "PRIORITY_CATEGORY_SYSTEM";
1472                 default: return "PRIORITY_CATEGORY_UNKNOWN_" + priorityCategory;
1473             }
1474         }
1475 
prioritySendersToString(int prioritySenders)1476         public static String prioritySendersToString(int prioritySenders) {
1477             switch (prioritySenders) {
1478                 case PRIORITY_SENDERS_ANY: return "PRIORITY_SENDERS_ANY";
1479                 case PRIORITY_SENDERS_CONTACTS: return "PRIORITY_SENDERS_CONTACTS";
1480                 case PRIORITY_SENDERS_STARRED: return "PRIORITY_SENDERS_STARRED";
1481                 default: return "PRIORITY_SENDERS_UNKNOWN_" + prioritySenders;
1482             }
1483         }
1484 
1485         public static final Parcelable.Creator<Policy> CREATOR = new Parcelable.Creator<Policy>() {
1486             @Override
1487             public Policy createFromParcel(Parcel in) {
1488                 return new Policy(in);
1489             }
1490 
1491             @Override
1492             public Policy[] newArray(int size) {
1493                 return new Policy[size];
1494             }
1495         };
1496     }
1497 
1498     /**
1499      * Recover a list of active notifications: ones that have been posted by the calling app that
1500      * have not yet been dismissed by the user or {@link #cancel(String, int)}ed by the app.
1501      *
1502      * Each notification is embedded in a {@link StatusBarNotification} object, including the
1503      * original <code>tag</code> and <code>id</code> supplied to
1504      * {@link #notify(String, int, Notification) notify()}
1505      * (via {@link StatusBarNotification#getTag() getTag()} and
1506      * {@link StatusBarNotification#getId() getId()}) as well as a copy of the original
1507      * {@link Notification} object (via {@link StatusBarNotification#getNotification()}).
1508      *
1509      * @return An array of {@link StatusBarNotification}.
1510      */
getActiveNotifications()1511     public StatusBarNotification[] getActiveNotifications() {
1512         final INotificationManager service = getService();
1513         final String pkg = mContext.getPackageName();
1514         try {
1515             final ParceledListSlice<StatusBarNotification> parceledList
1516                     = service.getAppActiveNotifications(pkg, mContext.getUserId());
1517             final List<StatusBarNotification> list = parceledList.getList();
1518             return list.toArray(new StatusBarNotification[list.size()]);
1519         } catch (RemoteException e) {
1520             throw e.rethrowFromSystemServer();
1521         }
1522     }
1523 
1524     /**
1525      * Gets the current notification interruption filter.
1526      * <p>
1527      * The interruption filter defines which notifications are allowed to
1528      * interrupt the user (e.g. via sound &amp; vibration) and is applied
1529      * globally.
1530      */
getCurrentInterruptionFilter()1531     public final @InterruptionFilter int getCurrentInterruptionFilter() {
1532         final INotificationManager service = getService();
1533         try {
1534             return zenModeToInterruptionFilter(service.getZenMode());
1535         } catch (RemoteException e) {
1536             throw e.rethrowFromSystemServer();
1537         }
1538     }
1539 
1540     /**
1541      * Sets the current notification interruption filter.
1542      * <p>
1543      * The interruption filter defines which notifications are allowed to
1544      * interrupt the user (e.g. via sound &amp; vibration) and is applied
1545      * globally.
1546      * <p>
1547      * Only available if policy access is granted to this package. See
1548      * {@link #isNotificationPolicyAccessGranted}.
1549      */
setInterruptionFilter(@nterruptionFilter int interruptionFilter)1550     public final void setInterruptionFilter(@InterruptionFilter int interruptionFilter) {
1551         final INotificationManager service = getService();
1552         try {
1553             service.setInterruptionFilter(mContext.getOpPackageName(), interruptionFilter);
1554         } catch (RemoteException e) {
1555             throw e.rethrowFromSystemServer();
1556         }
1557     }
1558 
1559     /** @hide */
zenModeToInterruptionFilter(int zen)1560     public static int zenModeToInterruptionFilter(int zen) {
1561         switch (zen) {
1562             case Global.ZEN_MODE_OFF: return INTERRUPTION_FILTER_ALL;
1563             case Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS: return INTERRUPTION_FILTER_PRIORITY;
1564             case Global.ZEN_MODE_ALARMS: return INTERRUPTION_FILTER_ALARMS;
1565             case Global.ZEN_MODE_NO_INTERRUPTIONS: return INTERRUPTION_FILTER_NONE;
1566             default: return INTERRUPTION_FILTER_UNKNOWN;
1567         }
1568     }
1569 
1570     /** @hide */
zenModeFromInterruptionFilter(int interruptionFilter, int defValue)1571     public static int zenModeFromInterruptionFilter(int interruptionFilter, int defValue) {
1572         switch (interruptionFilter) {
1573             case INTERRUPTION_FILTER_ALL: return Global.ZEN_MODE_OFF;
1574             case INTERRUPTION_FILTER_PRIORITY: return Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS;
1575             case INTERRUPTION_FILTER_ALARMS: return Global.ZEN_MODE_ALARMS;
1576             case INTERRUPTION_FILTER_NONE:  return Global.ZEN_MODE_NO_INTERRUPTIONS;
1577             default: return defValue;
1578         }
1579     }
1580 
1581 }
1582