• 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.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.pm.ParceledListSlice;
28 import android.graphics.drawable.Icon;
29 import android.net.Uri;
30 import android.os.Build;
31 import android.os.Bundle;
32 import android.os.Handler;
33 import android.os.IBinder;
34 import android.os.Parcel;
35 import android.os.Parcelable;
36 import android.os.RemoteException;
37 import android.os.ServiceManager;
38 import android.os.StrictMode;
39 import android.os.UserHandle;
40 import android.provider.Settings.Global;
41 import android.service.notification.StatusBarNotification;
42 import android.service.notification.ZenModeConfig;
43 import android.util.Log;
44 
45 import java.lang.annotation.Retention;
46 import java.lang.annotation.RetentionPolicy;
47 import java.util.Arrays;
48 import java.util.HashMap;
49 import java.util.List;
50 import java.util.Map;
51 import java.util.Objects;
52 
53 /**
54  * Class to notify the user of events that happen.  This is how you tell
55  * the user that something has happened in the background. {@more}
56  *
57  * Notifications can take different forms:
58  * <ul>
59  *      <li>A persistent icon that goes in the status bar and is accessible
60  *          through the launcher, (when the user selects it, a designated Intent
61  *          can be launched),</li>
62  *      <li>Turning on or flashing LEDs on the device, or</li>
63  *      <li>Alerting the user by flashing the backlight, playing a sound,
64  *          or vibrating.</li>
65  * </ul>
66  *
67  * <p>
68  * Each of the notify methods takes an int id parameter and optionally a
69  * {@link String} tag parameter, which may be {@code null}.  These parameters
70  * are used to form a pair (tag, id), or ({@code null}, id) if tag is
71  * unspecified.  This pair identifies this notification from your app to the
72  * system, so that pair should be unique within your app.  If you call one
73  * of the notify methods with a (tag, id) pair that is currently active and
74  * a new set of notification parameters, it will be updated.  For example,
75  * if you pass a new status bar icon, the old icon in the status bar will
76  * be replaced with the new one.  This is also the same tag and id you pass
77  * to the {@link #cancel(int)} or {@link #cancel(String, int)} method to clear
78  * this notification.
79  *
80  * <div class="special reference">
81  * <h3>Developer Guides</h3>
82  * <p>For a guide to creating notifications, read the
83  * <a href="{@docRoot}guide/topics/ui/notifiers/notifications.html">Status Bar Notifications</a>
84  * developer guide.</p>
85  * </div>
86  *
87  * @see android.app.Notification
88  */
89 @SystemService(Context.NOTIFICATION_SERVICE)
90 public class NotificationManager {
91     private static String TAG = "NotificationManager";
92     private static boolean localLOGV = false;
93 
94     /**
95      * Intent that is broadcast when the state of {@link #getEffectsSuppressor()} changes.
96      * This broadcast is only sent to registered receivers.
97      *
98      * @hide
99      */
100     @SdkConstant(SdkConstant.SdkConstantType.BROADCAST_INTENT_ACTION)
101     public static final String ACTION_EFFECTS_SUPPRESSOR_CHANGED
102             = "android.os.action.ACTION_EFFECTS_SUPPRESSOR_CHANGED";
103 
104     /**
105      * Intent that is broadcast when the state of {@link #isNotificationPolicyAccessGranted()}
106      * changes.
107      *
108      * This broadcast is only sent to registered receivers, and only to the apps that have changed.
109      */
110     @SdkConstant(SdkConstant.SdkConstantType.BROADCAST_INTENT_ACTION)
111     public static final String ACTION_NOTIFICATION_POLICY_ACCESS_GRANTED_CHANGED
112             = "android.app.action.NOTIFICATION_POLICY_ACCESS_GRANTED_CHANGED";
113 
114     /**
115      * Intent that is broadcast when the state of getNotificationPolicy() changes.
116      * This broadcast is only sent to registered receivers.
117      */
118     @SdkConstant(SdkConstant.SdkConstantType.BROADCAST_INTENT_ACTION)
119     public static final String ACTION_NOTIFICATION_POLICY_CHANGED
120             = "android.app.action.NOTIFICATION_POLICY_CHANGED";
121 
122     /**
123      * Intent that is broadcast when the state of getCurrentInterruptionFilter() changes.
124      * This broadcast is only sent to registered receivers.
125      */
126     @SdkConstant(SdkConstant.SdkConstantType.BROADCAST_INTENT_ACTION)
127     public static final String ACTION_INTERRUPTION_FILTER_CHANGED
128             = "android.app.action.INTERRUPTION_FILTER_CHANGED";
129 
130     /**
131      * Intent that is broadcast when the state of getCurrentInterruptionFilter() changes.
132      * @hide
133      */
134     @SdkConstant(SdkConstant.SdkConstantType.BROADCAST_INTENT_ACTION)
135     public static final String ACTION_INTERRUPTION_FILTER_CHANGED_INTERNAL
136             = "android.app.action.INTERRUPTION_FILTER_CHANGED_INTERNAL";
137 
138     /** @hide */
139     @IntDef(prefix = { "INTERRUPTION_FILTER_" }, value = {
140             INTERRUPTION_FILTER_NONE, INTERRUPTION_FILTER_PRIORITY, INTERRUPTION_FILTER_ALARMS,
141             INTERRUPTION_FILTER_ALL, INTERRUPTION_FILTER_UNKNOWN
142     })
143     @Retention(RetentionPolicy.SOURCE)
144     public @interface InterruptionFilter {}
145 
146     /**
147      * {@link #getCurrentInterruptionFilter() Interruption filter} constant -
148      *     Normal interruption filter - no notifications are suppressed.
149      */
150     public static final int INTERRUPTION_FILTER_ALL = 1;
151 
152     /**
153      * {@link #getCurrentInterruptionFilter() Interruption filter} constant -
154      *     Priority interruption filter - all notifications are suppressed except those that match
155      *     the priority criteria. Some audio streams are muted. See
156      *     {@link Policy#priorityCallSenders}, {@link Policy#priorityCategories},
157      *     {@link Policy#priorityMessageSenders} to define or query this criteria. Users can
158      *     additionally specify packages that can bypass this interruption filter.
159      */
160     public static final int INTERRUPTION_FILTER_PRIORITY = 2;
161 
162     /**
163      * {@link #getCurrentInterruptionFilter() Interruption filter} constant -
164      *     No interruptions filter - all notifications are suppressed and all audio streams (except
165      *     those used for phone calls) and vibrations are muted.
166      */
167     public static final int INTERRUPTION_FILTER_NONE = 3;
168 
169     /**
170      * {@link #getCurrentInterruptionFilter() Interruption filter} constant -
171      *     Alarms only interruption filter - all notifications except those of category
172      *     {@link Notification#CATEGORY_ALARM} are suppressed. Some audio streams are muted.
173      */
174     public static final int INTERRUPTION_FILTER_ALARMS = 4;
175 
176     /** {@link #getCurrentInterruptionFilter() Interruption filter} constant - returned when
177      * the value is unavailable for any reason.
178      */
179     public static final int INTERRUPTION_FILTER_UNKNOWN = 0;
180 
181     /** @hide */
182     @IntDef(prefix = { "IMPORTANCE_" }, value = {
183             IMPORTANCE_UNSPECIFIED, IMPORTANCE_NONE,
184             IMPORTANCE_MIN, IMPORTANCE_LOW, IMPORTANCE_DEFAULT, IMPORTANCE_HIGH
185     })
186     @Retention(RetentionPolicy.SOURCE)
187     public @interface Importance {}
188 
189     /** Value signifying that the user has not expressed a per-app visibility override value.
190      * @hide */
191     public static final int VISIBILITY_NO_OVERRIDE = -1000;
192 
193     /**
194      * Value signifying that the user has not expressed an importance.
195      *
196      * This value is for persisting preferences, and should never be associated with
197      * an actual notification.
198      */
199     public static final int IMPORTANCE_UNSPECIFIED = -1000;
200 
201     /**
202      * A notification with no importance: does not show in the shade.
203      */
204     public static final int IMPORTANCE_NONE = 0;
205 
206     /**
207      * Min notification importance: only shows in the shade, below the fold.  This should
208      * not be used with {@link Service#startForeground(int, Notification) Service.startForeground}
209      * since a foreground service is supposed to be something the user cares about so it does
210      * not make semantic sense to mark its notification as minimum importance.  If you do this
211      * as of Android version {@link android.os.Build.VERSION_CODES#O}, the system will show
212      * a higher-priority notification about your app running in the background.
213      */
214     public static final int IMPORTANCE_MIN = 1;
215 
216     /**
217      * Low notification importance: shows everywhere, but is not intrusive.
218      */
219     public static final int IMPORTANCE_LOW = 2;
220 
221     /**
222      * Default notification importance: shows everywhere, makes noise, but does not visually
223      * intrude.
224      */
225     public static final int IMPORTANCE_DEFAULT = 3;
226 
227     /**
228      * Higher notification importance: shows everywhere, makes noise and peeks. May use full screen
229      * intents.
230      */
231     public static final int IMPORTANCE_HIGH = 4;
232 
233     /**
234      * Unused.
235      */
236     public static final int IMPORTANCE_MAX = 5;
237 
238     private static INotificationManager sService;
239 
240     /** @hide */
getService()241     static public INotificationManager getService()
242     {
243         if (sService != null) {
244             return sService;
245         }
246         IBinder b = ServiceManager.getService("notification");
247         sService = INotificationManager.Stub.asInterface(b);
248         return sService;
249     }
250 
NotificationManager(Context context, Handler handler)251     /*package*/ NotificationManager(Context context, Handler handler)
252     {
253         mContext = context;
254     }
255 
256     /** {@hide} */
from(Context context)257     public static NotificationManager from(Context context) {
258         return (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
259     }
260 
261     /**
262      * Post a notification to be shown in the status bar. If a notification with
263      * the same id has already been posted by your application and has not yet been canceled, it
264      * will be replaced by the updated information.
265      *
266      * @param id An identifier for this notification unique within your
267      *        application.
268      * @param notification A {@link Notification} object describing what to show the user. Must not
269      *        be null.
270      */
notify(int id, Notification notification)271     public void notify(int id, Notification notification)
272     {
273         notify(null, id, notification);
274     }
275 
276     /**
277      * Post a notification to be shown in the status bar. If a notification with
278      * the same tag and id has already been posted by your application and has not yet been
279      * canceled, it will be replaced by the updated information.
280      *
281      * @param tag A string identifier for this notification.  May be {@code null}.
282      * @param id An identifier for this notification.  The pair (tag, id) must be unique
283      *        within your application.
284      * @param notification A {@link Notification} object describing what to
285      *        show the user. Must not be null.
286      */
notify(String tag, int id, Notification notification)287     public void notify(String tag, int id, Notification notification)
288     {
289         notifyAsUser(tag, id, notification, new UserHandle(UserHandle.myUserId()));
290     }
291 
292     /**
293      * @hide
294      */
notifyAsUser(String tag, int id, Notification notification, UserHandle user)295     public void notifyAsUser(String tag, int id, Notification notification, UserHandle user)
296     {
297         INotificationManager service = getService();
298         String pkg = mContext.getPackageName();
299         // Fix the notification as best we can.
300         Notification.addFieldsFromContext(mContext, notification);
301         if (notification.sound != null) {
302             notification.sound = notification.sound.getCanonicalUri();
303             if (StrictMode.vmFileUriExposureEnabled()) {
304                 notification.sound.checkFileUriExposed("Notification.sound");
305             }
306         }
307         fixLegacySmallIcon(notification, pkg);
308         if (mContext.getApplicationInfo().targetSdkVersion > Build.VERSION_CODES.LOLLIPOP_MR1) {
309             if (notification.getSmallIcon() == null) {
310                 throw new IllegalArgumentException("Invalid notification (no valid small icon): "
311                         + notification);
312             }
313         }
314         if (localLOGV) Log.v(TAG, pkg + ": notify(" + id + ", " + notification + ")");
315         notification.reduceImageSizes(mContext);
316         ActivityManager am = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
317         boolean isLowRam = am.isLowRamDevice();
318         final Notification copy = Builder.maybeCloneStrippedForDelivery(notification, isLowRam);
319         try {
320             service.enqueueNotificationWithTag(pkg, mContext.getOpPackageName(), tag, id,
321                     copy, user.getIdentifier());
322         } catch (RemoteException e) {
323             throw e.rethrowFromSystemServer();
324         }
325     }
326 
fixLegacySmallIcon(Notification n, String pkg)327     private void fixLegacySmallIcon(Notification n, String pkg) {
328         if (n.getSmallIcon() == null && n.icon != 0) {
329             n.setSmallIcon(Icon.createWithResource(pkg, n.icon));
330         }
331     }
332 
333     /**
334      * Cancel a previously shown notification.  If it's transient, the view
335      * will be hidden.  If it's persistent, it will be removed from the status
336      * bar.
337      */
cancel(int id)338     public void cancel(int id)
339     {
340         cancel(null, id);
341     }
342 
343     /**
344      * Cancel a previously shown notification.  If it's transient, the view
345      * will be hidden.  If it's persistent, it will be removed from the status
346      * bar.
347      */
cancel(String tag, int id)348     public void cancel(String tag, int id)
349     {
350         cancelAsUser(tag, id, new UserHandle(UserHandle.myUserId()));
351     }
352 
353     /**
354      * @hide
355      */
cancelAsUser(String tag, int id, UserHandle user)356     public void cancelAsUser(String tag, int id, UserHandle user)
357     {
358         INotificationManager service = getService();
359         String pkg = mContext.getPackageName();
360         if (localLOGV) Log.v(TAG, pkg + ": cancel(" + id + ")");
361         try {
362             service.cancelNotificationWithTag(pkg, tag, id, user.getIdentifier());
363         } catch (RemoteException e) {
364             throw e.rethrowFromSystemServer();
365         }
366     }
367 
368     /**
369      * Cancel all previously shown notifications. See {@link #cancel} for the
370      * detailed behavior.
371      */
cancelAll()372     public void cancelAll()
373     {
374         INotificationManager service = getService();
375         String pkg = mContext.getPackageName();
376         if (localLOGV) Log.v(TAG, pkg + ": cancelAll()");
377         try {
378             service.cancelAllNotifications(pkg, UserHandle.myUserId());
379         } catch (RemoteException e) {
380             throw e.rethrowFromSystemServer();
381         }
382     }
383 
384     /**
385      * Creates a group container for {@link NotificationChannel} objects.
386      *
387      * This can be used to rename an existing group.
388      * <p>
389      *     Group information is only used for presentation, not for behavior. Groups are optional
390      *     for channels, and you can have a mix of channels that belong to groups and channels
391      *     that do not.
392      * </p>
393      * <p>
394      *     For example, if your application supports multiple accounts, and those accounts will
395      *     have similar channels, you can create a group for each account with account specific
396      *     labels instead of appending account information to each channel's label.
397      * </p>
398      *
399      * @param group The group to create
400      */
createNotificationChannelGroup(@onNull NotificationChannelGroup group)401     public void createNotificationChannelGroup(@NonNull NotificationChannelGroup group) {
402         createNotificationChannelGroups(Arrays.asList(group));
403     }
404 
405     /**
406      * Creates multiple notification channel groups.
407      *
408      * @param groups The list of groups to create
409      */
createNotificationChannelGroups(@onNull List<NotificationChannelGroup> groups)410     public void createNotificationChannelGroups(@NonNull List<NotificationChannelGroup> groups) {
411         INotificationManager service = getService();
412         try {
413             service.createNotificationChannelGroups(mContext.getPackageName(),
414                     new ParceledListSlice(groups));
415         } catch (RemoteException e) {
416             throw e.rethrowFromSystemServer();
417         }
418     }
419 
420     /**
421      * Creates a notification channel that notifications can be posted to.
422      *
423      * This can also be used to restore a deleted channel and to update an existing channel's
424      * name, description, and/or importance.
425      *
426      * <p>The name and description should only be changed if the locale changes
427      * or in response to the user renaming this channel. For example, if a user has a channel
428      * named 'John Doe' that represents messages from a 'John Doe', and 'John Doe' changes his name
429      * to 'John Smith,' the channel can be renamed to match.
430      *
431      * <p>The importance of an existing channel will only be changed if the new importance is lower
432      * than the current value and the user has not altered any settings on this channel.
433      *
434      * All other fields are ignored for channels that already exist.
435      *
436      * @param channel  the channel to create.  Note that the created channel may differ from this
437      *                 value. If the provided channel is malformed, a RemoteException will be
438      *                 thrown.
439      */
createNotificationChannel(@onNull NotificationChannel channel)440     public void createNotificationChannel(@NonNull NotificationChannel channel) {
441         createNotificationChannels(Arrays.asList(channel));
442     }
443 
444     /**
445      * Creates multiple notification channels that different notifications can be posted to. See
446      * {@link #createNotificationChannel(NotificationChannel)}.
447      *
448      * @param channels the list of channels to attempt to create.
449      */
createNotificationChannels(@onNull List<NotificationChannel> channels)450     public void createNotificationChannels(@NonNull List<NotificationChannel> channels) {
451         INotificationManager service = getService();
452         try {
453             service.createNotificationChannels(mContext.getPackageName(),
454                     new ParceledListSlice(channels));
455         } catch (RemoteException e) {
456             throw e.rethrowFromSystemServer();
457         }
458     }
459 
460     /**
461      * Returns the notification channel settings for a given channel id.
462      *
463      * The channel must belong to your package, or it will not be returned.
464      */
getNotificationChannel(String channelId)465     public NotificationChannel getNotificationChannel(String channelId) {
466         INotificationManager service = getService();
467         try {
468             return service.getNotificationChannel(mContext.getPackageName(), channelId);
469         } catch (RemoteException e) {
470             throw e.rethrowFromSystemServer();
471         }
472     }
473 
474     /**
475      * Returns all notification channels belonging to the calling package.
476      */
getNotificationChannels()477     public List<NotificationChannel> getNotificationChannels() {
478         INotificationManager service = getService();
479         try {
480             return service.getNotificationChannels(mContext.getPackageName()).getList();
481         } catch (RemoteException e) {
482             throw e.rethrowFromSystemServer();
483         }
484     }
485 
486     /**
487      * Deletes the given notification channel.
488      *
489      * <p>If you {@link #createNotificationChannel(NotificationChannel) create} a new channel with
490      * this same id, the deleted channel will be un-deleted with all of the same settings it
491      * had before it was deleted.
492      */
deleteNotificationChannel(String channelId)493     public void deleteNotificationChannel(String channelId) {
494         INotificationManager service = getService();
495         try {
496             service.deleteNotificationChannel(mContext.getPackageName(), channelId);
497         } catch (RemoteException e) {
498             throw e.rethrowFromSystemServer();
499         }
500     }
501 
502     /**
503      * Returns all notification channel groups belonging to the calling app.
504      */
getNotificationChannelGroups()505     public List<NotificationChannelGroup> getNotificationChannelGroups() {
506         INotificationManager service = getService();
507         try {
508             return service.getNotificationChannelGroups(mContext.getPackageName()).getList();
509         } catch (RemoteException e) {
510             throw e.rethrowFromSystemServer();
511         }
512     }
513 
514     /**
515      * Deletes the given notification channel group, and all notification channels that
516      * belong to it.
517      */
deleteNotificationChannelGroup(String groupId)518     public void deleteNotificationChannelGroup(String groupId) {
519         INotificationManager service = getService();
520         try {
521             service.deleteNotificationChannelGroup(mContext.getPackageName(), groupId);
522         } catch (RemoteException e) {
523             throw e.rethrowFromSystemServer();
524         }
525     }
526 
527     /**
528      * @hide
529      */
530     @TestApi
getEffectsSuppressor()531     public ComponentName getEffectsSuppressor() {
532         INotificationManager service = getService();
533         try {
534             return service.getEffectsSuppressor();
535         } catch (RemoteException e) {
536             throw e.rethrowFromSystemServer();
537         }
538     }
539 
540     /**
541      * @hide
542      */
matchesCallFilter(Bundle extras)543     public boolean matchesCallFilter(Bundle extras) {
544         INotificationManager service = getService();
545         try {
546             return service.matchesCallFilter(extras);
547         } catch (RemoteException e) {
548             throw e.rethrowFromSystemServer();
549         }
550     }
551 
552     /**
553      * @hide
554      */
isSystemConditionProviderEnabled(String path)555     public boolean isSystemConditionProviderEnabled(String path) {
556         INotificationManager service = getService();
557         try {
558             return service.isSystemConditionProviderEnabled(path);
559         } catch (RemoteException e) {
560             throw e.rethrowFromSystemServer();
561         }
562     }
563 
564     /**
565      * @hide
566      */
setZenMode(int mode, Uri conditionId, String reason)567     public void setZenMode(int mode, Uri conditionId, String reason) {
568         INotificationManager service = getService();
569         try {
570             service.setZenMode(mode, conditionId, reason);
571         } catch (RemoteException e) {
572             throw e.rethrowFromSystemServer();
573         }
574     }
575 
576     /**
577      * @hide
578      */
getZenMode()579     public int getZenMode() {
580         INotificationManager service = getService();
581         try {
582             return service.getZenMode();
583         } catch (RemoteException e) {
584             throw e.rethrowFromSystemServer();
585         }
586     }
587 
588     /**
589      * @hide
590      */
getZenModeConfig()591     public ZenModeConfig getZenModeConfig() {
592         INotificationManager service = getService();
593         try {
594             return service.getZenModeConfig();
595         } catch (RemoteException e) {
596             throw e.rethrowFromSystemServer();
597         }
598     }
599 
600     /**
601      * @hide
602      */
getRuleInstanceCount(ComponentName owner)603     public int getRuleInstanceCount(ComponentName owner) {
604         INotificationManager service = getService();
605         try {
606             return service.getRuleInstanceCount(owner);
607         } catch (RemoteException e) {
608             throw e.rethrowFromSystemServer();
609         }
610     }
611 
612     /**
613      * Returns AutomaticZenRules owned by the caller.
614      *
615      * <p>
616      * Throws a SecurityException if policy access is granted to this package.
617      * See {@link #isNotificationPolicyAccessGranted}.
618      */
getAutomaticZenRules()619     public Map<String, AutomaticZenRule> getAutomaticZenRules() {
620         INotificationManager service = getService();
621         try {
622             List<ZenModeConfig.ZenRule> rules = service.getZenRules();
623             Map<String, AutomaticZenRule> ruleMap = new HashMap<>();
624             for (ZenModeConfig.ZenRule rule : rules) {
625                 ruleMap.put(rule.id, new AutomaticZenRule(rule.name, rule.component,
626                         rule.conditionId, zenModeToInterruptionFilter(rule.zenMode), rule.enabled,
627                         rule.creationTime));
628             }
629             return ruleMap;
630         } catch (RemoteException e) {
631             throw e.rethrowFromSystemServer();
632         }
633     }
634 
635     /**
636      * Returns the AutomaticZenRule with the given id, if it exists and the caller has access.
637      *
638      * <p>
639      * Throws a SecurityException if policy access is granted to this package.
640      * See {@link #isNotificationPolicyAccessGranted}.
641      *
642      * <p>
643      * Returns null if there are no zen rules that match the given id, or if the calling package
644      * doesn't own the matching rule. See {@link AutomaticZenRule#getOwner}.
645      */
getAutomaticZenRule(String id)646     public AutomaticZenRule getAutomaticZenRule(String id) {
647         INotificationManager service = getService();
648         try {
649             return service.getAutomaticZenRule(id);
650         } catch (RemoteException e) {
651             throw e.rethrowFromSystemServer();
652         }
653     }
654 
655     /**
656      * Creates the given zen rule.
657      *
658      * <p>
659      * Throws a SecurityException if policy access is granted to this package.
660      * See {@link #isNotificationPolicyAccessGranted}.
661      *
662      * @param automaticZenRule the rule to create.
663      * @return The id of the newly created rule; null if the rule could not be created.
664      */
addAutomaticZenRule(AutomaticZenRule automaticZenRule)665     public String addAutomaticZenRule(AutomaticZenRule automaticZenRule) {
666         INotificationManager service = getService();
667         try {
668             return service.addAutomaticZenRule(automaticZenRule);
669         } catch (RemoteException e) {
670             throw e.rethrowFromSystemServer();
671         }
672     }
673 
674     /**
675      * Updates the given zen rule.
676      *
677      * <p>
678      * Throws a SecurityException if policy access is granted to this package.
679      * See {@link #isNotificationPolicyAccessGranted}.
680      *
681      * <p>
682      * Callers can only update rules that they own. See {@link AutomaticZenRule#getOwner}.
683      * @param id The id of the rule to update
684      * @param automaticZenRule the rule to update.
685      * @return Whether the rule was successfully updated.
686      */
updateAutomaticZenRule(String id, AutomaticZenRule automaticZenRule)687     public boolean updateAutomaticZenRule(String id, AutomaticZenRule automaticZenRule) {
688         INotificationManager service = getService();
689         try {
690             return service.updateAutomaticZenRule(id, automaticZenRule);
691         } catch (RemoteException e) {
692             throw e.rethrowFromSystemServer();
693         }
694     }
695 
696     /**
697      * Deletes the automatic zen rule with the given id.
698      *
699      * <p>
700      * Throws a SecurityException if policy access is granted to this package.
701      * See {@link #isNotificationPolicyAccessGranted}.
702      *
703      * <p>
704      * Callers can only delete rules that they own. See {@link AutomaticZenRule#getOwner}.
705      * @param id the id of the rule to delete.
706      * @return Whether the rule was successfully deleted.
707      */
removeAutomaticZenRule(String id)708     public boolean removeAutomaticZenRule(String id) {
709         INotificationManager service = getService();
710         try {
711             return service.removeAutomaticZenRule(id);
712         } catch (RemoteException e) {
713             throw e.rethrowFromSystemServer();
714         }
715     }
716 
717     /**
718      * Deletes all automatic zen rules owned by the given package.
719      *
720      * @hide
721      */
removeAutomaticZenRules(String packageName)722     public boolean removeAutomaticZenRules(String packageName) {
723         INotificationManager service = getService();
724         try {
725             return service.removeAutomaticZenRules(packageName);
726         } catch (RemoteException e) {
727             throw e.rethrowFromSystemServer();
728         }
729     }
730 
731     /**
732      * Returns the user specified importance for notifications from the calling
733      * package.
734      */
getImportance()735     public @Importance int getImportance() {
736         INotificationManager service = getService();
737         try {
738             return service.getPackageImportance(mContext.getPackageName());
739         } catch (RemoteException e) {
740             throw e.rethrowFromSystemServer();
741         }
742     }
743 
744     /**
745      * Returns whether notifications from the calling package are blocked.
746      */
areNotificationsEnabled()747     public boolean areNotificationsEnabled() {
748         INotificationManager service = getService();
749         try {
750             return service.areNotificationsEnabled(mContext.getPackageName());
751         } catch (RemoteException e) {
752             throw e.rethrowFromSystemServer();
753         }
754     }
755 
756     /**
757      * Checks the ability to read/modify notification do not disturb policy for the calling package.
758      *
759      * <p>
760      * Returns true if the calling package can read/modify notification policy.
761      *
762      * <p>
763      * Apps can request policy access by sending the user to the activity that matches the system
764      * intent action {@link android.provider.Settings#ACTION_NOTIFICATION_POLICY_ACCESS_SETTINGS}.
765      *
766      * <p>
767      * Use {@link #ACTION_NOTIFICATION_POLICY_ACCESS_GRANTED_CHANGED} to listen for
768      * user grant or denial of this access.
769      */
isNotificationPolicyAccessGranted()770     public boolean isNotificationPolicyAccessGranted() {
771         INotificationManager service = getService();
772         try {
773             return service.isNotificationPolicyAccessGranted(mContext.getOpPackageName());
774         } catch (RemoteException e) {
775             throw e.rethrowFromSystemServer();
776         }
777     }
778 
779     /**
780      * Checks whether the user has approved a given
781      * {@link android.service.notification.NotificationListenerService}.
782      *
783      * <p>
784      * The listener service must belong to the calling app.
785      *
786      * <p>
787      * Apps can request notification listener access by sending the user to the activity that
788      * matches the system intent action
789      * {@link android.provider.Settings#ACTION_NOTIFICATION_LISTENER_SETTINGS}.
790      */
isNotificationListenerAccessGranted(ComponentName listener)791     public boolean isNotificationListenerAccessGranted(ComponentName listener) {
792         INotificationManager service = getService();
793         try {
794             return service.isNotificationListenerAccessGranted(listener);
795         } catch (RemoteException e) {
796             throw e.rethrowFromSystemServer();
797         }
798     }
799 
800     /**
801      * @hide
802      */
isNotificationAssistantAccessGranted(ComponentName assistant)803     public boolean isNotificationAssistantAccessGranted(ComponentName assistant) {
804         INotificationManager service = getService();
805         try {
806             return service.isNotificationAssistantAccessGranted(assistant);
807         } catch (RemoteException e) {
808             throw e.rethrowFromSystemServer();
809         }
810     }
811 
812     /** @hide */
isNotificationPolicyAccessGrantedForPackage(String pkg)813     public boolean isNotificationPolicyAccessGrantedForPackage(String pkg) {
814         INotificationManager service = getService();
815         try {
816             return service.isNotificationPolicyAccessGrantedForPackage(pkg);
817         } catch (RemoteException e) {
818             throw e.rethrowFromSystemServer();
819         }
820     }
821 
822     /**
823      * @hide
824      */
getEnabledNotificationListenerPackages()825     public List<String> getEnabledNotificationListenerPackages() {
826         INotificationManager service = getService();
827         try {
828             return service.getEnabledNotificationListenerPackages();
829         } catch (RemoteException e) {
830             throw e.rethrowFromSystemServer();
831         }
832     }
833 
834     /**
835      * Gets the current notification policy.
836      *
837      * <p>
838      * Only available if policy access is granted to this package.
839      * See {@link #isNotificationPolicyAccessGranted}.
840      */
getNotificationPolicy()841     public Policy getNotificationPolicy() {
842         INotificationManager service = getService();
843         try {
844             return service.getNotificationPolicy(mContext.getOpPackageName());
845         } catch (RemoteException e) {
846             throw e.rethrowFromSystemServer();
847         }
848     }
849 
850     /**
851      * Sets the current notification policy.
852      *
853      * <p>
854      * Only available if policy access is granted to this package.
855      * See {@link #isNotificationPolicyAccessGranted}.
856      *
857      * @param policy The new desired policy.
858      */
setNotificationPolicy(@onNull Policy policy)859     public void setNotificationPolicy(@NonNull Policy policy) {
860         checkRequired("policy", policy);
861         INotificationManager service = getService();
862         try {
863             service.setNotificationPolicy(mContext.getOpPackageName(), policy);
864         } catch (RemoteException e) {
865             throw e.rethrowFromSystemServer();
866         }
867     }
868 
869     /** @hide */
setNotificationPolicyAccessGranted(String pkg, boolean granted)870     public void setNotificationPolicyAccessGranted(String pkg, boolean granted) {
871         INotificationManager service = getService();
872         try {
873             service.setNotificationPolicyAccessGranted(pkg, granted);
874         } catch (RemoteException e) {
875             throw e.rethrowFromSystemServer();
876         }
877     }
878 
879     /** @hide */
setNotificationListenerAccessGranted(ComponentName listener, boolean granted)880     public void setNotificationListenerAccessGranted(ComponentName listener, boolean granted) {
881         INotificationManager service = getService();
882         try {
883             service.setNotificationListenerAccessGranted(listener, granted);
884         } catch (RemoteException e) {
885             throw e.rethrowFromSystemServer();
886         }
887     }
888 
889     /** @hide */
setNotificationListenerAccessGrantedForUser(ComponentName listener, int userId, boolean granted)890     public void setNotificationListenerAccessGrantedForUser(ComponentName listener, int userId,
891             boolean granted) {
892         INotificationManager service = getService();
893         try {
894             service.setNotificationListenerAccessGrantedForUser(listener, userId, granted);
895         } catch (RemoteException e) {
896             throw e.rethrowFromSystemServer();
897         }
898     }
899 
900     /** @hide */
getEnabledNotificationListeners(int userId)901     public List<ComponentName> getEnabledNotificationListeners(int userId) {
902         INotificationManager service = getService();
903         try {
904             return service.getEnabledNotificationListeners(userId);
905         } catch (RemoteException e) {
906             throw e.rethrowFromSystemServer();
907         }
908     }
909 
910     private Context mContext;
911 
checkRequired(String name, Object value)912     private static void checkRequired(String name, Object value) {
913         if (value == null) {
914             throw new IllegalArgumentException(name + " is required");
915         }
916     }
917 
918     /**
919      * Notification policy configuration.  Represents user-preferences for notification
920      * filtering.
921      */
922     public static class Policy implements android.os.Parcelable {
923         /** Reminder notifications are prioritized. */
924         public static final int PRIORITY_CATEGORY_REMINDERS = 1 << 0;
925         /** Event notifications are prioritized. */
926         public static final int PRIORITY_CATEGORY_EVENTS = 1 << 1;
927         /** Message notifications are prioritized. */
928         public static final int PRIORITY_CATEGORY_MESSAGES = 1 << 2;
929         /** Calls are prioritized. */
930         public static final int PRIORITY_CATEGORY_CALLS = 1 << 3;
931         /** Calls from repeat callers are prioritized. */
932         public static final int PRIORITY_CATEGORY_REPEAT_CALLERS = 1 << 4;
933 
934         private static final int[] ALL_PRIORITY_CATEGORIES = {
935             PRIORITY_CATEGORY_REMINDERS,
936             PRIORITY_CATEGORY_EVENTS,
937             PRIORITY_CATEGORY_MESSAGES,
938             PRIORITY_CATEGORY_CALLS,
939             PRIORITY_CATEGORY_REPEAT_CALLERS,
940         };
941 
942         /** Any sender is prioritized. */
943         public static final int PRIORITY_SENDERS_ANY = 0;
944         /** Saved contacts are prioritized. */
945         public static final int PRIORITY_SENDERS_CONTACTS = 1;
946         /** Only starred contacts are prioritized. */
947         public static final int PRIORITY_SENDERS_STARRED = 2;
948 
949         /** Notification categories to prioritize. Bitmask of PRIORITY_CATEGORY_* constants. */
950         public final int priorityCategories;
951 
952         /** Notification senders to prioritize for calls. One of:
953          * PRIORITY_SENDERS_ANY, PRIORITY_SENDERS_CONTACTS, PRIORITY_SENDERS_STARRED */
954         public final int priorityCallSenders;
955 
956         /** Notification senders to prioritize for messages. One of:
957          * PRIORITY_SENDERS_ANY, PRIORITY_SENDERS_CONTACTS, PRIORITY_SENDERS_STARRED */
958         public final int priorityMessageSenders;
959 
960         /**
961          * @hide
962          */
963         public static final int SUPPRESSED_EFFECTS_UNSET = -1;
964         /**
965          * Whether notifications suppressed by DND should not interrupt visually (e.g. with
966          * notification lights or by turning the screen on) when the screen is off.
967          */
968         public static final int SUPPRESSED_EFFECT_SCREEN_OFF = 1 << 0;
969         /**
970          * Whether notifications suppressed by DND should not interrupt visually when the screen
971          * is on (e.g. by peeking onto the screen).
972          */
973         public static final int SUPPRESSED_EFFECT_SCREEN_ON = 1 << 1;
974 
975         private static final int[] ALL_SUPPRESSED_EFFECTS = {
976                 SUPPRESSED_EFFECT_SCREEN_OFF,
977                 SUPPRESSED_EFFECT_SCREEN_ON,
978         };
979 
980         /**
981          * Visual effects to suppress for a notification that is filtered by Do Not Disturb mode.
982          * Bitmask of SUPPRESSED_EFFECT_* constants.
983          */
984         public final int suppressedVisualEffects;
985 
986         /**
987          * Constructs a policy for Do Not Disturb priority mode behavior.
988          *
989          * @param priorityCategories bitmask of categories of notifications that can bypass DND.
990          * @param priorityCallSenders which callers can bypass DND.
991          * @param priorityMessageSenders which message senders can bypass DND.
992          */
Policy(int priorityCategories, int priorityCallSenders, int priorityMessageSenders)993         public Policy(int priorityCategories, int priorityCallSenders, int priorityMessageSenders) {
994             this(priorityCategories, priorityCallSenders, priorityMessageSenders,
995                     SUPPRESSED_EFFECTS_UNSET);
996         }
997 
998         /**
999          * Constructs a policy for Do Not Disturb priority mode behavior.
1000          *
1001          * @param priorityCategories bitmask of categories of notifications that can bypass DND.
1002          * @param priorityCallSenders which callers can bypass DND.
1003          * @param priorityMessageSenders which message senders can bypass DND.
1004          * @param suppressedVisualEffects which visual interruptions should be suppressed from
1005          *                                notifications that are filtered by DND.
1006          */
Policy(int priorityCategories, int priorityCallSenders, int priorityMessageSenders, int suppressedVisualEffects)1007         public Policy(int priorityCategories, int priorityCallSenders, int priorityMessageSenders,
1008                 int suppressedVisualEffects) {
1009             this.priorityCategories = priorityCategories;
1010             this.priorityCallSenders = priorityCallSenders;
1011             this.priorityMessageSenders = priorityMessageSenders;
1012             this.suppressedVisualEffects = suppressedVisualEffects;
1013         }
1014 
1015         /** @hide */
Policy(Parcel source)1016         public Policy(Parcel source) {
1017             this(source.readInt(), source.readInt(), source.readInt(), source.readInt());
1018         }
1019 
1020         @Override
writeToParcel(Parcel dest, int flags)1021         public void writeToParcel(Parcel dest, int flags) {
1022             dest.writeInt(priorityCategories);
1023             dest.writeInt(priorityCallSenders);
1024             dest.writeInt(priorityMessageSenders);
1025             dest.writeInt(suppressedVisualEffects);
1026         }
1027 
1028         @Override
describeContents()1029         public int describeContents() {
1030             return 0;
1031         }
1032 
1033         @Override
hashCode()1034         public int hashCode() {
1035             return Objects.hash(priorityCategories, priorityCallSenders, priorityMessageSenders,
1036                     suppressedVisualEffects);
1037         }
1038 
1039         @Override
equals(Object o)1040         public boolean equals(Object o) {
1041             if (!(o instanceof Policy)) return false;
1042             if (o == this) return true;
1043             final Policy other = (Policy) o;
1044             return other.priorityCategories == priorityCategories
1045                     && other.priorityCallSenders == priorityCallSenders
1046                     && other.priorityMessageSenders == priorityMessageSenders
1047                     && other.suppressedVisualEffects == suppressedVisualEffects;
1048         }
1049 
1050         @Override
toString()1051         public String toString() {
1052             return "NotificationManager.Policy["
1053                     + "priorityCategories=" + priorityCategoriesToString(priorityCategories)
1054                     + ",priorityCallSenders=" + prioritySendersToString(priorityCallSenders)
1055                     + ",priorityMessageSenders=" + prioritySendersToString(priorityMessageSenders)
1056                     + ",suppressedVisualEffects="
1057                     + suppressedEffectsToString(suppressedVisualEffects)
1058                     + "]";
1059         }
1060 
suppressedEffectsToString(int effects)1061         public static String suppressedEffectsToString(int effects) {
1062             if (effects <= 0) return "";
1063             final StringBuilder sb = new StringBuilder();
1064             for (int i = 0; i < ALL_SUPPRESSED_EFFECTS.length; i++) {
1065                 final int effect = ALL_SUPPRESSED_EFFECTS[i];
1066                 if ((effects & effect) != 0) {
1067                     if (sb.length() > 0) sb.append(',');
1068                     sb.append(effectToString(effect));
1069                 }
1070                 effects &= ~effect;
1071             }
1072             if (effects != 0) {
1073                 if (sb.length() > 0) sb.append(',');
1074                 sb.append("UNKNOWN_").append(effects);
1075             }
1076             return sb.toString();
1077         }
1078 
priorityCategoriesToString(int priorityCategories)1079         public static String priorityCategoriesToString(int priorityCategories) {
1080             if (priorityCategories == 0) return "";
1081             final StringBuilder sb = new StringBuilder();
1082             for (int i = 0; i < ALL_PRIORITY_CATEGORIES.length; i++) {
1083                 final int priorityCategory = ALL_PRIORITY_CATEGORIES[i];
1084                 if ((priorityCategories & priorityCategory) != 0) {
1085                     if (sb.length() > 0) sb.append(',');
1086                     sb.append(priorityCategoryToString(priorityCategory));
1087                 }
1088                 priorityCategories &= ~priorityCategory;
1089             }
1090             if (priorityCategories != 0) {
1091                 if (sb.length() > 0) sb.append(',');
1092                 sb.append("PRIORITY_CATEGORY_UNKNOWN_").append(priorityCategories);
1093             }
1094             return sb.toString();
1095         }
1096 
effectToString(int effect)1097         private static String effectToString(int effect) {
1098             switch (effect) {
1099                 case SUPPRESSED_EFFECT_SCREEN_OFF: return "SUPPRESSED_EFFECT_SCREEN_OFF";
1100                 case SUPPRESSED_EFFECT_SCREEN_ON: return "SUPPRESSED_EFFECT_SCREEN_ON";
1101                 case SUPPRESSED_EFFECTS_UNSET: return "SUPPRESSED_EFFECTS_UNSET";
1102                 default: return "UNKNOWN_" + effect;
1103             }
1104         }
1105 
priorityCategoryToString(int priorityCategory)1106         private static String priorityCategoryToString(int priorityCategory) {
1107             switch (priorityCategory) {
1108                 case PRIORITY_CATEGORY_REMINDERS: return "PRIORITY_CATEGORY_REMINDERS";
1109                 case PRIORITY_CATEGORY_EVENTS: return "PRIORITY_CATEGORY_EVENTS";
1110                 case PRIORITY_CATEGORY_MESSAGES: return "PRIORITY_CATEGORY_MESSAGES";
1111                 case PRIORITY_CATEGORY_CALLS: return "PRIORITY_CATEGORY_CALLS";
1112                 case PRIORITY_CATEGORY_REPEAT_CALLERS: return "PRIORITY_CATEGORY_REPEAT_CALLERS";
1113                 default: return "PRIORITY_CATEGORY_UNKNOWN_" + priorityCategory;
1114             }
1115         }
1116 
prioritySendersToString(int prioritySenders)1117         public static String prioritySendersToString(int prioritySenders) {
1118             switch (prioritySenders) {
1119                 case PRIORITY_SENDERS_ANY: return "PRIORITY_SENDERS_ANY";
1120                 case PRIORITY_SENDERS_CONTACTS: return "PRIORITY_SENDERS_CONTACTS";
1121                 case PRIORITY_SENDERS_STARRED: return "PRIORITY_SENDERS_STARRED";
1122                 default: return "PRIORITY_SENDERS_UNKNOWN_" + prioritySenders;
1123             }
1124         }
1125 
1126         public static final Parcelable.Creator<Policy> CREATOR = new Parcelable.Creator<Policy>() {
1127             @Override
1128             public Policy createFromParcel(Parcel in) {
1129                 return new Policy(in);
1130             }
1131 
1132             @Override
1133             public Policy[] newArray(int size) {
1134                 return new Policy[size];
1135             }
1136         };
1137     }
1138 
1139     /**
1140      * Recover a list of active notifications: ones that have been posted by the calling app that
1141      * have not yet been dismissed by the user or {@link #cancel(String, int)}ed by the app.
1142      *
1143      * Each notification is embedded in a {@link StatusBarNotification} object, including the
1144      * original <code>tag</code> and <code>id</code> supplied to
1145      * {@link #notify(String, int, Notification) notify()}
1146      * (via {@link StatusBarNotification#getTag() getTag()} and
1147      * {@link StatusBarNotification#getId() getId()}) as well as a copy of the original
1148      * {@link Notification} object (via {@link StatusBarNotification#getNotification()}).
1149      *
1150      * @return An array of {@link StatusBarNotification}.
1151      */
getActiveNotifications()1152     public StatusBarNotification[] getActiveNotifications() {
1153         final INotificationManager service = getService();
1154         final String pkg = mContext.getPackageName();
1155         try {
1156             final ParceledListSlice<StatusBarNotification> parceledList
1157                     = service.getAppActiveNotifications(pkg, UserHandle.myUserId());
1158             final List<StatusBarNotification> list = parceledList.getList();
1159             return list.toArray(new StatusBarNotification[list.size()]);
1160         } catch (RemoteException e) {
1161             throw e.rethrowFromSystemServer();
1162         }
1163     }
1164 
1165     /**
1166      * Gets the current notification interruption filter.
1167      * <p>
1168      * The interruption filter defines which notifications are allowed to
1169      * interrupt the user (e.g. via sound &amp; vibration) and is applied
1170      * globally.
1171      */
getCurrentInterruptionFilter()1172     public final @InterruptionFilter int getCurrentInterruptionFilter() {
1173         final INotificationManager service = getService();
1174         try {
1175             return zenModeToInterruptionFilter(service.getZenMode());
1176         } catch (RemoteException e) {
1177             throw e.rethrowFromSystemServer();
1178         }
1179     }
1180 
1181     /**
1182      * Sets the current notification interruption filter.
1183      * <p>
1184      * The interruption filter defines which notifications are allowed to
1185      * interrupt the user (e.g. via sound &amp; vibration) and is applied
1186      * globally.
1187      * <p>
1188      * Only available if policy access is granted to this package. See
1189      * {@link #isNotificationPolicyAccessGranted}.
1190      */
setInterruptionFilter(@nterruptionFilter int interruptionFilter)1191     public final void setInterruptionFilter(@InterruptionFilter int interruptionFilter) {
1192         final INotificationManager service = getService();
1193         try {
1194             service.setInterruptionFilter(mContext.getOpPackageName(), interruptionFilter);
1195         } catch (RemoteException e) {
1196             throw e.rethrowFromSystemServer();
1197         }
1198     }
1199 
1200     /** @hide */
zenModeToInterruptionFilter(int zen)1201     public static int zenModeToInterruptionFilter(int zen) {
1202         switch (zen) {
1203             case Global.ZEN_MODE_OFF: return INTERRUPTION_FILTER_ALL;
1204             case Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS: return INTERRUPTION_FILTER_PRIORITY;
1205             case Global.ZEN_MODE_ALARMS: return INTERRUPTION_FILTER_ALARMS;
1206             case Global.ZEN_MODE_NO_INTERRUPTIONS: return INTERRUPTION_FILTER_NONE;
1207             default: return INTERRUPTION_FILTER_UNKNOWN;
1208         }
1209     }
1210 
1211     /** @hide */
zenModeFromInterruptionFilter(int interruptionFilter, int defValue)1212     public static int zenModeFromInterruptionFilter(int interruptionFilter, int defValue) {
1213         switch (interruptionFilter) {
1214             case INTERRUPTION_FILTER_ALL: return Global.ZEN_MODE_OFF;
1215             case INTERRUPTION_FILTER_PRIORITY: return Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS;
1216             case INTERRUPTION_FILTER_ALARMS: return Global.ZEN_MODE_ALARMS;
1217             case INTERRUPTION_FILTER_NONE:  return Global.ZEN_MODE_NO_INTERRUPTIONS;
1218             default: return defValue;
1219         }
1220     }
1221 
1222 }
1223