OSDN Git Service

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