NotificationManager.java revision 86d076f9d3ef7da272cb840ae9ad8bf78e435525
1/* 2 * Copyright (C) 2007 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package android.app; 18 19import android.annotation.IntDef; 20import android.annotation.NonNull; 21import android.annotation.SdkConstant; 22import android.annotation.SystemService; 23import android.annotation.TestApi; 24import android.app.Notification.Builder; 25import android.content.ComponentName; 26import android.content.Context; 27import android.content.Intent; 28import android.content.pm.ParceledListSlice; 29import android.graphics.drawable.Icon; 30import android.net.Uri; 31import android.os.Build; 32import android.os.Bundle; 33import android.os.Handler; 34import android.os.IBinder; 35import android.os.Parcel; 36import android.os.Parcelable; 37import android.os.RemoteException; 38import android.os.ServiceManager; 39import android.os.StrictMode; 40import android.os.UserHandle; 41import android.provider.Settings.Global; 42import android.service.notification.StatusBarNotification; 43import android.service.notification.ZenModeConfig; 44import android.util.Log; 45import android.util.proto.ProtoOutputStream; 46 47import java.lang.annotation.Retention; 48import java.lang.annotation.RetentionPolicy; 49import java.util.Arrays; 50import java.util.HashMap; 51import java.util.List; 52import java.util.Map; 53import 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) 92public 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 */ 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 324 /*package*/ NotificationManager(Context context, Handler handler) 325 { 326 mContext = context; 327 } 328 329 /** {@hide} */ 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 */ 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 */ 368 public void notify(String tag, int id, Notification notification) 369 { 370 notifyAsUser(tag, id, notification, mContext.getUser()); 371 } 372 373 /** 374 * @hide 375 */ 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 try { 404 service.enqueueNotificationWithTag(pkg, mContext.getOpPackageName(), tag, id, 405 copy, user.getIdentifier()); 406 } catch (RemoteException e) { 407 throw e.rethrowFromSystemServer(); 408 } 409 } 410 411 private void fixLegacySmallIcon(Notification n, String pkg) { 412 if (n.getSmallIcon() == null && n.icon != 0) { 413 n.setSmallIcon(Icon.createWithResource(pkg, n.icon)); 414 } 415 } 416 417 /** 418 * Cancel a previously shown notification. If it's transient, the view 419 * will be hidden. If it's persistent, it will be removed from the status 420 * bar. 421 */ 422 public void cancel(int id) 423 { 424 cancel(null, id); 425 } 426 427 /** 428 * Cancel a previously shown notification. If it's transient, the view 429 * will be hidden. If it's persistent, it will be removed from the status 430 * bar. 431 */ 432 public void cancel(String tag, int id) 433 { 434 cancelAsUser(tag, id, mContext.getUser()); 435 } 436 437 /** 438 * @hide 439 */ 440 public void cancelAsUser(String tag, int id, UserHandle user) 441 { 442 INotificationManager service = getService(); 443 String pkg = mContext.getPackageName(); 444 if (localLOGV) Log.v(TAG, pkg + ": cancel(" + id + ")"); 445 try { 446 service.cancelNotificationWithTag(pkg, tag, id, user.getIdentifier()); 447 } catch (RemoteException e) { 448 throw e.rethrowFromSystemServer(); 449 } 450 } 451 452 /** 453 * Cancel all previously shown notifications. See {@link #cancel} for the 454 * detailed behavior. 455 */ 456 public void cancelAll() 457 { 458 INotificationManager service = getService(); 459 String pkg = mContext.getPackageName(); 460 if (localLOGV) Log.v(TAG, pkg + ": cancelAll()"); 461 try { 462 service.cancelAllNotifications(pkg, mContext.getUserId()); 463 } catch (RemoteException e) { 464 throw e.rethrowFromSystemServer(); 465 } 466 } 467 468 /** 469 * Creates a group container for {@link NotificationChannel} objects. 470 * 471 * This can be used to rename an existing group. 472 * <p> 473 * Group information is only used for presentation, not for behavior. Groups are optional 474 * for channels, and you can have a mix of channels that belong to groups and channels 475 * that do not. 476 * </p> 477 * <p> 478 * For example, if your application supports multiple accounts, and those accounts will 479 * have similar channels, you can create a group for each account with account specific 480 * labels instead of appending account information to each channel's label. 481 * </p> 482 * 483 * @param group The group to create 484 */ 485 public void createNotificationChannelGroup(@NonNull NotificationChannelGroup group) { 486 createNotificationChannelGroups(Arrays.asList(group)); 487 } 488 489 /** 490 * Creates multiple notification channel groups. 491 * 492 * @param groups The list of groups to create 493 */ 494 public void createNotificationChannelGroups(@NonNull List<NotificationChannelGroup> groups) { 495 INotificationManager service = getService(); 496 try { 497 service.createNotificationChannelGroups(mContext.getPackageName(), 498 new ParceledListSlice(groups)); 499 } catch (RemoteException e) { 500 throw e.rethrowFromSystemServer(); 501 } 502 } 503 504 /** 505 * Creates a notification channel that notifications can be posted to. 506 * 507 * This can also be used to restore a deleted channel and to update an existing channel's 508 * name, description, group, and/or importance. 509 * 510 * <p>The name and description should only be changed if the locale changes 511 * or in response to the user renaming this channel. For example, if a user has a channel 512 * named 'John Doe' that represents messages from a 'John Doe', and 'John Doe' changes his name 513 * to 'John Smith,' the channel can be renamed to match. 514 * 515 * <p>The importance of an existing channel will only be changed if the new importance is lower 516 * than the current value and the user has not altered any settings on this channel. 517 * 518 * <p>The group an existing channel will only be changed if the channel does not already 519 * belong to a group. 520 * 521 * All other fields are ignored for channels that already exist. 522 * 523 * @param channel the channel to create. Note that the created channel may differ from this 524 * value. If the provided channel is malformed, a RemoteException will be 525 * thrown. 526 */ 527 public void createNotificationChannel(@NonNull NotificationChannel channel) { 528 createNotificationChannels(Arrays.asList(channel)); 529 } 530 531 /** 532 * Creates multiple notification channels that different notifications can be posted to. See 533 * {@link #createNotificationChannel(NotificationChannel)}. 534 * 535 * @param channels the list of channels to attempt to create. 536 */ 537 public void createNotificationChannels(@NonNull List<NotificationChannel> channels) { 538 INotificationManager service = getService(); 539 try { 540 service.createNotificationChannels(mContext.getPackageName(), 541 new ParceledListSlice(channels)); 542 } catch (RemoteException e) { 543 throw e.rethrowFromSystemServer(); 544 } 545 } 546 547 /** 548 * Returns the notification channel settings for a given channel id. 549 * 550 * The channel must belong to your package, or it will not be returned. 551 */ 552 public NotificationChannel getNotificationChannel(String channelId) { 553 INotificationManager service = getService(); 554 try { 555 return service.getNotificationChannel(mContext.getPackageName(), channelId); 556 } catch (RemoteException e) { 557 throw e.rethrowFromSystemServer(); 558 } 559 } 560 561 /** 562 * Returns all notification channels belonging to the calling package. 563 */ 564 public List<NotificationChannel> getNotificationChannels() { 565 INotificationManager service = getService(); 566 try { 567 return service.getNotificationChannels(mContext.getPackageName()).getList(); 568 } catch (RemoteException e) { 569 throw e.rethrowFromSystemServer(); 570 } 571 } 572 573 /** 574 * Deletes the given notification channel. 575 * 576 * <p>If you {@link #createNotificationChannel(NotificationChannel) create} a new channel with 577 * this same id, the deleted channel will be un-deleted with all of the same settings it 578 * had before it was deleted. 579 */ 580 public void deleteNotificationChannel(String channelId) { 581 INotificationManager service = getService(); 582 try { 583 service.deleteNotificationChannel(mContext.getPackageName(), channelId); 584 } catch (RemoteException e) { 585 throw e.rethrowFromSystemServer(); 586 } 587 } 588 589 /** 590 * Returns the notification channel group settings for a given channel group id. 591 * 592 * The channel group must belong to your package, or null will be returned. 593 */ 594 public NotificationChannelGroup getNotificationChannelGroup(String channelGroupId) { 595 INotificationManager service = getService(); 596 try { 597 return service.getNotificationChannelGroup(mContext.getPackageName(), channelGroupId); 598 } catch (RemoteException e) { 599 throw e.rethrowFromSystemServer(); 600 } 601 } 602 603 /** 604 * Returns all notification channel groups belonging to the calling app. 605 */ 606 public List<NotificationChannelGroup> getNotificationChannelGroups() { 607 INotificationManager service = getService(); 608 try { 609 return service.getNotificationChannelGroups(mContext.getPackageName()).getList(); 610 } catch (RemoteException e) { 611 throw e.rethrowFromSystemServer(); 612 } 613 } 614 615 /** 616 * Deletes the given notification channel group, and all notification channels that 617 * belong to it. 618 */ 619 public void deleteNotificationChannelGroup(String groupId) { 620 INotificationManager service = getService(); 621 try { 622 service.deleteNotificationChannelGroup(mContext.getPackageName(), groupId); 623 } catch (RemoteException e) { 624 throw e.rethrowFromSystemServer(); 625 } 626 } 627 628 /** 629 * @hide 630 */ 631 @TestApi 632 public ComponentName getEffectsSuppressor() { 633 INotificationManager service = getService(); 634 try { 635 return service.getEffectsSuppressor(); 636 } catch (RemoteException e) { 637 throw e.rethrowFromSystemServer(); 638 } 639 } 640 641 /** 642 * @hide 643 */ 644 public boolean matchesCallFilter(Bundle extras) { 645 INotificationManager service = getService(); 646 try { 647 return service.matchesCallFilter(extras); 648 } catch (RemoteException e) { 649 throw e.rethrowFromSystemServer(); 650 } 651 } 652 653 /** 654 * @hide 655 */ 656 public boolean isSystemConditionProviderEnabled(String path) { 657 INotificationManager service = getService(); 658 try { 659 return service.isSystemConditionProviderEnabled(path); 660 } catch (RemoteException e) { 661 throw e.rethrowFromSystemServer(); 662 } 663 } 664 665 /** 666 * @hide 667 */ 668 public void setZenMode(int mode, Uri conditionId, String reason) { 669 INotificationManager service = getService(); 670 try { 671 service.setZenMode(mode, conditionId, reason); 672 } catch (RemoteException e) { 673 throw e.rethrowFromSystemServer(); 674 } 675 } 676 677 /** 678 * @hide 679 */ 680 public int getZenMode() { 681 INotificationManager service = getService(); 682 try { 683 return service.getZenMode(); 684 } catch (RemoteException e) { 685 throw e.rethrowFromSystemServer(); 686 } 687 } 688 689 /** 690 * @hide 691 */ 692 public ZenModeConfig getZenModeConfig() { 693 INotificationManager service = getService(); 694 try { 695 return service.getZenModeConfig(); 696 } catch (RemoteException e) { 697 throw e.rethrowFromSystemServer(); 698 } 699 } 700 701 /** 702 * @hide 703 */ 704 public int getRuleInstanceCount(ComponentName owner) { 705 INotificationManager service = getService(); 706 try { 707 return service.getRuleInstanceCount(owner); 708 } catch (RemoteException e) { 709 throw e.rethrowFromSystemServer(); 710 } 711 } 712 713 /** 714 * Returns AutomaticZenRules owned by the caller. 715 * 716 * <p> 717 * Throws a SecurityException if policy access is granted to this package. 718 * See {@link #isNotificationPolicyAccessGranted}. 719 */ 720 public Map<String, AutomaticZenRule> getAutomaticZenRules() { 721 INotificationManager service = getService(); 722 try { 723 List<ZenModeConfig.ZenRule> rules = service.getZenRules(); 724 Map<String, AutomaticZenRule> ruleMap = new HashMap<>(); 725 for (ZenModeConfig.ZenRule rule : rules) { 726 ruleMap.put(rule.id, new AutomaticZenRule(rule.name, rule.component, 727 rule.conditionId, zenModeToInterruptionFilter(rule.zenMode), rule.enabled, 728 rule.creationTime)); 729 } 730 return ruleMap; 731 } catch (RemoteException e) { 732 throw e.rethrowFromSystemServer(); 733 } 734 } 735 736 /** 737 * Returns the AutomaticZenRule with the given id, if it exists and the caller has access. 738 * 739 * <p> 740 * Throws a SecurityException if policy access is granted to this package. 741 * See {@link #isNotificationPolicyAccessGranted}. 742 * 743 * <p> 744 * Returns null if there are no zen rules that match the given id, or if the calling package 745 * doesn't own the matching rule. See {@link AutomaticZenRule#getOwner}. 746 */ 747 public AutomaticZenRule getAutomaticZenRule(String id) { 748 INotificationManager service = getService(); 749 try { 750 return service.getAutomaticZenRule(id); 751 } catch (RemoteException e) { 752 throw e.rethrowFromSystemServer(); 753 } 754 } 755 756 /** 757 * Creates the given zen rule. 758 * 759 * <p> 760 * Throws a SecurityException if policy access is granted to this package. 761 * See {@link #isNotificationPolicyAccessGranted}. 762 * 763 * @param automaticZenRule the rule to create. 764 * @return The id of the newly created rule; null if the rule could not be created. 765 */ 766 public String addAutomaticZenRule(AutomaticZenRule automaticZenRule) { 767 INotificationManager service = getService(); 768 try { 769 return service.addAutomaticZenRule(automaticZenRule); 770 } catch (RemoteException e) { 771 throw e.rethrowFromSystemServer(); 772 } 773 } 774 775 /** 776 * Updates the given zen rule. 777 * 778 * <p> 779 * Throws a SecurityException if policy access is granted to this package. 780 * See {@link #isNotificationPolicyAccessGranted}. 781 * 782 * <p> 783 * Callers can only update rules that they own. See {@link AutomaticZenRule#getOwner}. 784 * @param id The id of the rule to update 785 * @param automaticZenRule the rule to update. 786 * @return Whether the rule was successfully updated. 787 */ 788 public boolean updateAutomaticZenRule(String id, AutomaticZenRule automaticZenRule) { 789 INotificationManager service = getService(); 790 try { 791 return service.updateAutomaticZenRule(id, automaticZenRule); 792 } catch (RemoteException e) { 793 throw e.rethrowFromSystemServer(); 794 } 795 } 796 797 /** 798 * Deletes the automatic zen rule with the given id. 799 * 800 * <p> 801 * Throws a SecurityException if policy access is granted to this package. 802 * See {@link #isNotificationPolicyAccessGranted}. 803 * 804 * <p> 805 * Callers can only delete rules that they own. See {@link AutomaticZenRule#getOwner}. 806 * @param id the id of the rule to delete. 807 * @return Whether the rule was successfully deleted. 808 */ 809 public boolean removeAutomaticZenRule(String id) { 810 INotificationManager service = getService(); 811 try { 812 return service.removeAutomaticZenRule(id); 813 } catch (RemoteException e) { 814 throw e.rethrowFromSystemServer(); 815 } 816 } 817 818 /** 819 * Deletes all automatic zen rules owned by the given package. 820 * 821 * @hide 822 */ 823 public boolean removeAutomaticZenRules(String packageName) { 824 INotificationManager service = getService(); 825 try { 826 return service.removeAutomaticZenRules(packageName); 827 } catch (RemoteException e) { 828 throw e.rethrowFromSystemServer(); 829 } 830 } 831 832 /** 833 * Returns the user specified importance for notifications from the calling 834 * package. 835 */ 836 public @Importance int getImportance() { 837 INotificationManager service = getService(); 838 try { 839 return service.getPackageImportance(mContext.getPackageName()); 840 } catch (RemoteException e) { 841 throw e.rethrowFromSystemServer(); 842 } 843 } 844 845 /** 846 * Returns whether notifications from the calling package are blocked. 847 */ 848 public boolean areNotificationsEnabled() { 849 INotificationManager service = getService(); 850 try { 851 return service.areNotificationsEnabled(mContext.getPackageName()); 852 } catch (RemoteException e) { 853 throw e.rethrowFromSystemServer(); 854 } 855 } 856 857 /** 858 * Checks the ability to modify notification do not disturb policy for the calling package. 859 * 860 * <p> 861 * Returns true if the calling package can modify notification policy. 862 * 863 * <p> 864 * Apps can request policy access by sending the user to the activity that matches the system 865 * intent action {@link android.provider.Settings#ACTION_NOTIFICATION_POLICY_ACCESS_SETTINGS}. 866 * 867 * <p> 868 * Use {@link #ACTION_NOTIFICATION_POLICY_ACCESS_GRANTED_CHANGED} to listen for 869 * user grant or denial of this access. 870 */ 871 public boolean isNotificationPolicyAccessGranted() { 872 INotificationManager service = getService(); 873 try { 874 return service.isNotificationPolicyAccessGranted(mContext.getOpPackageName()); 875 } catch (RemoteException e) { 876 throw e.rethrowFromSystemServer(); 877 } 878 } 879 880 /** 881 * Checks whether the user has approved a given 882 * {@link android.service.notification.NotificationListenerService}. 883 * 884 * <p> 885 * The listener service must belong to the calling app. 886 * 887 * <p> 888 * Apps can request notification listener access by sending the user to the activity that 889 * matches the system intent action 890 * {@link android.provider.Settings#ACTION_NOTIFICATION_LISTENER_SETTINGS}. 891 */ 892 public boolean isNotificationListenerAccessGranted(ComponentName listener) { 893 INotificationManager service = getService(); 894 try { 895 return service.isNotificationListenerAccessGranted(listener); 896 } catch (RemoteException e) { 897 throw e.rethrowFromSystemServer(); 898 } 899 } 900 901 /** 902 * @hide 903 */ 904 public boolean isNotificationAssistantAccessGranted(ComponentName assistant) { 905 INotificationManager service = getService(); 906 try { 907 return service.isNotificationAssistantAccessGranted(assistant); 908 } catch (RemoteException e) { 909 throw e.rethrowFromSystemServer(); 910 } 911 } 912 913 /** @hide */ 914 public boolean isNotificationPolicyAccessGrantedForPackage(String pkg) { 915 INotificationManager service = getService(); 916 try { 917 return service.isNotificationPolicyAccessGrantedForPackage(pkg); 918 } catch (RemoteException e) { 919 throw e.rethrowFromSystemServer(); 920 } 921 } 922 923 /** 924 * @hide 925 */ 926 public List<String> getEnabledNotificationListenerPackages() { 927 INotificationManager service = getService(); 928 try { 929 return service.getEnabledNotificationListenerPackages(); 930 } catch (RemoteException e) { 931 throw e.rethrowFromSystemServer(); 932 } 933 } 934 935 /** 936 * Gets the current notification policy. 937 * 938 * <p> 939 */ 940 public Policy getNotificationPolicy() { 941 INotificationManager service = getService(); 942 try { 943 return service.getNotificationPolicy(mContext.getOpPackageName()); 944 } catch (RemoteException e) { 945 throw e.rethrowFromSystemServer(); 946 } 947 } 948 949 /** 950 * Sets the current notification policy. 951 * 952 * <p> 953 * Only available if policy access is granted to this package. 954 * See {@link #isNotificationPolicyAccessGranted}. 955 * 956 * @param policy The new desired policy. 957 */ 958 public void setNotificationPolicy(@NonNull Policy policy) { 959 checkRequired("policy", policy); 960 INotificationManager service = getService(); 961 try { 962 service.setNotificationPolicy(mContext.getOpPackageName(), policy); 963 } catch (RemoteException e) { 964 throw e.rethrowFromSystemServer(); 965 } 966 } 967 968 /** @hide */ 969 public void setNotificationPolicyAccessGranted(String pkg, boolean granted) { 970 INotificationManager service = getService(); 971 try { 972 service.setNotificationPolicyAccessGranted(pkg, granted); 973 } catch (RemoteException e) { 974 throw e.rethrowFromSystemServer(); 975 } 976 } 977 978 /** @hide */ 979 public void setNotificationListenerAccessGranted(ComponentName listener, boolean granted) { 980 INotificationManager service = getService(); 981 try { 982 service.setNotificationListenerAccessGranted(listener, granted); 983 } catch (RemoteException e) { 984 throw e.rethrowFromSystemServer(); 985 } 986 } 987 988 /** @hide */ 989 public void setNotificationListenerAccessGrantedForUser(ComponentName listener, int userId, 990 boolean granted) { 991 INotificationManager service = getService(); 992 try { 993 service.setNotificationListenerAccessGrantedForUser(listener, userId, granted); 994 } catch (RemoteException e) { 995 throw e.rethrowFromSystemServer(); 996 } 997 } 998 999 /** @hide */ 1000 public List<ComponentName> getEnabledNotificationListeners(int userId) { 1001 INotificationManager service = getService(); 1002 try { 1003 return service.getEnabledNotificationListeners(userId); 1004 } catch (RemoteException e) { 1005 throw e.rethrowFromSystemServer(); 1006 } 1007 } 1008 1009 private Context mContext; 1010 1011 private static void checkRequired(String name, Object value) { 1012 if (value == null) { 1013 throw new IllegalArgumentException(name + " is required"); 1014 } 1015 } 1016 1017 /** 1018 * Notification policy configuration. Represents user-preferences for notification 1019 * filtering. 1020 */ 1021 public static class Policy implements android.os.Parcelable { 1022 /** Reminder notifications are prioritized. */ 1023 public static final int PRIORITY_CATEGORY_REMINDERS = 1 << 0; 1024 /** Event notifications are prioritized. */ 1025 public static final int PRIORITY_CATEGORY_EVENTS = 1 << 1; 1026 /** Message notifications are prioritized. */ 1027 public static final int PRIORITY_CATEGORY_MESSAGES = 1 << 2; 1028 /** Calls are prioritized. */ 1029 public static final int PRIORITY_CATEGORY_CALLS = 1 << 3; 1030 /** Calls from repeat callers are prioritized. */ 1031 public static final int PRIORITY_CATEGORY_REPEAT_CALLERS = 1 << 4; 1032 /** Alarms are prioritized */ 1033 public static final int PRIORITY_CATEGORY_ALARMS = 1 << 5; 1034 /** Media, game, voice navigation are prioritized */ 1035 public static final int PRIORITY_CATEGORY_MEDIA = 1 << 6; 1036 /**System (catch-all for non-never suppressible sounds) are prioritized */ 1037 public static final int PRIORITY_CATEGORY_SYSTEM = 1 << 7; 1038 1039 /** 1040 * @hide 1041 */ 1042 public static final int[] ALL_PRIORITY_CATEGORIES = { 1043 PRIORITY_CATEGORY_ALARMS, 1044 PRIORITY_CATEGORY_MEDIA, 1045 PRIORITY_CATEGORY_SYSTEM, 1046 PRIORITY_CATEGORY_REMINDERS, 1047 PRIORITY_CATEGORY_EVENTS, 1048 PRIORITY_CATEGORY_MESSAGES, 1049 PRIORITY_CATEGORY_CALLS, 1050 PRIORITY_CATEGORY_REPEAT_CALLERS, 1051 }; 1052 1053 /** Any sender is prioritized. */ 1054 public static final int PRIORITY_SENDERS_ANY = 0; 1055 /** Saved contacts are prioritized. */ 1056 public static final int PRIORITY_SENDERS_CONTACTS = 1; 1057 /** Only starred contacts are prioritized. */ 1058 public static final int PRIORITY_SENDERS_STARRED = 2; 1059 1060 /** Notification categories to prioritize. Bitmask of PRIORITY_CATEGORY_* constants. */ 1061 public final int priorityCategories; 1062 1063 /** Notification senders to prioritize for calls. One of: 1064 * PRIORITY_SENDERS_ANY, PRIORITY_SENDERS_CONTACTS, PRIORITY_SENDERS_STARRED */ 1065 public final int priorityCallSenders; 1066 1067 /** Notification senders to prioritize for messages. One of: 1068 * PRIORITY_SENDERS_ANY, PRIORITY_SENDERS_CONTACTS, PRIORITY_SENDERS_STARRED */ 1069 public final int priorityMessageSenders; 1070 1071 /** 1072 * @hide 1073 */ 1074 public static final int SUPPRESSED_EFFECTS_UNSET = -1; 1075 1076 /** 1077 * Whether notifications suppressed by DND should not interrupt visually (e.g. with 1078 * notification lights or by turning the screen on) when the screen is off. 1079 * 1080 * @deprecated use {@link #SUPPRESSED_EFFECT_FULL_SCREEN_INTENT} and 1081 * {@link #SUPPRESSED_EFFECT_AMBIENT} and {@link #SUPPRESSED_EFFECT_LIGHTS} individually. 1082 */ 1083 @Deprecated 1084 public static final int SUPPRESSED_EFFECT_SCREEN_OFF = 1 << 0; 1085 /** 1086 * Whether notifications suppressed by DND should not interrupt visually when the screen 1087 * is on (e.g. by peeking onto the screen). 1088 * 1089 * @deprecated use {@link #SUPPRESSED_EFFECT_PEEK}. 1090 */ 1091 @Deprecated 1092 public static final int SUPPRESSED_EFFECT_SCREEN_ON = 1 << 1; 1093 1094 /** 1095 * Whether {@link Notification#fullScreenIntent full screen intents} from 1096 * notifications intercepted by DND are blocked. 1097 */ 1098 public static final int SUPPRESSED_EFFECT_FULL_SCREEN_INTENT = 1 << 2; 1099 1100 /** 1101 * Whether {@link NotificationChannel#shouldShowLights() notification lights} from 1102 * notifications intercepted by DND are blocked. 1103 */ 1104 public static final int SUPPRESSED_EFFECT_LIGHTS = 1 << 3; 1105 1106 /** 1107 * Whether notifications intercepted by DND are prevented from peeking. 1108 */ 1109 public static final int SUPPRESSED_EFFECT_PEEK = 1 << 4; 1110 1111 /** 1112 * Whether notifications intercepted by DND are prevented from appearing in the status bar, 1113 * on devices that support status bars. 1114 */ 1115 public static final int SUPPRESSED_EFFECT_STATUS_BAR = 1 << 5; 1116 1117 /** 1118 * Whether {@link NotificationChannel#canShowBadge() badges} from 1119 * notifications intercepted by DND are blocked on devices that support badging. 1120 */ 1121 public static final int SUPPRESSED_EFFECT_BADGE = 1 << 6; 1122 1123 /** 1124 * Whether notification intercepted by DND are prevented from appearing on ambient displays 1125 * on devices that support ambient display. 1126 */ 1127 public static final int SUPPRESSED_EFFECT_AMBIENT = 1 << 7; 1128 1129 /** 1130 * Whether notification intercepted by DND are prevented from appearing in notification 1131 * list views like the notification shade or lockscreen on devices that support those 1132 * views. 1133 */ 1134 public static final int SUPPRESSED_EFFECT_NOTIFICATION_LIST = 1 << 8; 1135 1136 private static final int[] ALL_SUPPRESSED_EFFECTS = { 1137 SUPPRESSED_EFFECT_SCREEN_OFF, 1138 SUPPRESSED_EFFECT_SCREEN_ON, 1139 SUPPRESSED_EFFECT_FULL_SCREEN_INTENT, 1140 SUPPRESSED_EFFECT_LIGHTS, 1141 SUPPRESSED_EFFECT_PEEK, 1142 SUPPRESSED_EFFECT_STATUS_BAR, 1143 SUPPRESSED_EFFECT_BADGE, 1144 SUPPRESSED_EFFECT_AMBIENT, 1145 SUPPRESSED_EFFECT_NOTIFICATION_LIST 1146 }; 1147 1148 private static final int[] SCREEN_OFF_SUPPRESSED_EFFECTS = { 1149 SUPPRESSED_EFFECT_SCREEN_OFF, 1150 SUPPRESSED_EFFECT_FULL_SCREEN_INTENT, 1151 SUPPRESSED_EFFECT_LIGHTS, 1152 SUPPRESSED_EFFECT_AMBIENT, 1153 }; 1154 1155 private static final int[] SCREEN_ON_SUPPRESSED_EFFECTS = { 1156 SUPPRESSED_EFFECT_SCREEN_ON, 1157 SUPPRESSED_EFFECT_PEEK, 1158 SUPPRESSED_EFFECT_STATUS_BAR, 1159 SUPPRESSED_EFFECT_BADGE, 1160 SUPPRESSED_EFFECT_NOTIFICATION_LIST 1161 }; 1162 1163 /** 1164 * Visual effects to suppress for a notification that is filtered by Do Not Disturb mode. 1165 * Bitmask of SUPPRESSED_EFFECT_* constants. 1166 */ 1167 public final int suppressedVisualEffects; 1168 1169 /** 1170 * @hide 1171 */ 1172 public static final int STATE_CHANNELS_BYPASSING_DND = 1 << 0; 1173 1174 /** 1175 * @hide 1176 */ 1177 public static final int STATE_UNSET = -1; 1178 1179 /** 1180 * Notification state information that is necessary to determine Do Not Disturb behavior. 1181 * Bitmask of STATE_* constants. 1182 * @hide 1183 */ 1184 public final int state; 1185 1186 /** 1187 * Constructs a policy for Do Not Disturb priority mode behavior. 1188 * 1189 * <p> 1190 * Apps that target API levels below {@link Build.VERSION_CODES#P} cannot 1191 * change user-designated values to allow or disallow 1192 * {@link Policy#PRIORITY_CATEGORY_ALARMS}, {@link Policy#PRIORITY_CATEGORY_SYSTEM}, and 1193 * {@link Policy#PRIORITY_CATEGORY_MEDIA} from bypassing dnd. 1194 * 1195 * @param priorityCategories bitmask of categories of notifications that can bypass DND. 1196 * @param priorityCallSenders which callers can bypass DND. 1197 * @param priorityMessageSenders which message senders can bypass DND. 1198 */ 1199 public Policy(int priorityCategories, int priorityCallSenders, int priorityMessageSenders) { 1200 this(priorityCategories, priorityCallSenders, priorityMessageSenders, 1201 SUPPRESSED_EFFECTS_UNSET, STATE_UNSET); 1202 } 1203 1204 /** 1205 * Constructs a policy for Do Not Disturb priority mode behavior. 1206 * 1207 * <p> 1208 * Apps that target API levels below {@link Build.VERSION_CODES#P} cannot 1209 * change user-designated values to allow or disallow 1210 * {@link Policy#PRIORITY_CATEGORY_ALARMS}, {@link Policy#PRIORITY_CATEGORY_SYSTEM}, and 1211 * {@link Policy#PRIORITY_CATEGORY_MEDIA} from bypassing dnd. 1212 * <p> 1213 * Additionally, apps that target API levels below {@link Build.VERSION_CODES#P} can 1214 * only modify the {@link #SUPPRESSED_EFFECT_SCREEN_ON} and 1215 * {@link #SUPPRESSED_EFFECT_SCREEN_OFF} bits of the suppressed visual effects field. 1216 * All other suppressed effects will be ignored and reconstituted from the screen on 1217 * and screen off values. 1218 * <p> 1219 * Apps that target {@link Build.VERSION_CODES#P} or above can set any 1220 * suppressed visual effects. However, if any suppressed effects > 1221 * {@link #SUPPRESSED_EFFECT_SCREEN_ON} are set, {@link #SUPPRESSED_EFFECT_SCREEN_ON} 1222 * and {@link #SUPPRESSED_EFFECT_SCREEN_OFF} will be ignored and reconstituted from 1223 * the more specific suppressed visual effect bits. Apps should migrate to targeting 1224 * specific effects instead of the deprecated {@link #SUPPRESSED_EFFECT_SCREEN_ON} and 1225 * {@link #SUPPRESSED_EFFECT_SCREEN_OFF} effects. 1226 * 1227 * @param priorityCategories bitmask of categories of notifications that can bypass DND. 1228 * @param priorityCallSenders which callers can bypass DND. 1229 * @param priorityMessageSenders which message senders can bypass DND. 1230 * @param suppressedVisualEffects which visual interruptions should be suppressed from 1231 * notifications that are filtered by DND. 1232 */ 1233 public Policy(int priorityCategories, int priorityCallSenders, int priorityMessageSenders, 1234 int suppressedVisualEffects) { 1235 this.priorityCategories = priorityCategories; 1236 this.priorityCallSenders = priorityCallSenders; 1237 this.priorityMessageSenders = priorityMessageSenders; 1238 this.suppressedVisualEffects = suppressedVisualEffects; 1239 this.state = STATE_UNSET; 1240 } 1241 1242 /** @hide */ 1243 public Policy(int priorityCategories, int priorityCallSenders, int priorityMessageSenders, 1244 int suppressedVisualEffects, int state) { 1245 this.priorityCategories = priorityCategories; 1246 this.priorityCallSenders = priorityCallSenders; 1247 this.priorityMessageSenders = priorityMessageSenders; 1248 this.suppressedVisualEffects = suppressedVisualEffects; 1249 this.state = state; 1250 } 1251 1252 /** @hide */ 1253 public Policy(Parcel source) { 1254 this(source.readInt(), source.readInt(), source.readInt(), source.readInt(), 1255 source.readInt()); 1256 } 1257 1258 @Override 1259 public void writeToParcel(Parcel dest, int flags) { 1260 dest.writeInt(priorityCategories); 1261 dest.writeInt(priorityCallSenders); 1262 dest.writeInt(priorityMessageSenders); 1263 dest.writeInt(suppressedVisualEffects); 1264 dest.writeInt(state); 1265 } 1266 1267 @Override 1268 public int describeContents() { 1269 return 0; 1270 } 1271 1272 @Override 1273 public int hashCode() { 1274 return Objects.hash(priorityCategories, priorityCallSenders, priorityMessageSenders, 1275 suppressedVisualEffects); 1276 } 1277 1278 @Override 1279 public boolean equals(Object o) { 1280 if (!(o instanceof Policy)) return false; 1281 if (o == this) return true; 1282 final Policy other = (Policy) o; 1283 return other.priorityCategories == priorityCategories 1284 && other.priorityCallSenders == priorityCallSenders 1285 && other.priorityMessageSenders == priorityMessageSenders 1286 && other.suppressedVisualEffects == suppressedVisualEffects; 1287 } 1288 1289 @Override 1290 public String toString() { 1291 return "NotificationManager.Policy[" 1292 + "priorityCategories=" + priorityCategoriesToString(priorityCategories) 1293 + ",priorityCallSenders=" + prioritySendersToString(priorityCallSenders) 1294 + ",priorityMessageSenders=" + prioritySendersToString(priorityMessageSenders) 1295 + ",suppressedVisualEffects=" 1296 + suppressedEffectsToString(suppressedVisualEffects) 1297 + ",areChannelsBypassingDnd=" + (((state & STATE_CHANNELS_BYPASSING_DND) != 0) 1298 ? "true" : "false") 1299 + "]"; 1300 } 1301 1302 /** @hide */ 1303 public void writeToProto(ProtoOutputStream proto, long fieldId) { 1304 final long pToken = proto.start(fieldId); 1305 1306 bitwiseToProtoEnum(proto, PolicyProto.PRIORITY_CATEGORIES, priorityCategories); 1307 proto.write(PolicyProto.PRIORITY_CALL_SENDER, priorityCallSenders); 1308 proto.write(PolicyProto.PRIORITY_MESSAGE_SENDER, priorityMessageSenders); 1309 bitwiseToProtoEnum( 1310 proto, PolicyProto.SUPPRESSED_VISUAL_EFFECTS, suppressedVisualEffects); 1311 1312 proto.end(pToken); 1313 } 1314 1315 private static void bitwiseToProtoEnum(ProtoOutputStream proto, long fieldId, int data) { 1316 for (int i = 1; data > 0; ++i, data >>>= 1) { 1317 if ((data & 1) == 1) { 1318 proto.write(fieldId, i); 1319 } 1320 } 1321 } 1322 1323 /** 1324 * @hide 1325 */ 1326 public static int getAllSuppressedVisualEffects() { 1327 int effects = 0; 1328 for (int i = 0; i < ALL_SUPPRESSED_EFFECTS.length; i++) { 1329 effects |= ALL_SUPPRESSED_EFFECTS[i]; 1330 } 1331 return effects; 1332 } 1333 1334 /** 1335 * @hide 1336 */ 1337 public static boolean areAllVisualEffectsSuppressed(int effects) { 1338 for (int i = 0; i < ALL_SUPPRESSED_EFFECTS.length; i++) { 1339 final int effect = ALL_SUPPRESSED_EFFECTS[i]; 1340 if ((effects & effect) == 0) { 1341 return false; 1342 } 1343 } 1344 return true; 1345 } 1346 1347 /** 1348 * @hide 1349 */ 1350 public static boolean areAnyScreenOffEffectsSuppressed(int effects) { 1351 for (int i = 0; i < SCREEN_OFF_SUPPRESSED_EFFECTS.length; i++) { 1352 final int effect = SCREEN_OFF_SUPPRESSED_EFFECTS[i]; 1353 if ((effects & effect) != 0) { 1354 return true; 1355 } 1356 } 1357 return false; 1358 } 1359 1360 /** 1361 * @hide 1362 */ 1363 public static boolean areAnyScreenOnEffectsSuppressed(int effects) { 1364 for (int i = 0; i < SCREEN_ON_SUPPRESSED_EFFECTS.length; i++) { 1365 final int effect = SCREEN_ON_SUPPRESSED_EFFECTS[i]; 1366 if ((effects & effect) != 0) { 1367 return true; 1368 } 1369 } 1370 return false; 1371 } 1372 1373 /** 1374 * @hide 1375 */ 1376 public static int toggleScreenOffEffectsSuppressed(int currentEffects, boolean suppress) { 1377 return toggleEffects(currentEffects, SCREEN_OFF_SUPPRESSED_EFFECTS, suppress); 1378 } 1379 1380 /** 1381 * @hide 1382 */ 1383 public static int toggleScreenOnEffectsSuppressed(int currentEffects, boolean suppress) { 1384 return toggleEffects(currentEffects, SCREEN_ON_SUPPRESSED_EFFECTS, suppress); 1385 } 1386 1387 private static int toggleEffects(int currentEffects, int[] effects, boolean suppress) { 1388 for (int i = 0; i < effects.length; i++) { 1389 final int effect = effects[i]; 1390 if (suppress) { 1391 currentEffects |= effect; 1392 } else { 1393 currentEffects &= ~effect; 1394 } 1395 } 1396 return currentEffects; 1397 } 1398 1399 public static String suppressedEffectsToString(int effects) { 1400 if (effects <= 0) return ""; 1401 final StringBuilder sb = new StringBuilder(); 1402 for (int i = 0; i < ALL_SUPPRESSED_EFFECTS.length; i++) { 1403 final int effect = ALL_SUPPRESSED_EFFECTS[i]; 1404 if ((effects & effect) != 0) { 1405 if (sb.length() > 0) sb.append(','); 1406 sb.append(effectToString(effect)); 1407 } 1408 effects &= ~effect; 1409 } 1410 if (effects != 0) { 1411 if (sb.length() > 0) sb.append(','); 1412 sb.append("UNKNOWN_").append(effects); 1413 } 1414 return sb.toString(); 1415 } 1416 1417 public static String priorityCategoriesToString(int priorityCategories) { 1418 if (priorityCategories == 0) return ""; 1419 final StringBuilder sb = new StringBuilder(); 1420 for (int i = 0; i < ALL_PRIORITY_CATEGORIES.length; i++) { 1421 final int priorityCategory = ALL_PRIORITY_CATEGORIES[i]; 1422 if ((priorityCategories & priorityCategory) != 0) { 1423 if (sb.length() > 0) sb.append(','); 1424 sb.append(priorityCategoryToString(priorityCategory)); 1425 } 1426 priorityCategories &= ~priorityCategory; 1427 } 1428 if (priorityCategories != 0) { 1429 if (sb.length() > 0) sb.append(','); 1430 sb.append("PRIORITY_CATEGORY_UNKNOWN_").append(priorityCategories); 1431 } 1432 return sb.toString(); 1433 } 1434 1435 private static String effectToString(int effect) { 1436 switch (effect) { 1437 case SUPPRESSED_EFFECT_FULL_SCREEN_INTENT: 1438 return "SUPPRESSED_EFFECT_FULL_SCREEN_INTENT"; 1439 case SUPPRESSED_EFFECT_LIGHTS: 1440 return "SUPPRESSED_EFFECT_LIGHTS"; 1441 case SUPPRESSED_EFFECT_PEEK: 1442 return "SUPPRESSED_EFFECT_PEEK"; 1443 case SUPPRESSED_EFFECT_STATUS_BAR: 1444 return "SUPPRESSED_EFFECT_STATUS_BAR"; 1445 case SUPPRESSED_EFFECT_BADGE: 1446 return "SUPPRESSED_EFFECT_BADGE"; 1447 case SUPPRESSED_EFFECT_AMBIENT: 1448 return "SUPPRESSED_EFFECT_AMBIENT"; 1449 case SUPPRESSED_EFFECT_NOTIFICATION_LIST: 1450 return "SUPPRESSED_EFFECT_NOTIFICATION_LIST"; 1451 case SUPPRESSED_EFFECT_SCREEN_OFF: 1452 return "SUPPRESSED_EFFECT_SCREEN_OFF"; 1453 case SUPPRESSED_EFFECT_SCREEN_ON: 1454 return "SUPPRESSED_EFFECT_SCREEN_ON"; 1455 case SUPPRESSED_EFFECTS_UNSET: 1456 return "SUPPRESSED_EFFECTS_UNSET"; 1457 default: return "UNKNOWN_" + effect; 1458 } 1459 } 1460 1461 private static String priorityCategoryToString(int priorityCategory) { 1462 switch (priorityCategory) { 1463 case PRIORITY_CATEGORY_REMINDERS: return "PRIORITY_CATEGORY_REMINDERS"; 1464 case PRIORITY_CATEGORY_EVENTS: return "PRIORITY_CATEGORY_EVENTS"; 1465 case PRIORITY_CATEGORY_MESSAGES: return "PRIORITY_CATEGORY_MESSAGES"; 1466 case PRIORITY_CATEGORY_CALLS: return "PRIORITY_CATEGORY_CALLS"; 1467 case PRIORITY_CATEGORY_REPEAT_CALLERS: return "PRIORITY_CATEGORY_REPEAT_CALLERS"; 1468 case PRIORITY_CATEGORY_ALARMS: return "PRIORITY_CATEGORY_ALARMS"; 1469 case PRIORITY_CATEGORY_MEDIA: return "PRIORITY_CATEGORY_MEDIA"; 1470 case PRIORITY_CATEGORY_SYSTEM: return "PRIORITY_CATEGORY_SYSTEM"; 1471 default: return "PRIORITY_CATEGORY_UNKNOWN_" + priorityCategory; 1472 } 1473 } 1474 1475 public static String prioritySendersToString(int prioritySenders) { 1476 switch (prioritySenders) { 1477 case PRIORITY_SENDERS_ANY: return "PRIORITY_SENDERS_ANY"; 1478 case PRIORITY_SENDERS_CONTACTS: return "PRIORITY_SENDERS_CONTACTS"; 1479 case PRIORITY_SENDERS_STARRED: return "PRIORITY_SENDERS_STARRED"; 1480 default: return "PRIORITY_SENDERS_UNKNOWN_" + prioritySenders; 1481 } 1482 } 1483 1484 public static final Parcelable.Creator<Policy> CREATOR = new Parcelable.Creator<Policy>() { 1485 @Override 1486 public Policy createFromParcel(Parcel in) { 1487 return new Policy(in); 1488 } 1489 1490 @Override 1491 public Policy[] newArray(int size) { 1492 return new Policy[size]; 1493 } 1494 }; 1495 } 1496 1497 /** 1498 * Recover a list of active notifications: ones that have been posted by the calling app that 1499 * have not yet been dismissed by the user or {@link #cancel(String, int)}ed by the app. 1500 * 1501 * Each notification is embedded in a {@link StatusBarNotification} object, including the 1502 * original <code>tag</code> and <code>id</code> supplied to 1503 * {@link #notify(String, int, Notification) notify()} 1504 * (via {@link StatusBarNotification#getTag() getTag()} and 1505 * {@link StatusBarNotification#getId() getId()}) as well as a copy of the original 1506 * {@link Notification} object (via {@link StatusBarNotification#getNotification()}). 1507 * 1508 * @return An array of {@link StatusBarNotification}. 1509 */ 1510 public StatusBarNotification[] getActiveNotifications() { 1511 final INotificationManager service = getService(); 1512 final String pkg = mContext.getPackageName(); 1513 try { 1514 final ParceledListSlice<StatusBarNotification> parceledList 1515 = service.getAppActiveNotifications(pkg, mContext.getUserId()); 1516 final List<StatusBarNotification> list = parceledList.getList(); 1517 return list.toArray(new StatusBarNotification[list.size()]); 1518 } catch (RemoteException e) { 1519 throw e.rethrowFromSystemServer(); 1520 } 1521 } 1522 1523 /** 1524 * Gets the current notification interruption filter. 1525 * <p> 1526 * The interruption filter defines which notifications are allowed to 1527 * interrupt the user (e.g. via sound & vibration) and is applied 1528 * globally. 1529 */ 1530 public final @InterruptionFilter int getCurrentInterruptionFilter() { 1531 final INotificationManager service = getService(); 1532 try { 1533 return zenModeToInterruptionFilter(service.getZenMode()); 1534 } catch (RemoteException e) { 1535 throw e.rethrowFromSystemServer(); 1536 } 1537 } 1538 1539 /** 1540 * Sets the current notification interruption filter. 1541 * <p> 1542 * The interruption filter defines which notifications are allowed to 1543 * interrupt the user (e.g. via sound & vibration) and is applied 1544 * globally. 1545 * <p> 1546 * Only available if policy access is granted to this package. See 1547 * {@link #isNotificationPolicyAccessGranted}. 1548 */ 1549 public final void setInterruptionFilter(@InterruptionFilter int interruptionFilter) { 1550 final INotificationManager service = getService(); 1551 try { 1552 service.setInterruptionFilter(mContext.getOpPackageName(), interruptionFilter); 1553 } catch (RemoteException e) { 1554 throw e.rethrowFromSystemServer(); 1555 } 1556 } 1557 1558 /** @hide */ 1559 public static int zenModeToInterruptionFilter(int zen) { 1560 switch (zen) { 1561 case Global.ZEN_MODE_OFF: return INTERRUPTION_FILTER_ALL; 1562 case Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS: return INTERRUPTION_FILTER_PRIORITY; 1563 case Global.ZEN_MODE_ALARMS: return INTERRUPTION_FILTER_ALARMS; 1564 case Global.ZEN_MODE_NO_INTERRUPTIONS: return INTERRUPTION_FILTER_NONE; 1565 default: return INTERRUPTION_FILTER_UNKNOWN; 1566 } 1567 } 1568 1569 /** @hide */ 1570 public static int zenModeFromInterruptionFilter(int interruptionFilter, int defValue) { 1571 switch (interruptionFilter) { 1572 case INTERRUPTION_FILTER_ALL: return Global.ZEN_MODE_OFF; 1573 case INTERRUPTION_FILTER_PRIORITY: return Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS; 1574 case INTERRUPTION_FILTER_ALARMS: return Global.ZEN_MODE_ALARMS; 1575 case INTERRUPTION_FILTER_NONE: return Global.ZEN_MODE_NO_INTERRUPTIONS; 1576 default: return defValue; 1577 } 1578 } 1579 1580} 1581