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