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