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.Intent; 28 import android.content.pm.ParceledListSlice; 29 import android.graphics.drawable.Icon; 30 import android.net.Uri; 31 import android.os.Build; 32 import android.os.Bundle; 33 import android.os.Handler; 34 import android.os.IBinder; 35 import android.os.Parcel; 36 import android.os.Parcelable; 37 import android.os.RemoteException; 38 import android.os.ServiceManager; 39 import android.os.StrictMode; 40 import android.os.UserHandle; 41 import android.provider.Settings.Global; 42 import android.service.notification.StatusBarNotification; 43 import android.service.notification.ZenModeConfig; 44 import android.util.Log; 45 import android.util.proto.ProtoOutputStream; 46 47 import java.lang.annotation.Retention; 48 import java.lang.annotation.RetentionPolicy; 49 import java.util.Arrays; 50 import java.util.HashMap; 51 import java.util.List; 52 import java.util.Map; 53 import java.util.Objects; 54 55 /** 56 * Class to notify the user of events that happen. This is how you tell 57 * the user that something has happened in the background. {@more} 58 * 59 * Notifications can take different forms: 60 * <ul> 61 * <li>A persistent icon that goes in the status bar and is accessible 62 * through the launcher, (when the user selects it, a designated Intent 63 * can be launched),</li> 64 * <li>Turning on or flashing LEDs on the device, or</li> 65 * <li>Alerting the user by flashing the backlight, playing a sound, 66 * or vibrating.</li> 67 * </ul> 68 * 69 * <p> 70 * Each of the notify methods takes an int id parameter and optionally a 71 * {@link String} tag parameter, which may be {@code null}. These parameters 72 * are used to form a pair (tag, id), or ({@code null}, id) if tag is 73 * unspecified. This pair identifies this notification from your app to the 74 * system, so that pair should be unique within your app. If you call one 75 * of the notify methods with a (tag, id) pair that is currently active and 76 * a new set of notification parameters, it will be updated. For example, 77 * if you pass a new status bar icon, the old icon in the status bar will 78 * be replaced with the new one. This is also the same tag and id you pass 79 * to the {@link #cancel(int)} or {@link #cancel(String, int)} method to clear 80 * this notification. 81 * 82 * <div class="special reference"> 83 * <h3>Developer Guides</h3> 84 * <p>For a guide to creating notifications, read the 85 * <a href="{@docRoot}guide/topics/ui/notifiers/notifications.html">Status Bar Notifications</a> 86 * developer guide.</p> 87 * </div> 88 * 89 * @see android.app.Notification 90 */ 91 @SystemService(Context.NOTIFICATION_SERVICE) 92 public class NotificationManager { 93 private static String TAG = "NotificationManager"; 94 private static boolean localLOGV = false; 95 96 /** 97 * Intent that is broadcast when an application is blocked or unblocked. 98 * 99 * This broadcast is only sent to the app whose block state has changed. 100 * 101 * Input: nothing 102 * Output: {@link #EXTRA_BLOCKED_STATE} 103 */ 104 @SdkConstant(SdkConstant.SdkConstantType.BROADCAST_INTENT_ACTION) 105 public static final String ACTION_APP_BLOCK_STATE_CHANGED = 106 "android.app.action.APP_BLOCK_STATE_CHANGED"; 107 108 /** 109 * Intent that is broadcast when a {@link NotificationChannel} is blocked 110 * (when {@link NotificationChannel#getImportance()} is {@link #IMPORTANCE_NONE}) or unblocked 111 * (when {@link NotificationChannel#getImportance()} is anything other than 112 * {@link #IMPORTANCE_NONE}). 113 * 114 * This broadcast is only sent to the app that owns the channel that has changed. 115 * 116 * Input: nothing 117 * Output: {@link #EXTRA_NOTIFICATION_CHANNEL_ID} 118 * Output: {@link #EXTRA_BLOCKED_STATE} 119 */ 120 @SdkConstant(SdkConstant.SdkConstantType.BROADCAST_INTENT_ACTION) 121 public static final String ACTION_NOTIFICATION_CHANNEL_BLOCK_STATE_CHANGED = 122 "android.app.action.NOTIFICATION_CHANNEL_BLOCK_STATE_CHANGED"; 123 124 /** 125 * Extra for {@link #ACTION_NOTIFICATION_CHANNEL_BLOCK_STATE_CHANGED} containing the id of the 126 * {@link NotificationChannel} which has a new blocked state. 127 * 128 * The value will be the {@link NotificationChannel#getId()} of the channel. 129 */ 130 public static final String EXTRA_NOTIFICATION_CHANNEL_ID = 131 "android.app.extra.NOTIFICATION_CHANNEL_ID"; 132 133 /** 134 * Extra for {@link #ACTION_NOTIFICATION_CHANNEL_GROUP_BLOCK_STATE_CHANGED} containing the id 135 * of the {@link NotificationChannelGroup} which has a new blocked state. 136 * 137 * The value will be the {@link NotificationChannelGroup#getId()} of the group. 138 */ 139 public static final String EXTRA_NOTIFICATION_CHANNEL_GROUP_ID = 140 "android.app.extra.NOTIFICATION_CHANNEL_GROUP_ID"; 141 142 143 /** 144 * Extra for {@link #ACTION_NOTIFICATION_CHANNEL_BLOCK_STATE_CHANGED} or 145 * {@link #ACTION_NOTIFICATION_CHANNEL_GROUP_BLOCK_STATE_CHANGED} containing the new blocked 146 * state as a boolean. 147 * 148 * The value will be {@code true} if this channel or group is now blocked and {@code false} if 149 * this channel or group is now unblocked. 150 */ 151 public static final String EXTRA_BLOCKED_STATE = "android.app.extra.BLOCKED_STATE"; 152 153 /** 154 * Intent that is broadcast when a {@link NotificationChannelGroup} is 155 * {@link NotificationChannelGroup#isBlocked() blocked} or unblocked. 156 * 157 * This broadcast is only sent to the app that owns the channel group that has changed. 158 * 159 * Input: nothing 160 * Output: {@link #EXTRA_NOTIFICATION_CHANNEL_GROUP_ID} 161 * Output: {@link #EXTRA_BLOCKED_STATE} 162 */ 163 @SdkConstant(SdkConstant.SdkConstantType.BROADCAST_INTENT_ACTION) 164 public static final String ACTION_NOTIFICATION_CHANNEL_GROUP_BLOCK_STATE_CHANGED = 165 "android.app.action.NOTIFICATION_CHANNEL_GROUP_BLOCK_STATE_CHANGED"; 166 167 /** 168 * Intent that is broadcast when the state of {@link #getEffectsSuppressor()} changes. 169 * This broadcast is only sent to registered receivers. 170 * 171 * @hide 172 */ 173 @SdkConstant(SdkConstant.SdkConstantType.BROADCAST_INTENT_ACTION) 174 public static final String ACTION_EFFECTS_SUPPRESSOR_CHANGED 175 = "android.os.action.ACTION_EFFECTS_SUPPRESSOR_CHANGED"; 176 177 /** 178 * Intent that is broadcast when the state of {@link #isNotificationPolicyAccessGranted()} 179 * changes. 180 * 181 * This broadcast is only sent to registered receivers, and only to the apps that have changed. 182 */ 183 @SdkConstant(SdkConstant.SdkConstantType.BROADCAST_INTENT_ACTION) 184 public static final String ACTION_NOTIFICATION_POLICY_ACCESS_GRANTED_CHANGED 185 = "android.app.action.NOTIFICATION_POLICY_ACCESS_GRANTED_CHANGED"; 186 187 /** 188 * Intent that is broadcast when the state of getNotificationPolicy() changes. 189 * This broadcast is only sent to registered receivers. 190 */ 191 @SdkConstant(SdkConstant.SdkConstantType.BROADCAST_INTENT_ACTION) 192 public static final String ACTION_NOTIFICATION_POLICY_CHANGED 193 = "android.app.action.NOTIFICATION_POLICY_CHANGED"; 194 195 /** 196 * Intent that is broadcast when the state of getCurrentInterruptionFilter() changes. 197 * This broadcast is only sent to registered receivers. 198 */ 199 @SdkConstant(SdkConstant.SdkConstantType.BROADCAST_INTENT_ACTION) 200 public static final String ACTION_INTERRUPTION_FILTER_CHANGED 201 = "android.app.action.INTERRUPTION_FILTER_CHANGED"; 202 203 /** 204 * Intent that is broadcast when the state of getCurrentInterruptionFilter() changes. 205 * @hide 206 */ 207 @SdkConstant(SdkConstant.SdkConstantType.BROADCAST_INTENT_ACTION) 208 public static final String ACTION_INTERRUPTION_FILTER_CHANGED_INTERNAL 209 = "android.app.action.INTERRUPTION_FILTER_CHANGED_INTERNAL"; 210 211 /** @hide */ 212 @IntDef(prefix = { "INTERRUPTION_FILTER_" }, value = { 213 INTERRUPTION_FILTER_NONE, INTERRUPTION_FILTER_PRIORITY, INTERRUPTION_FILTER_ALARMS, 214 INTERRUPTION_FILTER_ALL, INTERRUPTION_FILTER_UNKNOWN 215 }) 216 @Retention(RetentionPolicy.SOURCE) 217 public @interface InterruptionFilter {} 218 219 /** 220 * {@link #getCurrentInterruptionFilter() Interruption filter} constant - 221 * Normal interruption filter - no notifications are suppressed. 222 */ 223 public static final int INTERRUPTION_FILTER_ALL = 1; 224 225 /** 226 * {@link #getCurrentInterruptionFilter() Interruption filter} constant - 227 * Priority interruption filter - all notifications are suppressed except those that match 228 * the priority criteria. Some audio streams are muted. See 229 * {@link Policy#priorityCallSenders}, {@link Policy#priorityCategories}, 230 * {@link Policy#priorityMessageSenders} to define or query this criteria. Users can 231 * additionally specify packages that can bypass this interruption filter. 232 */ 233 public static final int INTERRUPTION_FILTER_PRIORITY = 2; 234 235 /** 236 * {@link #getCurrentInterruptionFilter() Interruption filter} constant - 237 * No interruptions filter - all notifications are suppressed and all audio streams (except 238 * those used for phone calls) and vibrations are muted. 239 */ 240 public static final int INTERRUPTION_FILTER_NONE = 3; 241 242 /** 243 * {@link #getCurrentInterruptionFilter() Interruption filter} constant - 244 * Alarms only interruption filter - all notifications except those of category 245 * {@link Notification#CATEGORY_ALARM} are suppressed. Some audio streams are muted. 246 */ 247 public static final int INTERRUPTION_FILTER_ALARMS = 4; 248 249 /** {@link #getCurrentInterruptionFilter() Interruption filter} constant - returned when 250 * the value is unavailable for any reason. 251 */ 252 public static final int INTERRUPTION_FILTER_UNKNOWN = 0; 253 254 /** @hide */ 255 @IntDef(prefix = { "IMPORTANCE_" }, value = { 256 IMPORTANCE_UNSPECIFIED, IMPORTANCE_NONE, 257 IMPORTANCE_MIN, IMPORTANCE_LOW, IMPORTANCE_DEFAULT, IMPORTANCE_HIGH 258 }) 259 @Retention(RetentionPolicy.SOURCE) 260 public @interface Importance {} 261 262 /** Value signifying that the user has not expressed a per-app visibility override value. 263 * @hide */ 264 public static final int VISIBILITY_NO_OVERRIDE = -1000; 265 266 /** 267 * Value signifying that the user has not expressed an importance. 268 * 269 * This value is for persisting preferences, and should never be associated with 270 * an actual notification. 271 */ 272 public static final int IMPORTANCE_UNSPECIFIED = -1000; 273 274 /** 275 * A notification with no importance: does not show in the shade. 276 */ 277 public static final int IMPORTANCE_NONE = 0; 278 279 /** 280 * Min notification importance: only shows in the shade, below the fold. This should 281 * not be used with {@link Service#startForeground(int, Notification) Service.startForeground} 282 * since a foreground service is supposed to be something the user cares about so it does 283 * not make semantic sense to mark its notification as minimum importance. If you do this 284 * as of Android version {@link android.os.Build.VERSION_CODES#O}, the system will show 285 * a higher-priority notification about your app running in the background. 286 */ 287 public static final int IMPORTANCE_MIN = 1; 288 289 /** 290 * Low notification importance: shows everywhere, but is not intrusive. 291 */ 292 public static final int IMPORTANCE_LOW = 2; 293 294 /** 295 * Default notification importance: shows everywhere, makes noise, but does not visually 296 * intrude. 297 */ 298 public static final int IMPORTANCE_DEFAULT = 3; 299 300 /** 301 * Higher notification importance: shows everywhere, makes noise and peeks. May use full screen 302 * intents. 303 */ 304 public static final int IMPORTANCE_HIGH = 4; 305 306 /** 307 * Unused. 308 */ 309 public static final int IMPORTANCE_MAX = 5; 310 311 private static INotificationManager sService; 312 313 /** @hide */ getService()314 static public INotificationManager getService() 315 { 316 if (sService != null) { 317 return sService; 318 } 319 IBinder b = ServiceManager.getService("notification"); 320 sService = INotificationManager.Stub.asInterface(b); 321 return sService; 322 } 323 NotificationManager(Context context, Handler handler)324 /*package*/ NotificationManager(Context context, Handler handler) 325 { 326 mContext = context; 327 } 328 329 /** {@hide} */ from(Context context)330 public static NotificationManager from(Context context) { 331 return (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); 332 } 333 334 /** 335 * Post a notification to be shown in the status bar. If a notification with 336 * the same id has already been posted by your application and has not yet been canceled, it 337 * will be replaced by the updated information. 338 * 339 * @param id An identifier for this notification unique within your 340 * application. 341 * @param notification A {@link Notification} object describing what to show the user. Must not 342 * be null. 343 */ notify(int id, Notification notification)344 public void notify(int id, Notification notification) 345 { 346 notify(null, id, notification); 347 } 348 349 /** 350 * Post a notification to be shown in the status bar. If a notification with 351 * the same tag and id has already been posted by your application and has not yet been 352 * canceled, it will be replaced by the updated information. 353 * 354 * All {@link android.service.notification.NotificationListenerService listener services} will 355 * be granted {@link Intent#FLAG_GRANT_READ_URI_PERMISSION} access to any {@link Uri uris} 356 * provided on this notification or the 357 * {@link NotificationChannel} this notification is posted to using 358 * {@link Context#grantUriPermission(String, Uri, int)}. Permission will be revoked when the 359 * notification is canceled, or you can revoke permissions with 360 * {@link Context#revokeUriPermission(Uri, int)}. 361 * 362 * @param tag A string identifier for this notification. May be {@code null}. 363 * @param id An identifier for this notification. The pair (tag, id) must be unique 364 * within your application. 365 * @param notification A {@link Notification} object describing what to 366 * show the user. Must not be null. 367 */ notify(String tag, int id, Notification notification)368 public void notify(String tag, int id, Notification notification) 369 { 370 notifyAsUser(tag, id, notification, mContext.getUser()); 371 } 372 373 /** 374 * @hide 375 */ notifyAsUser(String tag, int id, Notification notification, UserHandle user)376 public void notifyAsUser(String tag, int id, Notification notification, UserHandle user) 377 { 378 INotificationManager service = getService(); 379 String pkg = mContext.getPackageName(); 380 // Fix the notification as best we can. 381 Notification.addFieldsFromContext(mContext, notification); 382 383 if (notification.sound != null) { 384 notification.sound = notification.sound.getCanonicalUri(); 385 if (StrictMode.vmFileUriExposureEnabled()) { 386 notification.sound.checkFileUriExposed("Notification.sound"); 387 } 388 389 } 390 fixLegacySmallIcon(notification, pkg); 391 if (mContext.getApplicationInfo().targetSdkVersion > Build.VERSION_CODES.LOLLIPOP_MR1) { 392 if (notification.getSmallIcon() == null) { 393 throw new IllegalArgumentException("Invalid notification (no valid small icon): " 394 + notification); 395 } 396 } 397 if (localLOGV) Log.v(TAG, pkg + ": notify(" + id + ", " + notification + ")"); 398 notification.reduceImageSizes(mContext); 399 400 ActivityManager am = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE); 401 boolean isLowRam = am.isLowRamDevice(); 402 final Notification copy = Builder.maybeCloneStrippedForDelivery(notification, isLowRam, 403 mContext); 404 try { 405 service.enqueueNotificationWithTag(pkg, mContext.getOpPackageName(), tag, id, 406 copy, user.getIdentifier()); 407 } catch (RemoteException e) { 408 throw e.rethrowFromSystemServer(); 409 } 410 } 411 fixLegacySmallIcon(Notification n, String pkg)412 private void fixLegacySmallIcon(Notification n, String pkg) { 413 if (n.getSmallIcon() == null && n.icon != 0) { 414 n.setSmallIcon(Icon.createWithResource(pkg, n.icon)); 415 } 416 } 417 418 /** 419 * Cancel a previously shown notification. If it's transient, the view 420 * will be hidden. If it's persistent, it will be removed from the status 421 * bar. 422 */ cancel(int id)423 public void cancel(int id) 424 { 425 cancel(null, id); 426 } 427 428 /** 429 * Cancel a previously shown notification. If it's transient, the view 430 * will be hidden. If it's persistent, it will be removed from the status 431 * bar. 432 */ cancel(String tag, int id)433 public void cancel(String tag, int id) 434 { 435 cancelAsUser(tag, id, mContext.getUser()); 436 } 437 438 /** 439 * @hide 440 */ cancelAsUser(String tag, int id, UserHandle user)441 public void cancelAsUser(String tag, int id, UserHandle user) 442 { 443 INotificationManager service = getService(); 444 String pkg = mContext.getPackageName(); 445 if (localLOGV) Log.v(TAG, pkg + ": cancel(" + id + ")"); 446 try { 447 service.cancelNotificationWithTag(pkg, tag, id, user.getIdentifier()); 448 } catch (RemoteException e) { 449 throw e.rethrowFromSystemServer(); 450 } 451 } 452 453 /** 454 * Cancel all previously shown notifications. See {@link #cancel} for the 455 * detailed behavior. 456 */ cancelAll()457 public void cancelAll() 458 { 459 INotificationManager service = getService(); 460 String pkg = mContext.getPackageName(); 461 if (localLOGV) Log.v(TAG, pkg + ": cancelAll()"); 462 try { 463 service.cancelAllNotifications(pkg, mContext.getUserId()); 464 } catch (RemoteException e) { 465 throw e.rethrowFromSystemServer(); 466 } 467 } 468 469 /** 470 * Creates a group container for {@link NotificationChannel} objects. 471 * 472 * This can be used to rename an existing group. 473 * <p> 474 * Group information is only used for presentation, not for behavior. Groups are optional 475 * for channels, and you can have a mix of channels that belong to groups and channels 476 * that do not. 477 * </p> 478 * <p> 479 * For example, if your application supports multiple accounts, and those accounts will 480 * have similar channels, you can create a group for each account with account specific 481 * labels instead of appending account information to each channel's label. 482 * </p> 483 * 484 * @param group The group to create 485 */ createNotificationChannelGroup(@onNull NotificationChannelGroup group)486 public void createNotificationChannelGroup(@NonNull NotificationChannelGroup group) { 487 createNotificationChannelGroups(Arrays.asList(group)); 488 } 489 490 /** 491 * Creates multiple notification channel groups. 492 * 493 * @param groups The list of groups to create 494 */ createNotificationChannelGroups(@onNull List<NotificationChannelGroup> groups)495 public void createNotificationChannelGroups(@NonNull List<NotificationChannelGroup> groups) { 496 INotificationManager service = getService(); 497 try { 498 service.createNotificationChannelGroups(mContext.getPackageName(), 499 new ParceledListSlice(groups)); 500 } catch (RemoteException e) { 501 throw e.rethrowFromSystemServer(); 502 } 503 } 504 505 /** 506 * Creates a notification channel that notifications can be posted to. 507 * 508 * This can also be used to restore a deleted channel and to update an existing channel's 509 * name, description, group, and/or importance. 510 * 511 * <p>The name and description should only be changed if the locale changes 512 * or in response to the user renaming this channel. For example, if a user has a channel 513 * named 'John Doe' that represents messages from a 'John Doe', and 'John Doe' changes his name 514 * to 'John Smith,' the channel can be renamed to match. 515 * 516 * <p>The importance of an existing channel will only be changed if the new importance is lower 517 * than the current value and the user has not altered any settings on this channel. 518 * 519 * <p>The group an existing channel will only be changed if the channel does not already 520 * belong to a group. 521 * 522 * All other fields are ignored for channels that already exist. 523 * 524 * @param channel the channel to create. Note that the created channel may differ from this 525 * value. If the provided channel is malformed, a RemoteException will be 526 * thrown. 527 */ createNotificationChannel(@onNull NotificationChannel channel)528 public void createNotificationChannel(@NonNull NotificationChannel channel) { 529 createNotificationChannels(Arrays.asList(channel)); 530 } 531 532 /** 533 * Creates multiple notification channels that different notifications can be posted to. See 534 * {@link #createNotificationChannel(NotificationChannel)}. 535 * 536 * @param channels the list of channels to attempt to create. 537 */ createNotificationChannels(@onNull List<NotificationChannel> channels)538 public void createNotificationChannels(@NonNull List<NotificationChannel> channels) { 539 INotificationManager service = getService(); 540 try { 541 service.createNotificationChannels(mContext.getPackageName(), 542 new ParceledListSlice(channels)); 543 } catch (RemoteException e) { 544 throw e.rethrowFromSystemServer(); 545 } 546 } 547 548 /** 549 * Returns the notification channel settings for a given channel id. 550 * 551 * The channel must belong to your package, or it will not be returned. 552 */ getNotificationChannel(String channelId)553 public NotificationChannel getNotificationChannel(String channelId) { 554 INotificationManager service = getService(); 555 try { 556 return service.getNotificationChannel(mContext.getPackageName(), channelId); 557 } catch (RemoteException e) { 558 throw e.rethrowFromSystemServer(); 559 } 560 } 561 562 /** 563 * Returns all notification channels belonging to the calling package. 564 */ getNotificationChannels()565 public List<NotificationChannel> getNotificationChannels() { 566 INotificationManager service = getService(); 567 try { 568 return service.getNotificationChannels(mContext.getPackageName()).getList(); 569 } catch (RemoteException e) { 570 throw e.rethrowFromSystemServer(); 571 } 572 } 573 574 /** 575 * Deletes the given notification channel. 576 * 577 * <p>If you {@link #createNotificationChannel(NotificationChannel) create} a new channel with 578 * this same id, the deleted channel will be un-deleted with all of the same settings it 579 * had before it was deleted. 580 */ deleteNotificationChannel(String channelId)581 public void deleteNotificationChannel(String channelId) { 582 INotificationManager service = getService(); 583 try { 584 service.deleteNotificationChannel(mContext.getPackageName(), channelId); 585 } catch (RemoteException e) { 586 throw e.rethrowFromSystemServer(); 587 } 588 } 589 590 /** 591 * Returns the notification channel group settings for a given channel group id. 592 * 593 * The channel group must belong to your package, or null will be returned. 594 */ getNotificationChannelGroup(String channelGroupId)595 public NotificationChannelGroup getNotificationChannelGroup(String channelGroupId) { 596 INotificationManager service = getService(); 597 try { 598 return service.getNotificationChannelGroup(mContext.getPackageName(), channelGroupId); 599 } catch (RemoteException e) { 600 throw e.rethrowFromSystemServer(); 601 } 602 } 603 604 /** 605 * Returns all notification channel groups belonging to the calling app. 606 */ getNotificationChannelGroups()607 public List<NotificationChannelGroup> getNotificationChannelGroups() { 608 INotificationManager service = getService(); 609 try { 610 return service.getNotificationChannelGroups(mContext.getPackageName()).getList(); 611 } catch (RemoteException e) { 612 throw e.rethrowFromSystemServer(); 613 } 614 } 615 616 /** 617 * Deletes the given notification channel group, and all notification channels that 618 * belong to it. 619 */ deleteNotificationChannelGroup(String groupId)620 public void deleteNotificationChannelGroup(String groupId) { 621 INotificationManager service = getService(); 622 try { 623 service.deleteNotificationChannelGroup(mContext.getPackageName(), groupId); 624 } catch (RemoteException e) { 625 throw e.rethrowFromSystemServer(); 626 } 627 } 628 629 /** 630 * @hide 631 */ 632 @TestApi getEffectsSuppressor()633 public ComponentName getEffectsSuppressor() { 634 INotificationManager service = getService(); 635 try { 636 return service.getEffectsSuppressor(); 637 } catch (RemoteException e) { 638 throw e.rethrowFromSystemServer(); 639 } 640 } 641 642 /** 643 * @hide 644 */ matchesCallFilter(Bundle extras)645 public boolean matchesCallFilter(Bundle extras) { 646 INotificationManager service = getService(); 647 try { 648 return service.matchesCallFilter(extras); 649 } catch (RemoteException e) { 650 throw e.rethrowFromSystemServer(); 651 } 652 } 653 654 /** 655 * @hide 656 */ isSystemConditionProviderEnabled(String path)657 public boolean isSystemConditionProviderEnabled(String path) { 658 INotificationManager service = getService(); 659 try { 660 return service.isSystemConditionProviderEnabled(path); 661 } catch (RemoteException e) { 662 throw e.rethrowFromSystemServer(); 663 } 664 } 665 666 /** 667 * @hide 668 */ setZenMode(int mode, Uri conditionId, String reason)669 public void setZenMode(int mode, Uri conditionId, String reason) { 670 INotificationManager service = getService(); 671 try { 672 service.setZenMode(mode, conditionId, reason); 673 } catch (RemoteException e) { 674 throw e.rethrowFromSystemServer(); 675 } 676 } 677 678 /** 679 * @hide 680 */ getZenMode()681 public int getZenMode() { 682 INotificationManager service = getService(); 683 try { 684 return service.getZenMode(); 685 } catch (RemoteException e) { 686 throw e.rethrowFromSystemServer(); 687 } 688 } 689 690 /** 691 * @hide 692 */ getZenModeConfig()693 public ZenModeConfig getZenModeConfig() { 694 INotificationManager service = getService(); 695 try { 696 return service.getZenModeConfig(); 697 } catch (RemoteException e) { 698 throw e.rethrowFromSystemServer(); 699 } 700 } 701 702 /** 703 * @hide 704 */ getRuleInstanceCount(ComponentName owner)705 public int getRuleInstanceCount(ComponentName owner) { 706 INotificationManager service = getService(); 707 try { 708 return service.getRuleInstanceCount(owner); 709 } catch (RemoteException e) { 710 throw e.rethrowFromSystemServer(); 711 } 712 } 713 714 /** 715 * Returns AutomaticZenRules owned by the caller. 716 * 717 * <p> 718 * Throws a SecurityException if policy access is granted to this package. 719 * See {@link #isNotificationPolicyAccessGranted}. 720 */ getAutomaticZenRules()721 public Map<String, AutomaticZenRule> getAutomaticZenRules() { 722 INotificationManager service = getService(); 723 try { 724 List<ZenModeConfig.ZenRule> rules = service.getZenRules(); 725 Map<String, AutomaticZenRule> ruleMap = new HashMap<>(); 726 for (ZenModeConfig.ZenRule rule : rules) { 727 ruleMap.put(rule.id, new AutomaticZenRule(rule.name, rule.component, 728 rule.conditionId, zenModeToInterruptionFilter(rule.zenMode), rule.enabled, 729 rule.creationTime)); 730 } 731 return ruleMap; 732 } catch (RemoteException e) { 733 throw e.rethrowFromSystemServer(); 734 } 735 } 736 737 /** 738 * Returns the AutomaticZenRule with the given id, if it exists and the caller has access. 739 * 740 * <p> 741 * Throws a SecurityException if policy access is granted to this package. 742 * See {@link #isNotificationPolicyAccessGranted}. 743 * 744 * <p> 745 * Returns null if there are no zen rules that match the given id, or if the calling package 746 * doesn't own the matching rule. See {@link AutomaticZenRule#getOwner}. 747 */ getAutomaticZenRule(String id)748 public AutomaticZenRule getAutomaticZenRule(String id) { 749 INotificationManager service = getService(); 750 try { 751 return service.getAutomaticZenRule(id); 752 } catch (RemoteException e) { 753 throw e.rethrowFromSystemServer(); 754 } 755 } 756 757 /** 758 * Creates the given zen rule. 759 * 760 * <p> 761 * Throws a SecurityException if policy access is granted to this package. 762 * See {@link #isNotificationPolicyAccessGranted}. 763 * 764 * @param automaticZenRule the rule to create. 765 * @return The id of the newly created rule; null if the rule could not be created. 766 */ addAutomaticZenRule(AutomaticZenRule automaticZenRule)767 public String addAutomaticZenRule(AutomaticZenRule automaticZenRule) { 768 INotificationManager service = getService(); 769 try { 770 return service.addAutomaticZenRule(automaticZenRule); 771 } catch (RemoteException e) { 772 throw e.rethrowFromSystemServer(); 773 } 774 } 775 776 /** 777 * Updates the given zen rule. 778 * 779 * <p> 780 * Throws a SecurityException if policy access is granted to this package. 781 * See {@link #isNotificationPolicyAccessGranted}. 782 * 783 * <p> 784 * Callers can only update rules that they own. See {@link AutomaticZenRule#getOwner}. 785 * @param id The id of the rule to update 786 * @param automaticZenRule the rule to update. 787 * @return Whether the rule was successfully updated. 788 */ updateAutomaticZenRule(String id, AutomaticZenRule automaticZenRule)789 public boolean updateAutomaticZenRule(String id, AutomaticZenRule automaticZenRule) { 790 INotificationManager service = getService(); 791 try { 792 return service.updateAutomaticZenRule(id, automaticZenRule); 793 } catch (RemoteException e) { 794 throw e.rethrowFromSystemServer(); 795 } 796 } 797 798 /** 799 * Deletes the automatic zen rule with the given id. 800 * 801 * <p> 802 * Throws a SecurityException if policy access is granted to this package. 803 * See {@link #isNotificationPolicyAccessGranted}. 804 * 805 * <p> 806 * Callers can only delete rules that they own. See {@link AutomaticZenRule#getOwner}. 807 * @param id the id of the rule to delete. 808 * @return Whether the rule was successfully deleted. 809 */ removeAutomaticZenRule(String id)810 public boolean removeAutomaticZenRule(String id) { 811 INotificationManager service = getService(); 812 try { 813 return service.removeAutomaticZenRule(id); 814 } catch (RemoteException e) { 815 throw e.rethrowFromSystemServer(); 816 } 817 } 818 819 /** 820 * Deletes all automatic zen rules owned by the given package. 821 * 822 * @hide 823 */ removeAutomaticZenRules(String packageName)824 public boolean removeAutomaticZenRules(String packageName) { 825 INotificationManager service = getService(); 826 try { 827 return service.removeAutomaticZenRules(packageName); 828 } catch (RemoteException e) { 829 throw e.rethrowFromSystemServer(); 830 } 831 } 832 833 /** 834 * Returns the user specified importance for notifications from the calling 835 * package. 836 */ getImportance()837 public @Importance int getImportance() { 838 INotificationManager service = getService(); 839 try { 840 return service.getPackageImportance(mContext.getPackageName()); 841 } catch (RemoteException e) { 842 throw e.rethrowFromSystemServer(); 843 } 844 } 845 846 /** 847 * Returns whether notifications from the calling package are blocked. 848 */ areNotificationsEnabled()849 public boolean areNotificationsEnabled() { 850 INotificationManager service = getService(); 851 try { 852 return service.areNotificationsEnabled(mContext.getPackageName()); 853 } catch (RemoteException e) { 854 throw e.rethrowFromSystemServer(); 855 } 856 } 857 858 /** 859 * Checks the ability to modify notification do not disturb policy for the calling package. 860 * 861 * <p> 862 * Returns true if the calling package can modify notification policy. 863 * 864 * <p> 865 * Apps can request policy access by sending the user to the activity that matches the system 866 * intent action {@link android.provider.Settings#ACTION_NOTIFICATION_POLICY_ACCESS_SETTINGS}. 867 * 868 * <p> 869 * Use {@link #ACTION_NOTIFICATION_POLICY_ACCESS_GRANTED_CHANGED} to listen for 870 * user grant or denial of this access. 871 */ isNotificationPolicyAccessGranted()872 public boolean isNotificationPolicyAccessGranted() { 873 INotificationManager service = getService(); 874 try { 875 return service.isNotificationPolicyAccessGranted(mContext.getOpPackageName()); 876 } catch (RemoteException e) { 877 throw e.rethrowFromSystemServer(); 878 } 879 } 880 881 /** 882 * Checks whether the user has approved a given 883 * {@link android.service.notification.NotificationListenerService}. 884 * 885 * <p> 886 * The listener service must belong to the calling app. 887 * 888 * <p> 889 * Apps can request notification listener access by sending the user to the activity that 890 * matches the system intent action 891 * {@link android.provider.Settings#ACTION_NOTIFICATION_LISTENER_SETTINGS}. 892 */ isNotificationListenerAccessGranted(ComponentName listener)893 public boolean isNotificationListenerAccessGranted(ComponentName listener) { 894 INotificationManager service = getService(); 895 try { 896 return service.isNotificationListenerAccessGranted(listener); 897 } catch (RemoteException e) { 898 throw e.rethrowFromSystemServer(); 899 } 900 } 901 902 /** 903 * @hide 904 */ isNotificationAssistantAccessGranted(ComponentName assistant)905 public boolean isNotificationAssistantAccessGranted(ComponentName assistant) { 906 INotificationManager service = getService(); 907 try { 908 return service.isNotificationAssistantAccessGranted(assistant); 909 } catch (RemoteException e) { 910 throw e.rethrowFromSystemServer(); 911 } 912 } 913 914 /** @hide */ isNotificationPolicyAccessGrantedForPackage(String pkg)915 public boolean isNotificationPolicyAccessGrantedForPackage(String pkg) { 916 INotificationManager service = getService(); 917 try { 918 return service.isNotificationPolicyAccessGrantedForPackage(pkg); 919 } catch (RemoteException e) { 920 throw e.rethrowFromSystemServer(); 921 } 922 } 923 924 /** 925 * @hide 926 */ getEnabledNotificationListenerPackages()927 public List<String> getEnabledNotificationListenerPackages() { 928 INotificationManager service = getService(); 929 try { 930 return service.getEnabledNotificationListenerPackages(); 931 } catch (RemoteException e) { 932 throw e.rethrowFromSystemServer(); 933 } 934 } 935 936 /** 937 * Gets the current notification policy. 938 * 939 * <p> 940 */ getNotificationPolicy()941 public Policy getNotificationPolicy() { 942 INotificationManager service = getService(); 943 try { 944 return service.getNotificationPolicy(mContext.getOpPackageName()); 945 } catch (RemoteException e) { 946 throw e.rethrowFromSystemServer(); 947 } 948 } 949 950 /** 951 * Sets the current notification policy. 952 * 953 * <p> 954 * Only available if policy access is granted to this package. 955 * See {@link #isNotificationPolicyAccessGranted}. 956 * 957 * @param policy The new desired policy. 958 */ setNotificationPolicy(@onNull Policy policy)959 public void setNotificationPolicy(@NonNull Policy policy) { 960 checkRequired("policy", policy); 961 INotificationManager service = getService(); 962 try { 963 service.setNotificationPolicy(mContext.getOpPackageName(), policy); 964 } catch (RemoteException e) { 965 throw e.rethrowFromSystemServer(); 966 } 967 } 968 969 /** @hide */ setNotificationPolicyAccessGranted(String pkg, boolean granted)970 public void setNotificationPolicyAccessGranted(String pkg, boolean granted) { 971 INotificationManager service = getService(); 972 try { 973 service.setNotificationPolicyAccessGranted(pkg, granted); 974 } catch (RemoteException e) { 975 throw e.rethrowFromSystemServer(); 976 } 977 } 978 979 /** @hide */ setNotificationListenerAccessGranted(ComponentName listener, boolean granted)980 public void setNotificationListenerAccessGranted(ComponentName listener, boolean granted) { 981 INotificationManager service = getService(); 982 try { 983 service.setNotificationListenerAccessGranted(listener, granted); 984 } catch (RemoteException e) { 985 throw e.rethrowFromSystemServer(); 986 } 987 } 988 989 /** @hide */ setNotificationListenerAccessGrantedForUser(ComponentName listener, int userId, boolean granted)990 public void setNotificationListenerAccessGrantedForUser(ComponentName listener, int userId, 991 boolean granted) { 992 INotificationManager service = getService(); 993 try { 994 service.setNotificationListenerAccessGrantedForUser(listener, userId, granted); 995 } catch (RemoteException e) { 996 throw e.rethrowFromSystemServer(); 997 } 998 } 999 1000 /** @hide */ getEnabledNotificationListeners(int userId)1001 public List<ComponentName> getEnabledNotificationListeners(int userId) { 1002 INotificationManager service = getService(); 1003 try { 1004 return service.getEnabledNotificationListeners(userId); 1005 } catch (RemoteException e) { 1006 throw e.rethrowFromSystemServer(); 1007 } 1008 } 1009 1010 private Context mContext; 1011 checkRequired(String name, Object value)1012 private static void checkRequired(String name, Object value) { 1013 if (value == null) { 1014 throw new IllegalArgumentException(name + " is required"); 1015 } 1016 } 1017 1018 /** 1019 * Notification policy configuration. Represents user-preferences for notification 1020 * filtering. 1021 */ 1022 public static class Policy implements android.os.Parcelable { 1023 /** Reminder notifications are prioritized. */ 1024 public static final int PRIORITY_CATEGORY_REMINDERS = 1 << 0; 1025 /** Event notifications are prioritized. */ 1026 public static final int PRIORITY_CATEGORY_EVENTS = 1 << 1; 1027 /** Message notifications are prioritized. */ 1028 public static final int PRIORITY_CATEGORY_MESSAGES = 1 << 2; 1029 /** Calls are prioritized. */ 1030 public static final int PRIORITY_CATEGORY_CALLS = 1 << 3; 1031 /** Calls from repeat callers are prioritized. */ 1032 public static final int PRIORITY_CATEGORY_REPEAT_CALLERS = 1 << 4; 1033 /** Alarms are prioritized */ 1034 public static final int PRIORITY_CATEGORY_ALARMS = 1 << 5; 1035 /** Media, game, voice navigation are prioritized */ 1036 public static final int PRIORITY_CATEGORY_MEDIA = 1 << 6; 1037 /**System (catch-all for non-never suppressible sounds) are prioritized */ 1038 public static final int PRIORITY_CATEGORY_SYSTEM = 1 << 7; 1039 1040 /** 1041 * @hide 1042 */ 1043 public static final int[] ALL_PRIORITY_CATEGORIES = { 1044 PRIORITY_CATEGORY_ALARMS, 1045 PRIORITY_CATEGORY_MEDIA, 1046 PRIORITY_CATEGORY_SYSTEM, 1047 PRIORITY_CATEGORY_REMINDERS, 1048 PRIORITY_CATEGORY_EVENTS, 1049 PRIORITY_CATEGORY_MESSAGES, 1050 PRIORITY_CATEGORY_CALLS, 1051 PRIORITY_CATEGORY_REPEAT_CALLERS, 1052 }; 1053 1054 /** Any sender is prioritized. */ 1055 public static final int PRIORITY_SENDERS_ANY = 0; 1056 /** Saved contacts are prioritized. */ 1057 public static final int PRIORITY_SENDERS_CONTACTS = 1; 1058 /** Only starred contacts are prioritized. */ 1059 public static final int PRIORITY_SENDERS_STARRED = 2; 1060 1061 /** Notification categories to prioritize. Bitmask of PRIORITY_CATEGORY_* constants. */ 1062 public final int priorityCategories; 1063 1064 /** Notification senders to prioritize for calls. One of: 1065 * PRIORITY_SENDERS_ANY, PRIORITY_SENDERS_CONTACTS, PRIORITY_SENDERS_STARRED */ 1066 public final int priorityCallSenders; 1067 1068 /** Notification senders to prioritize for messages. One of: 1069 * PRIORITY_SENDERS_ANY, PRIORITY_SENDERS_CONTACTS, PRIORITY_SENDERS_STARRED */ 1070 public final int priorityMessageSenders; 1071 1072 /** 1073 * @hide 1074 */ 1075 public static final int SUPPRESSED_EFFECTS_UNSET = -1; 1076 1077 /** 1078 * Whether notifications suppressed by DND should not interrupt visually (e.g. with 1079 * notification lights or by turning the screen on) when the screen is off. 1080 * 1081 * @deprecated use {@link #SUPPRESSED_EFFECT_FULL_SCREEN_INTENT} and 1082 * {@link #SUPPRESSED_EFFECT_AMBIENT} and {@link #SUPPRESSED_EFFECT_LIGHTS} individually. 1083 */ 1084 @Deprecated 1085 public static final int SUPPRESSED_EFFECT_SCREEN_OFF = 1 << 0; 1086 /** 1087 * Whether notifications suppressed by DND should not interrupt visually when the screen 1088 * is on (e.g. by peeking onto the screen). 1089 * 1090 * @deprecated use {@link #SUPPRESSED_EFFECT_PEEK}. 1091 */ 1092 @Deprecated 1093 public static final int SUPPRESSED_EFFECT_SCREEN_ON = 1 << 1; 1094 1095 /** 1096 * Whether {@link Notification#fullScreenIntent full screen intents} from 1097 * notifications intercepted by DND are blocked. 1098 */ 1099 public static final int SUPPRESSED_EFFECT_FULL_SCREEN_INTENT = 1 << 2; 1100 1101 /** 1102 * Whether {@link NotificationChannel#shouldShowLights() notification lights} from 1103 * notifications intercepted by DND are blocked. 1104 */ 1105 public static final int SUPPRESSED_EFFECT_LIGHTS = 1 << 3; 1106 1107 /** 1108 * Whether notifications intercepted by DND are prevented from peeking. 1109 */ 1110 public static final int SUPPRESSED_EFFECT_PEEK = 1 << 4; 1111 1112 /** 1113 * Whether notifications intercepted by DND are prevented from appearing in the status bar, 1114 * on devices that support status bars. 1115 */ 1116 public static final int SUPPRESSED_EFFECT_STATUS_BAR = 1 << 5; 1117 1118 /** 1119 * Whether {@link NotificationChannel#canShowBadge() badges} from 1120 * notifications intercepted by DND are blocked on devices that support badging. 1121 */ 1122 public static final int SUPPRESSED_EFFECT_BADGE = 1 << 6; 1123 1124 /** 1125 * Whether notification intercepted by DND are prevented from appearing on ambient displays 1126 * on devices that support ambient display. 1127 */ 1128 public static final int SUPPRESSED_EFFECT_AMBIENT = 1 << 7; 1129 1130 /** 1131 * Whether notification intercepted by DND are prevented from appearing in notification 1132 * list views like the notification shade or lockscreen on devices that support those 1133 * views. 1134 */ 1135 public static final int SUPPRESSED_EFFECT_NOTIFICATION_LIST = 1 << 8; 1136 1137 private static final int[] ALL_SUPPRESSED_EFFECTS = { 1138 SUPPRESSED_EFFECT_SCREEN_OFF, 1139 SUPPRESSED_EFFECT_SCREEN_ON, 1140 SUPPRESSED_EFFECT_FULL_SCREEN_INTENT, 1141 SUPPRESSED_EFFECT_LIGHTS, 1142 SUPPRESSED_EFFECT_PEEK, 1143 SUPPRESSED_EFFECT_STATUS_BAR, 1144 SUPPRESSED_EFFECT_BADGE, 1145 SUPPRESSED_EFFECT_AMBIENT, 1146 SUPPRESSED_EFFECT_NOTIFICATION_LIST 1147 }; 1148 1149 private static final int[] SCREEN_OFF_SUPPRESSED_EFFECTS = { 1150 SUPPRESSED_EFFECT_SCREEN_OFF, 1151 SUPPRESSED_EFFECT_FULL_SCREEN_INTENT, 1152 SUPPRESSED_EFFECT_LIGHTS, 1153 SUPPRESSED_EFFECT_AMBIENT, 1154 }; 1155 1156 private static final int[] SCREEN_ON_SUPPRESSED_EFFECTS = { 1157 SUPPRESSED_EFFECT_SCREEN_ON, 1158 SUPPRESSED_EFFECT_PEEK, 1159 SUPPRESSED_EFFECT_STATUS_BAR, 1160 SUPPRESSED_EFFECT_BADGE, 1161 SUPPRESSED_EFFECT_NOTIFICATION_LIST 1162 }; 1163 1164 /** 1165 * Visual effects to suppress for a notification that is filtered by Do Not Disturb mode. 1166 * Bitmask of SUPPRESSED_EFFECT_* constants. 1167 */ 1168 public final int suppressedVisualEffects; 1169 1170 /** 1171 * @hide 1172 */ 1173 public static final int STATE_CHANNELS_BYPASSING_DND = 1 << 0; 1174 1175 /** 1176 * @hide 1177 */ 1178 public static final int STATE_UNSET = -1; 1179 1180 /** 1181 * Notification state information that is necessary to determine Do Not Disturb behavior. 1182 * Bitmask of STATE_* constants. 1183 * @hide 1184 */ 1185 public final int state; 1186 1187 /** 1188 * Constructs a policy for Do Not Disturb priority mode behavior. 1189 * 1190 * <p> 1191 * Apps that target API levels below {@link Build.VERSION_CODES#P} cannot 1192 * change user-designated values to allow or disallow 1193 * {@link Policy#PRIORITY_CATEGORY_ALARMS}, {@link Policy#PRIORITY_CATEGORY_SYSTEM}, and 1194 * {@link Policy#PRIORITY_CATEGORY_MEDIA} from bypassing dnd. 1195 * 1196 * @param priorityCategories bitmask of categories of notifications that can bypass DND. 1197 * @param priorityCallSenders which callers can bypass DND. 1198 * @param priorityMessageSenders which message senders can bypass DND. 1199 */ Policy(int priorityCategories, int priorityCallSenders, int priorityMessageSenders)1200 public Policy(int priorityCategories, int priorityCallSenders, int priorityMessageSenders) { 1201 this(priorityCategories, priorityCallSenders, priorityMessageSenders, 1202 SUPPRESSED_EFFECTS_UNSET, STATE_UNSET); 1203 } 1204 1205 /** 1206 * Constructs a policy for Do Not Disturb priority mode behavior. 1207 * 1208 * <p> 1209 * Apps that target API levels below {@link Build.VERSION_CODES#P} cannot 1210 * change user-designated values to allow or disallow 1211 * {@link Policy#PRIORITY_CATEGORY_ALARMS}, {@link Policy#PRIORITY_CATEGORY_SYSTEM}, and 1212 * {@link Policy#PRIORITY_CATEGORY_MEDIA} from bypassing dnd. 1213 * <p> 1214 * Additionally, apps that target API levels below {@link Build.VERSION_CODES#P} can 1215 * only modify the {@link #SUPPRESSED_EFFECT_SCREEN_ON} and 1216 * {@link #SUPPRESSED_EFFECT_SCREEN_OFF} bits of the suppressed visual effects field. 1217 * All other suppressed effects will be ignored and reconstituted from the screen on 1218 * and screen off values. 1219 * <p> 1220 * Apps that target {@link Build.VERSION_CODES#P} or above can set any 1221 * suppressed visual effects. However, if any suppressed effects > 1222 * {@link #SUPPRESSED_EFFECT_SCREEN_ON} are set, {@link #SUPPRESSED_EFFECT_SCREEN_ON} 1223 * and {@link #SUPPRESSED_EFFECT_SCREEN_OFF} will be ignored and reconstituted from 1224 * the more specific suppressed visual effect bits. Apps should migrate to targeting 1225 * specific effects instead of the deprecated {@link #SUPPRESSED_EFFECT_SCREEN_ON} and 1226 * {@link #SUPPRESSED_EFFECT_SCREEN_OFF} effects. 1227 * 1228 * @param priorityCategories bitmask of categories of notifications that can bypass DND. 1229 * @param priorityCallSenders which callers can bypass DND. 1230 * @param priorityMessageSenders which message senders can bypass DND. 1231 * @param suppressedVisualEffects which visual interruptions should be suppressed from 1232 * notifications that are filtered by DND. 1233 */ Policy(int priorityCategories, int priorityCallSenders, int priorityMessageSenders, int suppressedVisualEffects)1234 public Policy(int priorityCategories, int priorityCallSenders, int priorityMessageSenders, 1235 int suppressedVisualEffects) { 1236 this.priorityCategories = priorityCategories; 1237 this.priorityCallSenders = priorityCallSenders; 1238 this.priorityMessageSenders = priorityMessageSenders; 1239 this.suppressedVisualEffects = suppressedVisualEffects; 1240 this.state = STATE_UNSET; 1241 } 1242 1243 /** @hide */ Policy(int priorityCategories, int priorityCallSenders, int priorityMessageSenders, int suppressedVisualEffects, int state)1244 public Policy(int priorityCategories, int priorityCallSenders, int priorityMessageSenders, 1245 int suppressedVisualEffects, int state) { 1246 this.priorityCategories = priorityCategories; 1247 this.priorityCallSenders = priorityCallSenders; 1248 this.priorityMessageSenders = priorityMessageSenders; 1249 this.suppressedVisualEffects = suppressedVisualEffects; 1250 this.state = state; 1251 } 1252 1253 /** @hide */ Policy(Parcel source)1254 public Policy(Parcel source) { 1255 this(source.readInt(), source.readInt(), source.readInt(), source.readInt(), 1256 source.readInt()); 1257 } 1258 1259 @Override writeToParcel(Parcel dest, int flags)1260 public void writeToParcel(Parcel dest, int flags) { 1261 dest.writeInt(priorityCategories); 1262 dest.writeInt(priorityCallSenders); 1263 dest.writeInt(priorityMessageSenders); 1264 dest.writeInt(suppressedVisualEffects); 1265 dest.writeInt(state); 1266 } 1267 1268 @Override describeContents()1269 public int describeContents() { 1270 return 0; 1271 } 1272 1273 @Override hashCode()1274 public int hashCode() { 1275 return Objects.hash(priorityCategories, priorityCallSenders, priorityMessageSenders, 1276 suppressedVisualEffects); 1277 } 1278 1279 @Override equals(Object o)1280 public boolean equals(Object o) { 1281 if (!(o instanceof Policy)) return false; 1282 if (o == this) return true; 1283 final Policy other = (Policy) o; 1284 return other.priorityCategories == priorityCategories 1285 && other.priorityCallSenders == priorityCallSenders 1286 && other.priorityMessageSenders == priorityMessageSenders 1287 && other.suppressedVisualEffects == suppressedVisualEffects; 1288 } 1289 1290 @Override toString()1291 public String toString() { 1292 return "NotificationManager.Policy[" 1293 + "priorityCategories=" + priorityCategoriesToString(priorityCategories) 1294 + ",priorityCallSenders=" + prioritySendersToString(priorityCallSenders) 1295 + ",priorityMessageSenders=" + prioritySendersToString(priorityMessageSenders) 1296 + ",suppressedVisualEffects=" 1297 + suppressedEffectsToString(suppressedVisualEffects) 1298 + ",areChannelsBypassingDnd=" + (((state & STATE_CHANNELS_BYPASSING_DND) != 0) 1299 ? "true" : "false") 1300 + "]"; 1301 } 1302 1303 /** @hide */ writeToProto(ProtoOutputStream proto, long fieldId)1304 public void writeToProto(ProtoOutputStream proto, long fieldId) { 1305 final long pToken = proto.start(fieldId); 1306 1307 bitwiseToProtoEnum(proto, PolicyProto.PRIORITY_CATEGORIES, priorityCategories); 1308 proto.write(PolicyProto.PRIORITY_CALL_SENDER, priorityCallSenders); 1309 proto.write(PolicyProto.PRIORITY_MESSAGE_SENDER, priorityMessageSenders); 1310 bitwiseToProtoEnum( 1311 proto, PolicyProto.SUPPRESSED_VISUAL_EFFECTS, suppressedVisualEffects); 1312 1313 proto.end(pToken); 1314 } 1315 bitwiseToProtoEnum(ProtoOutputStream proto, long fieldId, int data)1316 private static void bitwiseToProtoEnum(ProtoOutputStream proto, long fieldId, int data) { 1317 for (int i = 1; data > 0; ++i, data >>>= 1) { 1318 if ((data & 1) == 1) { 1319 proto.write(fieldId, i); 1320 } 1321 } 1322 } 1323 1324 /** 1325 * @hide 1326 */ getAllSuppressedVisualEffects()1327 public static int getAllSuppressedVisualEffects() { 1328 int effects = 0; 1329 for (int i = 0; i < ALL_SUPPRESSED_EFFECTS.length; i++) { 1330 effects |= ALL_SUPPRESSED_EFFECTS[i]; 1331 } 1332 return effects; 1333 } 1334 1335 /** 1336 * @hide 1337 */ areAllVisualEffectsSuppressed(int effects)1338 public static boolean areAllVisualEffectsSuppressed(int effects) { 1339 for (int i = 0; i < ALL_SUPPRESSED_EFFECTS.length; i++) { 1340 final int effect = ALL_SUPPRESSED_EFFECTS[i]; 1341 if ((effects & effect) == 0) { 1342 return false; 1343 } 1344 } 1345 return true; 1346 } 1347 1348 /** 1349 * @hide 1350 */ areAnyScreenOffEffectsSuppressed(int effects)1351 public static boolean areAnyScreenOffEffectsSuppressed(int effects) { 1352 for (int i = 0; i < SCREEN_OFF_SUPPRESSED_EFFECTS.length; i++) { 1353 final int effect = SCREEN_OFF_SUPPRESSED_EFFECTS[i]; 1354 if ((effects & effect) != 0) { 1355 return true; 1356 } 1357 } 1358 return false; 1359 } 1360 1361 /** 1362 * @hide 1363 */ areAnyScreenOnEffectsSuppressed(int effects)1364 public static boolean areAnyScreenOnEffectsSuppressed(int effects) { 1365 for (int i = 0; i < SCREEN_ON_SUPPRESSED_EFFECTS.length; i++) { 1366 final int effect = SCREEN_ON_SUPPRESSED_EFFECTS[i]; 1367 if ((effects & effect) != 0) { 1368 return true; 1369 } 1370 } 1371 return false; 1372 } 1373 1374 /** 1375 * @hide 1376 */ toggleScreenOffEffectsSuppressed(int currentEffects, boolean suppress)1377 public static int toggleScreenOffEffectsSuppressed(int currentEffects, boolean suppress) { 1378 return toggleEffects(currentEffects, SCREEN_OFF_SUPPRESSED_EFFECTS, suppress); 1379 } 1380 1381 /** 1382 * @hide 1383 */ toggleScreenOnEffectsSuppressed(int currentEffects, boolean suppress)1384 public static int toggleScreenOnEffectsSuppressed(int currentEffects, boolean suppress) { 1385 return toggleEffects(currentEffects, SCREEN_ON_SUPPRESSED_EFFECTS, suppress); 1386 } 1387 toggleEffects(int currentEffects, int[] effects, boolean suppress)1388 private static int toggleEffects(int currentEffects, int[] effects, boolean suppress) { 1389 for (int i = 0; i < effects.length; i++) { 1390 final int effect = effects[i]; 1391 if (suppress) { 1392 currentEffects |= effect; 1393 } else { 1394 currentEffects &= ~effect; 1395 } 1396 } 1397 return currentEffects; 1398 } 1399 suppressedEffectsToString(int effects)1400 public static String suppressedEffectsToString(int effects) { 1401 if (effects <= 0) return ""; 1402 final StringBuilder sb = new StringBuilder(); 1403 for (int i = 0; i < ALL_SUPPRESSED_EFFECTS.length; i++) { 1404 final int effect = ALL_SUPPRESSED_EFFECTS[i]; 1405 if ((effects & effect) != 0) { 1406 if (sb.length() > 0) sb.append(','); 1407 sb.append(effectToString(effect)); 1408 } 1409 effects &= ~effect; 1410 } 1411 if (effects != 0) { 1412 if (sb.length() > 0) sb.append(','); 1413 sb.append("UNKNOWN_").append(effects); 1414 } 1415 return sb.toString(); 1416 } 1417 priorityCategoriesToString(int priorityCategories)1418 public static String priorityCategoriesToString(int priorityCategories) { 1419 if (priorityCategories == 0) return ""; 1420 final StringBuilder sb = new StringBuilder(); 1421 for (int i = 0; i < ALL_PRIORITY_CATEGORIES.length; i++) { 1422 final int priorityCategory = ALL_PRIORITY_CATEGORIES[i]; 1423 if ((priorityCategories & priorityCategory) != 0) { 1424 if (sb.length() > 0) sb.append(','); 1425 sb.append(priorityCategoryToString(priorityCategory)); 1426 } 1427 priorityCategories &= ~priorityCategory; 1428 } 1429 if (priorityCategories != 0) { 1430 if (sb.length() > 0) sb.append(','); 1431 sb.append("PRIORITY_CATEGORY_UNKNOWN_").append(priorityCategories); 1432 } 1433 return sb.toString(); 1434 } 1435 effectToString(int effect)1436 private static String effectToString(int effect) { 1437 switch (effect) { 1438 case SUPPRESSED_EFFECT_FULL_SCREEN_INTENT: 1439 return "SUPPRESSED_EFFECT_FULL_SCREEN_INTENT"; 1440 case SUPPRESSED_EFFECT_LIGHTS: 1441 return "SUPPRESSED_EFFECT_LIGHTS"; 1442 case SUPPRESSED_EFFECT_PEEK: 1443 return "SUPPRESSED_EFFECT_PEEK"; 1444 case SUPPRESSED_EFFECT_STATUS_BAR: 1445 return "SUPPRESSED_EFFECT_STATUS_BAR"; 1446 case SUPPRESSED_EFFECT_BADGE: 1447 return "SUPPRESSED_EFFECT_BADGE"; 1448 case SUPPRESSED_EFFECT_AMBIENT: 1449 return "SUPPRESSED_EFFECT_AMBIENT"; 1450 case SUPPRESSED_EFFECT_NOTIFICATION_LIST: 1451 return "SUPPRESSED_EFFECT_NOTIFICATION_LIST"; 1452 case SUPPRESSED_EFFECT_SCREEN_OFF: 1453 return "SUPPRESSED_EFFECT_SCREEN_OFF"; 1454 case SUPPRESSED_EFFECT_SCREEN_ON: 1455 return "SUPPRESSED_EFFECT_SCREEN_ON"; 1456 case SUPPRESSED_EFFECTS_UNSET: 1457 return "SUPPRESSED_EFFECTS_UNSET"; 1458 default: return "UNKNOWN_" + effect; 1459 } 1460 } 1461 priorityCategoryToString(int priorityCategory)1462 private static String priorityCategoryToString(int priorityCategory) { 1463 switch (priorityCategory) { 1464 case PRIORITY_CATEGORY_REMINDERS: return "PRIORITY_CATEGORY_REMINDERS"; 1465 case PRIORITY_CATEGORY_EVENTS: return "PRIORITY_CATEGORY_EVENTS"; 1466 case PRIORITY_CATEGORY_MESSAGES: return "PRIORITY_CATEGORY_MESSAGES"; 1467 case PRIORITY_CATEGORY_CALLS: return "PRIORITY_CATEGORY_CALLS"; 1468 case PRIORITY_CATEGORY_REPEAT_CALLERS: return "PRIORITY_CATEGORY_REPEAT_CALLERS"; 1469 case PRIORITY_CATEGORY_ALARMS: return "PRIORITY_CATEGORY_ALARMS"; 1470 case PRIORITY_CATEGORY_MEDIA: return "PRIORITY_CATEGORY_MEDIA"; 1471 case PRIORITY_CATEGORY_SYSTEM: return "PRIORITY_CATEGORY_SYSTEM"; 1472 default: return "PRIORITY_CATEGORY_UNKNOWN_" + priorityCategory; 1473 } 1474 } 1475 prioritySendersToString(int prioritySenders)1476 public static String prioritySendersToString(int prioritySenders) { 1477 switch (prioritySenders) { 1478 case PRIORITY_SENDERS_ANY: return "PRIORITY_SENDERS_ANY"; 1479 case PRIORITY_SENDERS_CONTACTS: return "PRIORITY_SENDERS_CONTACTS"; 1480 case PRIORITY_SENDERS_STARRED: return "PRIORITY_SENDERS_STARRED"; 1481 default: return "PRIORITY_SENDERS_UNKNOWN_" + prioritySenders; 1482 } 1483 } 1484 1485 public static final Parcelable.Creator<Policy> CREATOR = new Parcelable.Creator<Policy>() { 1486 @Override 1487 public Policy createFromParcel(Parcel in) { 1488 return new Policy(in); 1489 } 1490 1491 @Override 1492 public Policy[] newArray(int size) { 1493 return new Policy[size]; 1494 } 1495 }; 1496 } 1497 1498 /** 1499 * Recover a list of active notifications: ones that have been posted by the calling app that 1500 * have not yet been dismissed by the user or {@link #cancel(String, int)}ed by the app. 1501 * 1502 * Each notification is embedded in a {@link StatusBarNotification} object, including the 1503 * original <code>tag</code> and <code>id</code> supplied to 1504 * {@link #notify(String, int, Notification) notify()} 1505 * (via {@link StatusBarNotification#getTag() getTag()} and 1506 * {@link StatusBarNotification#getId() getId()}) as well as a copy of the original 1507 * {@link Notification} object (via {@link StatusBarNotification#getNotification()}). 1508 * 1509 * @return An array of {@link StatusBarNotification}. 1510 */ getActiveNotifications()1511 public StatusBarNotification[] getActiveNotifications() { 1512 final INotificationManager service = getService(); 1513 final String pkg = mContext.getPackageName(); 1514 try { 1515 final ParceledListSlice<StatusBarNotification> parceledList 1516 = service.getAppActiveNotifications(pkg, mContext.getUserId()); 1517 final List<StatusBarNotification> list = parceledList.getList(); 1518 return list.toArray(new StatusBarNotification[list.size()]); 1519 } catch (RemoteException e) { 1520 throw e.rethrowFromSystemServer(); 1521 } 1522 } 1523 1524 /** 1525 * Gets the current notification interruption filter. 1526 * <p> 1527 * The interruption filter defines which notifications are allowed to 1528 * interrupt the user (e.g. via sound & vibration) and is applied 1529 * globally. 1530 */ getCurrentInterruptionFilter()1531 public final @InterruptionFilter int getCurrentInterruptionFilter() { 1532 final INotificationManager service = getService(); 1533 try { 1534 return zenModeToInterruptionFilter(service.getZenMode()); 1535 } catch (RemoteException e) { 1536 throw e.rethrowFromSystemServer(); 1537 } 1538 } 1539 1540 /** 1541 * Sets the current notification interruption filter. 1542 * <p> 1543 * The interruption filter defines which notifications are allowed to 1544 * interrupt the user (e.g. via sound & vibration) and is applied 1545 * globally. 1546 * <p> 1547 * Only available if policy access is granted to this package. See 1548 * {@link #isNotificationPolicyAccessGranted}. 1549 */ setInterruptionFilter(@nterruptionFilter int interruptionFilter)1550 public final void setInterruptionFilter(@InterruptionFilter int interruptionFilter) { 1551 final INotificationManager service = getService(); 1552 try { 1553 service.setInterruptionFilter(mContext.getOpPackageName(), interruptionFilter); 1554 } catch (RemoteException e) { 1555 throw e.rethrowFromSystemServer(); 1556 } 1557 } 1558 1559 /** @hide */ zenModeToInterruptionFilter(int zen)1560 public static int zenModeToInterruptionFilter(int zen) { 1561 switch (zen) { 1562 case Global.ZEN_MODE_OFF: return INTERRUPTION_FILTER_ALL; 1563 case Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS: return INTERRUPTION_FILTER_PRIORITY; 1564 case Global.ZEN_MODE_ALARMS: return INTERRUPTION_FILTER_ALARMS; 1565 case Global.ZEN_MODE_NO_INTERRUPTIONS: return INTERRUPTION_FILTER_NONE; 1566 default: return INTERRUPTION_FILTER_UNKNOWN; 1567 } 1568 } 1569 1570 /** @hide */ zenModeFromInterruptionFilter(int interruptionFilter, int defValue)1571 public static int zenModeFromInterruptionFilter(int interruptionFilter, int defValue) { 1572 switch (interruptionFilter) { 1573 case INTERRUPTION_FILTER_ALL: return Global.ZEN_MODE_OFF; 1574 case INTERRUPTION_FILTER_PRIORITY: return Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS; 1575 case INTERRUPTION_FILTER_ALARMS: return Global.ZEN_MODE_ALARMS; 1576 case INTERRUPTION_FILTER_NONE: return Global.ZEN_MODE_NO_INTERRUPTIONS; 1577 default: return defValue; 1578 } 1579 } 1580 1581 } 1582