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