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