2 * Copyright (C) 2007 The Android Open Source Project
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
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;
45 import java.lang.annotation.Retention;
46 import java.lang.annotation.RetentionPolicy;
47 import java.util.HashMap;
48 import java.util.List;
50 import java.util.Objects;
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}
56 * Notifications can take different forms:
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,
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
80 * You do not instantiate this class directly; instead, retrieve it through
81 * {@link android.content.Context#getSystemService}.
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>
90 * @see android.app.Notification
91 * @see android.content.Context#getSystemService
93 public class NotificationManager
95 private static String TAG = "NotificationManager";
96 private static boolean localLOGV = false;
99 * Intent that is broadcast when the state of {@link #getEffectsSuppressor()} changes.
100 * This broadcast is only sent to registered receivers.
104 @SdkConstant(SdkConstant.SdkConstantType.BROADCAST_INTENT_ACTION)
105 public static final String ACTION_EFFECTS_SUPPRESSOR_CHANGED
106 = "android.os.action.ACTION_EFFECTS_SUPPRESSOR_CHANGED";
109 * Intent that is broadcast when the state of {@link #isNotificationPolicyAccessGranted()}
112 * This broadcast is only sent to registered receivers, and only to the apps that have changed.
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";
119 * Intent that is broadcast when the state of getNotificationPolicy() changes.
120 * This broadcast is only sent to registered receivers.
122 @SdkConstant(SdkConstant.SdkConstantType.BROADCAST_INTENT_ACTION)
123 public static final String ACTION_NOTIFICATION_POLICY_CHANGED
124 = "android.app.action.NOTIFICATION_POLICY_CHANGED";
127 * Intent that is broadcast when the state of getCurrentInterruptionFilter() changes.
128 * This broadcast is only sent to registered receivers.
130 @SdkConstant(SdkConstant.SdkConstantType.BROADCAST_INTENT_ACTION)
131 public static final String ACTION_INTERRUPTION_FILTER_CHANGED
132 = "android.app.action.INTERRUPTION_FILTER_CHANGED";
135 * Intent that is broadcast when the state of getCurrentInterruptionFilter() changes.
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";
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 {}
149 * {@link #getCurrentInterruptionFilter() Interruption filter} constant -
150 * Normal interruption filter - no notifications are suppressed.
152 public static final int INTERRUPTION_FILTER_ALL = 1;
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.
162 public static final int INTERRUPTION_FILTER_PRIORITY = 2;
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.
169 public static final int INTERRUPTION_FILTER_NONE = 3;
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.
176 public static final int INTERRUPTION_FILTER_ALARMS = 4;
178 /** {@link #getCurrentInterruptionFilter() Interruption filter} constant - returned when
179 * the value is unavailable for any reason.
181 public static final int INTERRUPTION_FILTER_UNKNOWN = 0;
184 @IntDef({VISIBILITY_NO_OVERRIDE, IMPORTANCE_UNSPECIFIED, IMPORTANCE_NONE,
185 IMPORTANCE_MIN, IMPORTANCE_LOW, IMPORTANCE_DEFAULT, IMPORTANCE_HIGH,
187 @Retention(RetentionPolicy.SOURCE)
188 public @interface Importance {}
190 /** Value signifying that the user has not expressed a per-app visibility override value.
192 public static final int VISIBILITY_NO_OVERRIDE = -1000;
194 * Value signifying that the user has not expressed an importance.
196 * This value is for persisting preferences, and should never be associated with
197 * an actual notification.
199 public static final int IMPORTANCE_UNSPECIFIED = -1000;
202 * A notification with no importance: shows nowhere, is blocked.
204 public static final int IMPORTANCE_NONE = 0;
207 * Min notification importance: only shows in the shade, below the fold.
209 public static final int IMPORTANCE_MIN = 1;
212 * Low notification importance: shows everywhere, but is not intrusive.
214 public static final int IMPORTANCE_LOW = 2;
217 * Default notification importance: shows everywhere, allowed to makes noise,
218 * but does not visually intrude.
220 public static final int IMPORTANCE_DEFAULT = 3;
223 * Higher notification importance: shows everywhere, allowed to makes noise and peek.
225 public static final int IMPORTANCE_HIGH = 4;
228 * Highest notification importance: shows everywhere, allowed to makes noise, peek, and
229 * use full screen intents.
231 public static final int IMPORTANCE_MAX = 5;
233 private static INotificationManager sService;
236 static public INotificationManager getService()
238 if (sService != null) {
241 IBinder b = ServiceManager.getService("notification");
242 sService = INotificationManager.Stub.asInterface(b);
246 /*package*/ NotificationManager(Context context, Handler handler)
252 public static NotificationManager from(Context context) {
253 return (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
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.
261 * @param id An identifier for this notification unique within your
263 * @param notification A {@link Notification} object describing what to show the user. Must not
266 public void notify(int id, Notification notification)
268 notify(null, id, notification);
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.
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.
282 public void notify(String tag, int id, Notification notification)
284 notifyAsUser(tag, id, notification, new UserHandle(UserHandle.myUserId()));
290 public void notifyAsUser(String tag, int id, Notification notification, UserHandle user)
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");
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): "
310 if (localLOGV) Log.v(TAG, pkg + ": notify(" + id + ", " + notification + ")");
311 final Notification copy = Builder.maybeCloneStrippedForDelivery(notification);
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]);
318 } catch (RemoteException e) {
319 throw e.rethrowFromSystemServer();
323 private void fixLegacySmallIcon(Notification n, String pkg) {
324 if (n.getSmallIcon() == null && n.icon != 0) {
325 n.setSmallIcon(Icon.createWithResource(pkg, n.icon));
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
334 public void cancel(int id)
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
344 public void cancel(String tag, int id)
346 cancelAsUser(tag, id, new UserHandle(UserHandle.myUserId()));
352 public void cancelAsUser(String tag, int id, UserHandle user)
354 INotificationManager service = getService();
355 String pkg = mContext.getPackageName();
356 if (localLOGV) Log.v(TAG, pkg + ": cancel(" + id + ")");
358 service.cancelNotificationWithTag(pkg, tag, id, user.getIdentifier());
359 } catch (RemoteException e) {
360 throw e.rethrowFromSystemServer();
365 * Cancel all previously shown notifications. See {@link #cancel} for the
368 public void cancelAll()
370 INotificationManager service = getService();
371 String pkg = mContext.getPackageName();
372 if (localLOGV) Log.v(TAG, pkg + ": cancelAll()");
374 service.cancelAllNotifications(pkg, UserHandle.myUserId());
375 } catch (RemoteException e) {
376 throw e.rethrowFromSystemServer();
383 public ComponentName getEffectsSuppressor() {
384 INotificationManager service = getService();
386 return service.getEffectsSuppressor();
387 } catch (RemoteException e) {
388 throw e.rethrowFromSystemServer();
395 public boolean matchesCallFilter(Bundle extras) {
396 INotificationManager service = getService();
398 return service.matchesCallFilter(extras);
399 } catch (RemoteException e) {
400 throw e.rethrowFromSystemServer();
407 public boolean isSystemConditionProviderEnabled(String path) {
408 INotificationManager service = getService();
410 return service.isSystemConditionProviderEnabled(path);
411 } catch (RemoteException e) {
412 throw e.rethrowFromSystemServer();
419 public void setZenMode(int mode, Uri conditionId, String reason) {
420 INotificationManager service = getService();
422 service.setZenMode(mode, conditionId, reason);
423 } catch (RemoteException e) {
424 throw e.rethrowFromSystemServer();
431 public int getZenMode() {
432 INotificationManager service = getService();
434 return service.getZenMode();
435 } catch (RemoteException e) {
436 throw e.rethrowFromSystemServer();
443 public ZenModeConfig getZenModeConfig() {
444 INotificationManager service = getService();
446 return service.getZenModeConfig();
447 } catch (RemoteException e) {
448 throw e.rethrowFromSystemServer();
455 public int getRuleInstanceCount(ComponentName owner) {
456 INotificationManager service = getService();
458 return service.getRuleInstanceCount(owner);
459 } catch (RemoteException e) {
460 throw e.rethrowFromSystemServer();
465 * Returns AutomaticZenRules owned by the caller.
468 * Throws a SecurityException if policy access is granted to this package.
469 * See {@link #isNotificationPolicyAccessGranted}.
471 public Map<String, AutomaticZenRule> getAutomaticZenRules() {
472 INotificationManager service = getService();
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,
482 } catch (RemoteException e) {
483 throw e.rethrowFromSystemServer();
488 * Returns the AutomaticZenRule with the given id, if it exists and the caller has access.
491 * Throws a SecurityException if policy access is granted to this package.
492 * See {@link #isNotificationPolicyAccessGranted}.
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}.
498 public AutomaticZenRule getAutomaticZenRule(String id) {
499 INotificationManager service = getService();
501 return service.getAutomaticZenRule(id);
502 } catch (RemoteException e) {
503 throw e.rethrowFromSystemServer();
508 * Creates the given zen rule.
511 * Throws a SecurityException if policy access is granted to this package.
512 * See {@link #isNotificationPolicyAccessGranted}.
514 * @param automaticZenRule the rule to create.
515 * @return The id of the newly created rule; null if the rule could not be created.
517 public String addAutomaticZenRule(AutomaticZenRule automaticZenRule) {
518 INotificationManager service = getService();
520 return service.addAutomaticZenRule(automaticZenRule);
521 } catch (RemoteException e) {
522 throw e.rethrowFromSystemServer();
527 * Updates the given zen rule.
530 * Throws a SecurityException if policy access is granted to this package.
531 * See {@link #isNotificationPolicyAccessGranted}.
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.
539 public boolean updateAutomaticZenRule(String id, AutomaticZenRule automaticZenRule) {
540 INotificationManager service = getService();
542 return service.updateAutomaticZenRule(id, automaticZenRule);
543 } catch (RemoteException e) {
544 throw e.rethrowFromSystemServer();
549 * Deletes the automatic zen rule with the given id.
552 * Throws a SecurityException if policy access is granted to this package.
553 * See {@link #isNotificationPolicyAccessGranted}.
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.
560 public boolean removeAutomaticZenRule(String id) {
561 INotificationManager service = getService();
563 return service.removeAutomaticZenRule(id);
564 } catch (RemoteException e) {
565 throw e.rethrowFromSystemServer();
570 * Deletes all automatic zen rules owned by the given package.
574 public boolean removeAutomaticZenRules(String packageName) {
575 INotificationManager service = getService();
577 return service.removeAutomaticZenRules(packageName);
578 } catch (RemoteException e) {
579 throw e.rethrowFromSystemServer();
584 * Returns the user specified importance for notifications from the calling package.
586 * @return An importance level, such as {@link #IMPORTANCE_DEFAULT}.
588 public @Importance int getImportance() {
589 INotificationManager service = getService();
591 return service.getPackageImportance(mContext.getPackageName());
592 } catch (RemoteException e) {
593 throw e.rethrowFromSystemServer();
598 * Returns whether notifications from the calling package are blocked.
600 public boolean areNotificationsEnabled() {
601 INotificationManager service = getService();
603 return service.areNotificationsEnabled(mContext.getPackageName());
604 } catch (RemoteException e) {
605 throw e.rethrowFromSystemServer();
610 * Checks the ability to read/modify notification policy for the calling package.
613 * Returns true if the calling package can read/modify notification policy.
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}.
620 * Use {@link #ACTION_NOTIFICATION_POLICY_ACCESS_GRANTED_CHANGED} to listen for
621 * user grant or denial of this access.
623 public boolean isNotificationPolicyAccessGranted() {
624 INotificationManager service = getService();
626 return service.isNotificationPolicyAccessGranted(mContext.getOpPackageName());
627 } catch (RemoteException e) {
628 throw e.rethrowFromSystemServer();
633 public boolean isNotificationPolicyAccessGrantedForPackage(String pkg) {
634 INotificationManager service = getService();
636 return service.isNotificationPolicyAccessGrantedForPackage(pkg);
637 } catch (RemoteException e) {
638 throw e.rethrowFromSystemServer();
643 * Gets the current notification policy.
646 * Only available if policy access is granted to this package.
647 * See {@link #isNotificationPolicyAccessGranted}.
649 public Policy getNotificationPolicy() {
650 INotificationManager service = getService();
652 return service.getNotificationPolicy(mContext.getOpPackageName());
653 } catch (RemoteException e) {
654 throw e.rethrowFromSystemServer();
659 * Sets the current notification policy.
662 * Only available if policy access is granted to this package.
663 * See {@link #isNotificationPolicyAccessGranted}.
665 * @param policy The new desired policy.
667 public void setNotificationPolicy(@NonNull Policy policy) {
668 checkRequired("policy", policy);
669 INotificationManager service = getService();
671 service.setNotificationPolicy(mContext.getOpPackageName(), policy);
672 } catch (RemoteException e) {
673 throw e.rethrowFromSystemServer();
678 public void setNotificationPolicyAccessGranted(String pkg, boolean granted) {
679 INotificationManager service = getService();
681 service.setNotificationPolicyAccessGranted(pkg, granted);
682 } catch (RemoteException e) {
683 throw e.rethrowFromSystemServer();
688 public ArraySet<String> getPackagesRequestingNotificationPolicyAccess() {
689 INotificationManager service = getService();
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++) {
699 } catch (RemoteException e) {
700 throw e.rethrowFromSystemServer();
702 return new ArraySet<>();
705 private Context mContext;
707 private static void checkRequired(String name, Object value) {
709 throw new IllegalArgumentException(name + " is required");
714 * Notification policy configuration. Represents user-preferences for notification
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;
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,
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;
744 /** Notification categories to prioritize. Bitmask of PRIORITY_CATEGORY_* constants. */
745 public final int priorityCategories;
747 /** Notification senders to prioritize for calls. One of:
748 * PRIORITY_SENDERS_ANY, PRIORITY_SENDERS_CONTACTS, PRIORITY_SENDERS_STARRED */
749 public final int priorityCallSenders;
751 /** Notification senders to prioritize for messages. One of:
752 * PRIORITY_SENDERS_ANY, PRIORITY_SENDERS_CONTACTS, PRIORITY_SENDERS_STARRED */
753 public final int priorityMessageSenders;
758 public static final int SUPPRESSED_EFFECTS_UNSET = -1;
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.
763 public static final int SUPPRESSED_EFFECT_SCREEN_OFF = 1 << 0;
765 * Whether notifications suppressed by DND should not interrupt visually when the screen
766 * is on (e.g. by peeking onto the screen).
768 public static final int SUPPRESSED_EFFECT_SCREEN_ON = 1 << 1;
770 private static final int[] ALL_SUPPRESSED_EFFECTS = {
771 SUPPRESSED_EFFECT_SCREEN_OFF,
772 SUPPRESSED_EFFECT_SCREEN_ON,
776 * Visual effects to suppress for a notification that is filtered by Do Not Disturb mode.
777 * Bitmask of SUPPRESSED_EFFECT_* constants.
779 public final int suppressedVisualEffects;
782 * Constructs a policy for Do Not Disturb priority mode behavior.
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.
788 public Policy(int priorityCategories, int priorityCallSenders, int priorityMessageSenders) {
789 this(priorityCategories, priorityCallSenders, priorityMessageSenders,
790 SUPPRESSED_EFFECTS_UNSET);
794 * Constructs a policy for Do Not Disturb priority mode behavior.
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.
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;
811 public Policy(Parcel source) {
812 this(source.readInt(), source.readInt(), source.readInt(), source.readInt());
816 public void writeToParcel(Parcel dest, int flags) {
817 dest.writeInt(priorityCategories);
818 dest.writeInt(priorityCallSenders);
819 dest.writeInt(priorityMessageSenders);
820 dest.writeInt(suppressedVisualEffects);
824 public int describeContents() {
829 public int hashCode() {
830 return Objects.hash(priorityCategories, priorityCallSenders, priorityMessageSenders,
831 suppressedVisualEffects);
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;
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)
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));
868 if (sb.length() > 0) sb.append(',');
869 sb.append("UNKNOWN_").append(effects);
871 return sb.toString();
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));
883 priorityCategories &= ~priorityCategory;
885 if (priorityCategories != 0) {
886 if (sb.length() > 0) sb.append(',');
887 sb.append("PRIORITY_CATEGORY_UNKNOWN_").append(priorityCategories);
889 return sb.toString();
892 private static String effectToString(int 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;
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;
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;
921 public static final Parcelable.Creator<Policy> CREATOR = new Parcelable.Creator<Policy>() {
923 public Policy createFromParcel(Parcel in) {
924 return new Policy(in);
928 public Policy[] newArray(int size) {
929 return new Policy[size];
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.
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()}).
945 * @return An array of {@link StatusBarNotification}.
947 public StatusBarNotification[] getActiveNotifications() {
948 final INotificationManager service = getService();
949 final String pkg = mContext.getPackageName();
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();
961 * Gets the current notification interruption filter.
964 * The interruption filter defines which notifications are allowed to interrupt the user
965 * (e.g. via sound & vibration) and is applied globally.
966 * @return One of the INTERRUPTION_FILTER_ constants, or INTERRUPTION_FILTER_UNKNOWN when
969 public final @InterruptionFilter int getCurrentInterruptionFilter() {
970 final INotificationManager service = getService();
972 return zenModeToInterruptionFilter(service.getZenMode());
973 } catch (RemoteException e) {
974 throw e.rethrowFromSystemServer();
979 * Sets the current notification interruption filter.
982 * The interruption filter defines which notifications are allowed to interrupt the user
983 * (e.g. via sound & vibration) and is applied globally.
984 * @return One of the INTERRUPTION_FILTER_ constants, or INTERRUPTION_FILTER_UNKNOWN when
988 * Only available if policy access is granted to this package.
989 * See {@link #isNotificationPolicyAccessGranted}.
991 public final void setInterruptionFilter(int interruptionFilter) {
992 final INotificationManager service = getService();
994 service.setInterruptionFilter(mContext.getOpPackageName(), interruptionFilter);
995 } catch (RemoteException e) {
996 throw e.rethrowFromSystemServer();
1001 public static int zenModeToInterruptionFilter(int 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;
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;