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