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 17package android.app; 18 19import android.annotation.IntDef; 20import android.annotation.NonNull; 21import android.annotation.SdkConstant; 22import android.app.Notification.Builder; 23import android.content.ComponentName; 24import android.content.Context; 25import android.content.pm.ParceledListSlice; 26import android.graphics.drawable.Icon; 27import android.net.Uri; 28import android.os.Build; 29import android.os.Bundle; 30import android.os.Handler; 31import android.os.IBinder; 32import android.os.Parcel; 33import android.os.Parcelable; 34import android.os.RemoteException; 35import android.os.ServiceManager; 36import android.os.StrictMode; 37import android.os.UserHandle; 38import android.provider.Settings.Global; 39import android.service.notification.NotificationListenerService.Ranking; 40import android.service.notification.StatusBarNotification; 41import android.service.notification.ZenModeConfig; 42import android.util.ArraySet; 43import android.util.Log; 44 45import java.lang.annotation.Retention; 46import java.lang.annotation.RetentionPolicy; 47import java.util.HashMap; 48import java.util.List; 49import java.util.Map; 50import 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 */ 93public 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 & 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 & 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} 1022