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