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.NonNull; 20 import android.annotation.Nullable; 21 import android.annotation.SdkConstant; 22 import android.app.Notification.Builder; 23 import android.content.ComponentName; 24 import android.content.Context; 25 import android.content.pm.ParceledListSlice; 26 import android.graphics.drawable.Icon; 27 import android.net.Uri; 28 import android.os.Build; 29 import android.os.Bundle; 30 import android.os.Handler; 31 import android.os.IBinder; 32 import android.os.Parcel; 33 import android.os.Parcelable; 34 import android.os.RemoteException; 35 import android.os.ServiceManager; 36 import android.os.StrictMode; 37 import android.os.UserHandle; 38 import android.provider.Settings.Global; 39 import android.service.notification.IConditionListener; 40 import android.service.notification.StatusBarNotification; 41 import android.service.notification.ZenModeConfig; 42 import android.util.ArraySet; 43 import android.util.Log; 44 45 import java.util.Objects; 46 import java.util.List; 47 48 /** 49 * Class to notify the user of events that happen. This is how you tell 50 * the user that something has happened in the background. {@more} 51 * 52 * Notifications can take different forms: 53 * <ul> 54 * <li>A persistent icon that goes in the status bar and is accessible 55 * through the launcher, (when the user selects it, a designated Intent 56 * can be launched),</li> 57 * <li>Turning on or flashing LEDs on the device, or</li> 58 * <li>Alerting the user by flashing the backlight, playing a sound, 59 * or vibrating.</li> 60 * </ul> 61 * 62 * <p> 63 * Each of the notify methods takes an int id parameter and optionally a 64 * {@link String} tag parameter, which may be {@code null}. These parameters 65 * are used to form a pair (tag, id), or ({@code null}, id) if tag is 66 * unspecified. This pair identifies this notification from your app to the 67 * system, so that pair should be unique within your app. If you call one 68 * of the notify methods with a (tag, id) pair that is currently active and 69 * a new set of notification parameters, it will be updated. For example, 70 * if you pass a new status bar icon, the old icon in the status bar will 71 * be replaced with the new one. This is also the same tag and id you pass 72 * to the {@link #cancel(int)} or {@link #cancel(String, int)} method to clear 73 * this notification. 74 * 75 * <p> 76 * You do not instantiate this class directly; instead, retrieve it through 77 * {@link android.content.Context#getSystemService}. 78 * 79 * <div class="special reference"> 80 * <h3>Developer Guides</h3> 81 * <p>For a guide to creating notifications, read the 82 * <a href="{@docRoot}guide/topics/ui/notifiers/notifications.html">Status Bar Notifications</a> 83 * developer guide.</p> 84 * </div> 85 * 86 * @see android.app.Notification 87 * @see android.content.Context#getSystemService 88 */ 89 public class NotificationManager 90 { 91 private static String TAG = "NotificationManager"; 92 private static boolean localLOGV = false; 93 94 /** 95 * Intent that is broadcast when the state of {@link #getEffectsSuppressor()} changes. 96 * This broadcast is only sent to registered receivers. 97 * 98 * @hide 99 */ 100 @SdkConstant(SdkConstant.SdkConstantType.BROADCAST_INTENT_ACTION) 101 public static final String ACTION_EFFECTS_SUPPRESSOR_CHANGED 102 = "android.os.action.ACTION_EFFECTS_SUPPRESSOR_CHANGED"; 103 104 /** 105 * Intent that is broadcast when the state of {@link #isNotificationPolicyAccessGranted()} 106 * changes. 107 * 108 * This broadcast is only sent to registered receivers, and only to the apps that have changed. 109 */ 110 @SdkConstant(SdkConstant.SdkConstantType.BROADCAST_INTENT_ACTION) 111 public static final String ACTION_NOTIFICATION_POLICY_ACCESS_GRANTED_CHANGED 112 = "android.app.action.NOTIFICATION_POLICY_ACCESS_GRANTED_CHANGED"; 113 114 /** 115 * Intent that is broadcast when the state of getNotificationPolicy() changes. 116 * This broadcast is only sent to registered receivers. 117 */ 118 @SdkConstant(SdkConstant.SdkConstantType.BROADCAST_INTENT_ACTION) 119 public static final String ACTION_NOTIFICATION_POLICY_CHANGED 120 = "android.app.action.NOTIFICATION_POLICY_CHANGED"; 121 122 /** 123 * Intent that is broadcast when the state of getCurrentInterruptionFilter() changes. 124 * This broadcast is only sent to registered receivers. 125 */ 126 @SdkConstant(SdkConstant.SdkConstantType.BROADCAST_INTENT_ACTION) 127 public static final String ACTION_INTERRUPTION_FILTER_CHANGED 128 = "android.app.action.INTERRUPTION_FILTER_CHANGED"; 129 130 /** 131 * {@link #getCurrentInterruptionFilter() Interruption filter} constant - 132 * Normal interruption filter. 133 */ 134 public static final int INTERRUPTION_FILTER_ALL = 1; 135 136 /** 137 * {@link #getCurrentInterruptionFilter() Interruption filter} constant - 138 * Priority interruption filter. 139 */ 140 public static final int INTERRUPTION_FILTER_PRIORITY = 2; 141 142 /** 143 * {@link #getCurrentInterruptionFilter() Interruption filter} constant - 144 * No interruptions filter. 145 */ 146 public static final int INTERRUPTION_FILTER_NONE = 3; 147 148 /** 149 * {@link #getCurrentInterruptionFilter() Interruption filter} constant - 150 * Alarms only interruption filter. 151 */ 152 public static final int INTERRUPTION_FILTER_ALARMS = 4; 153 154 /** {@link #getCurrentInterruptionFilter() Interruption filter} constant - returned when 155 * the value is unavailable for any reason. 156 */ 157 public static final int INTERRUPTION_FILTER_UNKNOWN = 0; 158 159 private static INotificationManager sService; 160 161 /** @hide */ getService()162 static public INotificationManager getService() 163 { 164 if (sService != null) { 165 return sService; 166 } 167 IBinder b = ServiceManager.getService("notification"); 168 sService = INotificationManager.Stub.asInterface(b); 169 return sService; 170 } 171 NotificationManager(Context context, Handler handler)172 /*package*/ NotificationManager(Context context, Handler handler) 173 { 174 mContext = context; 175 } 176 177 /** {@hide} */ from(Context context)178 public static NotificationManager from(Context context) { 179 return (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); 180 } 181 182 /** 183 * Post a notification to be shown in the status bar. If a notification with 184 * the same id has already been posted by your application and has not yet been canceled, it 185 * will be replaced by the updated information. 186 * 187 * @param id An identifier for this notification unique within your 188 * application. 189 * @param notification A {@link Notification} object describing what to show the user. Must not 190 * be null. 191 */ notify(int id, Notification notification)192 public void notify(int id, Notification notification) 193 { 194 notify(null, id, notification); 195 } 196 197 /** 198 * Post a notification to be shown in the status bar. If a notification with 199 * the same tag and id has already been posted by your application and has not yet been 200 * canceled, it will be replaced by the updated information. 201 * 202 * @param tag A string identifier for this notification. May be {@code null}. 203 * @param id An identifier for this notification. The pair (tag, id) must be unique 204 * within your application. 205 * @param notification A {@link Notification} object describing what to 206 * show the user. Must not be null. 207 */ notify(String tag, int id, Notification notification)208 public void notify(String tag, int id, Notification notification) 209 { 210 int[] idOut = new int[1]; 211 INotificationManager service = getService(); 212 String pkg = mContext.getPackageName(); 213 if (notification.sound != null) { 214 notification.sound = notification.sound.getCanonicalUri(); 215 if (StrictMode.vmFileUriExposureEnabled()) { 216 notification.sound.checkFileUriExposed("Notification.sound"); 217 } 218 } 219 fixLegacySmallIcon(notification, pkg); 220 if (mContext.getApplicationInfo().targetSdkVersion > Build.VERSION_CODES.LOLLIPOP_MR1) { 221 if (notification.getSmallIcon() == null) { 222 throw new IllegalArgumentException("Invalid notification (no valid small icon): " 223 + notification); 224 } 225 } 226 if (localLOGV) Log.v(TAG, pkg + ": notify(" + id + ", " + notification + ")"); 227 Notification stripped = notification.clone(); 228 Builder.stripForDelivery(stripped); 229 try { 230 service.enqueueNotificationWithTag(pkg, mContext.getOpPackageName(), tag, id, 231 stripped, idOut, UserHandle.myUserId()); 232 if (id != idOut[0]) { 233 Log.w(TAG, "notify: id corrupted: sent " + id + ", got back " + idOut[0]); 234 } 235 } catch (RemoteException e) { 236 } 237 } 238 239 /** 240 * @hide 241 */ notifyAsUser(String tag, int id, Notification notification, UserHandle user)242 public void notifyAsUser(String tag, int id, Notification notification, UserHandle user) 243 { 244 int[] idOut = new int[1]; 245 INotificationManager service = getService(); 246 String pkg = mContext.getPackageName(); 247 if (notification.sound != null) { 248 notification.sound = notification.sound.getCanonicalUri(); 249 if (StrictMode.vmFileUriExposureEnabled()) { 250 notification.sound.checkFileUriExposed("Notification.sound"); 251 } 252 } 253 fixLegacySmallIcon(notification, pkg); 254 if (localLOGV) Log.v(TAG, pkg + ": notify(" + id + ", " + notification + ")"); 255 Notification stripped = notification.clone(); 256 Builder.stripForDelivery(stripped); 257 try { 258 service.enqueueNotificationWithTag(pkg, mContext.getOpPackageName(), tag, id, 259 stripped, idOut, user.getIdentifier()); 260 if (id != idOut[0]) { 261 Log.w(TAG, "notify: id corrupted: sent " + id + ", got back " + idOut[0]); 262 } 263 } catch (RemoteException e) { 264 } 265 } 266 fixLegacySmallIcon(Notification n, String pkg)267 private void fixLegacySmallIcon(Notification n, String pkg) { 268 if (n.getSmallIcon() == null && n.icon != 0) { 269 n.setSmallIcon(Icon.createWithResource(pkg, n.icon)); 270 } 271 } 272 273 /** 274 * Cancel a previously shown notification. If it's transient, the view 275 * will be hidden. If it's persistent, it will be removed from the status 276 * bar. 277 */ cancel(int id)278 public void cancel(int id) 279 { 280 cancel(null, id); 281 } 282 283 /** 284 * Cancel a previously shown notification. If it's transient, the view 285 * will be hidden. If it's persistent, it will be removed from the status 286 * bar. 287 */ cancel(String tag, int id)288 public void cancel(String tag, int id) 289 { 290 INotificationManager service = getService(); 291 String pkg = mContext.getPackageName(); 292 if (localLOGV) Log.v(TAG, pkg + ": cancel(" + id + ")"); 293 try { 294 service.cancelNotificationWithTag(pkg, tag, id, UserHandle.myUserId()); 295 } catch (RemoteException e) { 296 } 297 } 298 299 /** 300 * @hide 301 */ cancelAsUser(String tag, int id, UserHandle user)302 public void cancelAsUser(String tag, int id, UserHandle user) 303 { 304 INotificationManager service = getService(); 305 String pkg = mContext.getPackageName(); 306 if (localLOGV) Log.v(TAG, pkg + ": cancel(" + id + ")"); 307 try { 308 service.cancelNotificationWithTag(pkg, tag, id, user.getIdentifier()); 309 } catch (RemoteException e) { 310 } 311 } 312 313 /** 314 * Cancel all previously shown notifications. See {@link #cancel} for the 315 * detailed behavior. 316 */ cancelAll()317 public void cancelAll() 318 { 319 INotificationManager service = getService(); 320 String pkg = mContext.getPackageName(); 321 if (localLOGV) Log.v(TAG, pkg + ": cancelAll()"); 322 try { 323 service.cancelAllNotifications(pkg, UserHandle.myUserId()); 324 } catch (RemoteException e) { 325 } 326 } 327 328 /** 329 * @hide 330 */ getEffectsSuppressor()331 public ComponentName getEffectsSuppressor() { 332 INotificationManager service = getService(); 333 try { 334 return service.getEffectsSuppressor(); 335 } catch (RemoteException e) { 336 return null; 337 } 338 } 339 340 /** 341 * @hide 342 */ matchesCallFilter(Bundle extras)343 public boolean matchesCallFilter(Bundle extras) { 344 INotificationManager service = getService(); 345 try { 346 return service.matchesCallFilter(extras); 347 } catch (RemoteException e) { 348 return false; 349 } 350 } 351 352 /** 353 * @hide 354 */ isSystemConditionProviderEnabled(String path)355 public boolean isSystemConditionProviderEnabled(String path) { 356 INotificationManager service = getService(); 357 try { 358 return service.isSystemConditionProviderEnabled(path); 359 } catch (RemoteException e) { 360 return false; 361 } 362 } 363 364 /** 365 * @hide 366 */ setZenMode(int mode, Uri conditionId, String reason)367 public void setZenMode(int mode, Uri conditionId, String reason) { 368 INotificationManager service = getService(); 369 try { 370 service.setZenMode(mode, conditionId, reason); 371 } catch (RemoteException e) { 372 } 373 } 374 375 /** 376 * @hide 377 */ setZenModeConfig(ZenModeConfig config, String reason)378 public boolean setZenModeConfig(ZenModeConfig config, String reason) { 379 INotificationManager service = getService(); 380 try { 381 return service.setZenModeConfig(config, reason); 382 } catch (RemoteException e) { 383 return false; 384 } 385 } 386 387 /** 388 * @hide 389 */ requestZenModeConditions(IConditionListener listener, int relevance)390 public void requestZenModeConditions(IConditionListener listener, int relevance) { 391 INotificationManager service = getService(); 392 try { 393 service.requestZenModeConditions(listener, relevance); 394 } catch (RemoteException e) { 395 } 396 } 397 398 /** 399 * @hide 400 */ getZenMode()401 public int getZenMode() { 402 INotificationManager service = getService(); 403 try { 404 return service.getZenMode(); 405 } catch (RemoteException e) { 406 } 407 return Global.ZEN_MODE_OFF; 408 } 409 410 /** 411 * @hide 412 */ getZenModeConfig()413 public ZenModeConfig getZenModeConfig() { 414 INotificationManager service = getService(); 415 try { 416 return service.getZenModeConfig(); 417 } catch (RemoteException e) { 418 } 419 return null; 420 } 421 422 /** 423 * Checks the ability to read/modify notification policy for the calling package. 424 * 425 * <p> 426 * Returns true if the calling package can read/modify notification policy. 427 * 428 * <p> 429 * Request policy access by sending the user to the activity that matches the system intent 430 * action {@link android.provider.Settings#ACTION_NOTIFICATION_POLICY_ACCESS_SETTINGS}. 431 * 432 * <p> 433 * Use {@link #ACTION_NOTIFICATION_POLICY_ACCESS_GRANTED_CHANGED} to listen for 434 * user grant or denial of this access. 435 */ isNotificationPolicyAccessGranted()436 public boolean isNotificationPolicyAccessGranted() { 437 INotificationManager service = getService(); 438 try { 439 return service.isNotificationPolicyAccessGranted(mContext.getOpPackageName()); 440 } catch (RemoteException e) { 441 } 442 return false; 443 } 444 445 /** @hide */ isNotificationPolicyAccessGrantedForPackage(String pkg)446 public boolean isNotificationPolicyAccessGrantedForPackage(String pkg) { 447 INotificationManager service = getService(); 448 try { 449 return service.isNotificationPolicyAccessGrantedForPackage(pkg); 450 } catch (RemoteException e) { 451 } 452 return false; 453 } 454 455 /** 456 * Gets the current notification policy. 457 * 458 * <p> 459 * Only available if policy access is granted to this package. 460 * See {@link #isNotificationPolicyAccessGranted}. 461 */ getNotificationPolicy()462 public Policy getNotificationPolicy() { 463 INotificationManager service = getService(); 464 try { 465 return service.getNotificationPolicy(mContext.getOpPackageName()); 466 } catch (RemoteException e) { 467 } 468 return null; 469 } 470 471 /** 472 * Sets the current notification policy. 473 * 474 * <p> 475 * Only available if policy access is granted to this package. 476 * See {@link #isNotificationPolicyAccessGranted}. 477 * 478 * @param policy The new desired policy. 479 */ setNotificationPolicy(@onNull Policy policy)480 public void setNotificationPolicy(@NonNull Policy policy) { 481 checkRequired("policy", policy); 482 INotificationManager service = getService(); 483 try { 484 service.setNotificationPolicy(mContext.getOpPackageName(), policy); 485 } catch (RemoteException e) { 486 } 487 } 488 489 /** @hide */ setNotificationPolicyAccessGranted(String pkg, boolean granted)490 public void setNotificationPolicyAccessGranted(String pkg, boolean granted) { 491 INotificationManager service = getService(); 492 try { 493 service.setNotificationPolicyAccessGranted(pkg, granted); 494 } catch (RemoteException e) { 495 } 496 } 497 498 /** @hide */ getPackagesRequestingNotificationPolicyAccess()499 public ArraySet<String> getPackagesRequestingNotificationPolicyAccess() { 500 INotificationManager service = getService(); 501 try { 502 final String[] pkgs = service.getPackagesRequestingNotificationPolicyAccess(); 503 if (pkgs != null && pkgs.length > 0) { 504 final ArraySet<String> rt = new ArraySet<>(pkgs.length); 505 for (int i = 0; i < pkgs.length; i++) { 506 rt.add(pkgs[i]); 507 } 508 return rt; 509 } 510 } catch (RemoteException e) { 511 } 512 return new ArraySet<String>(); 513 } 514 515 private Context mContext; 516 checkRequired(String name, Object value)517 private static void checkRequired(String name, Object value) { 518 if (value == null) { 519 throw new IllegalArgumentException(name + " is required"); 520 } 521 } 522 523 /** 524 * Notification policy configuration. Represents user-preferences for notification 525 * filtering and prioritization. 526 */ 527 public static class Policy implements android.os.Parcelable { 528 /** Reminder notifications are prioritized. */ 529 public static final int PRIORITY_CATEGORY_REMINDERS = 1 << 0; 530 /** Event notifications are prioritized. */ 531 public static final int PRIORITY_CATEGORY_EVENTS = 1 << 1; 532 /** Message notifications are prioritized. */ 533 public static final int PRIORITY_CATEGORY_MESSAGES = 1 << 2; 534 /** Calls are prioritized. */ 535 public static final int PRIORITY_CATEGORY_CALLS = 1 << 3; 536 /** Calls from repeat callers are prioritized. */ 537 public static final int PRIORITY_CATEGORY_REPEAT_CALLERS = 1 << 4; 538 539 private static final int[] ALL_PRIORITY_CATEGORIES = { 540 PRIORITY_CATEGORY_REMINDERS, 541 PRIORITY_CATEGORY_EVENTS, 542 PRIORITY_CATEGORY_MESSAGES, 543 PRIORITY_CATEGORY_CALLS, 544 PRIORITY_CATEGORY_REPEAT_CALLERS, 545 }; 546 547 /** Any sender is prioritized. */ 548 public static final int PRIORITY_SENDERS_ANY = 0; 549 /** Saved contacts are prioritized. */ 550 public static final int PRIORITY_SENDERS_CONTACTS = 1; 551 /** Only starred contacts are prioritized. */ 552 public static final int PRIORITY_SENDERS_STARRED = 2; 553 554 /** Notification categories to prioritize. Bitmask of PRIORITY_CATEGORY_* constants. */ 555 public final int priorityCategories; 556 557 /** Notification senders to prioritize for calls. One of: 558 * PRIORITY_SENDERS_ANY, PRIORITY_SENDERS_CONTACTS, PRIORITY_SENDERS_STARRED */ 559 public final int priorityCallSenders; 560 561 /** Notification senders to prioritize for messages. One of: 562 * PRIORITY_SENDERS_ANY, PRIORITY_SENDERS_CONTACTS, PRIORITY_SENDERS_STARRED */ 563 public final int priorityMessageSenders; 564 Policy(int priorityCategories, int priorityCallSenders, int priorityMessageSenders)565 public Policy(int priorityCategories, int priorityCallSenders, int priorityMessageSenders) { 566 this.priorityCategories = priorityCategories; 567 this.priorityCallSenders = priorityCallSenders; 568 this.priorityMessageSenders = priorityMessageSenders; 569 } 570 571 /** @hide */ Policy(Parcel source)572 public Policy(Parcel source) { 573 this(source.readInt(), source.readInt(), source.readInt()); 574 } 575 576 @Override writeToParcel(Parcel dest, int flags)577 public void writeToParcel(Parcel dest, int flags) { 578 dest.writeInt(priorityCategories); 579 dest.writeInt(priorityCallSenders); 580 dest.writeInt(priorityMessageSenders); 581 } 582 583 @Override describeContents()584 public int describeContents() { 585 return 0; 586 } 587 588 @Override hashCode()589 public int hashCode() { 590 return Objects.hash(priorityCategories, priorityCallSenders, priorityMessageSenders); 591 } 592 593 @Override equals(Object o)594 public boolean equals(Object o) { 595 if (!(o instanceof Policy)) return false; 596 if (o == this) return true; 597 final Policy other = (Policy) o; 598 return other.priorityCategories == priorityCategories 599 && other.priorityCallSenders == priorityCallSenders 600 && other.priorityMessageSenders == priorityMessageSenders; 601 } 602 603 @Override toString()604 public String toString() { 605 return "NotificationManager.Policy[" 606 + "priorityCategories=" + priorityCategoriesToString(priorityCategories) 607 + ",priorityCallSenders=" + prioritySendersToString(priorityCallSenders) 608 + ",priorityMessageSenders=" + prioritySendersToString(priorityMessageSenders) 609 + "]"; 610 } 611 priorityCategoriesToString(int priorityCategories)612 public static String priorityCategoriesToString(int priorityCategories) { 613 if (priorityCategories == 0) return ""; 614 final StringBuilder sb = new StringBuilder(); 615 for (int i = 0; i < ALL_PRIORITY_CATEGORIES.length; i++) { 616 final int priorityCategory = ALL_PRIORITY_CATEGORIES[i]; 617 if ((priorityCategories & priorityCategory) != 0) { 618 if (sb.length() > 0) sb.append(','); 619 sb.append(priorityCategoryToString(priorityCategory)); 620 } 621 priorityCategories &= ~priorityCategory; 622 } 623 if (priorityCategories != 0) { 624 if (sb.length() > 0) sb.append(','); 625 sb.append("PRIORITY_CATEGORY_UNKNOWN_").append(priorityCategories); 626 } 627 return sb.toString(); 628 } 629 priorityCategoryToString(int priorityCategory)630 private static String priorityCategoryToString(int priorityCategory) { 631 switch (priorityCategory) { 632 case PRIORITY_CATEGORY_REMINDERS: return "PRIORITY_CATEGORY_REMINDERS"; 633 case PRIORITY_CATEGORY_EVENTS: return "PRIORITY_CATEGORY_EVENTS"; 634 case PRIORITY_CATEGORY_MESSAGES: return "PRIORITY_CATEGORY_MESSAGES"; 635 case PRIORITY_CATEGORY_CALLS: return "PRIORITY_CATEGORY_CALLS"; 636 case PRIORITY_CATEGORY_REPEAT_CALLERS: return "PRIORITY_CATEGORY_REPEAT_CALLERS"; 637 default: return "PRIORITY_CATEGORY_UNKNOWN_" + priorityCategory; 638 } 639 } 640 prioritySendersToString(int prioritySenders)641 public static String prioritySendersToString(int prioritySenders) { 642 switch (prioritySenders) { 643 case PRIORITY_SENDERS_ANY: return "PRIORITY_SENDERS_ANY"; 644 case PRIORITY_SENDERS_CONTACTS: return "PRIORITY_SENDERS_CONTACTS"; 645 case PRIORITY_SENDERS_STARRED: return "PRIORITY_SENDERS_STARRED"; 646 default: return "PRIORITY_SENDERS_UNKNOWN_" + prioritySenders; 647 } 648 } 649 650 public static final Parcelable.Creator<Policy> CREATOR = new Parcelable.Creator<Policy>() { 651 @Override 652 public Policy createFromParcel(Parcel in) { 653 return new Policy(in); 654 } 655 656 @Override 657 public Policy[] newArray(int size) { 658 return new Policy[size]; 659 } 660 }; 661 662 } 663 664 /** 665 * Recover a list of active notifications: ones that have been posted by the calling app that 666 * have not yet been dismissed by the user or {@link #cancel(String, int)}ed by the app. 667 * 668 * Each notification is embedded in a {@link StatusBarNotification} object, including the 669 * original <code>tag</code> and <code>id</code> supplied to 670 * {@link #notify(String, int, Notification) notify()} 671 * (via {@link StatusBarNotification#getTag() getTag()} and 672 * {@link StatusBarNotification#getId() getId()}) as well as a copy of the original 673 * {@link Notification} object (via {@link StatusBarNotification#getNotification()}). 674 * 675 * @return An array of {@link StatusBarNotification}. 676 */ getActiveNotifications()677 public StatusBarNotification[] getActiveNotifications() { 678 final INotificationManager service = getService(); 679 final String pkg = mContext.getPackageName(); 680 try { 681 final ParceledListSlice<StatusBarNotification> parceledList 682 = service.getAppActiveNotifications(pkg, UserHandle.myUserId()); 683 final List<StatusBarNotification> list = parceledList.getList(); 684 return list.toArray(new StatusBarNotification[list.size()]); 685 } catch (RemoteException e) { 686 Log.e(TAG, "Unable to talk to notification manager. Woe!", e); 687 } 688 return new StatusBarNotification[0]; 689 } 690 691 /** 692 * Gets the current notification interruption filter. 693 * 694 * <p> 695 * The interruption filter defines which notifications are allowed to interrupt the user 696 * (e.g. via sound & vibration) and is applied globally. 697 * @return One of the INTERRUPTION_FILTER_ constants, or INTERRUPTION_FILTER_UNKNOWN when 698 * unavailable. 699 * 700 * <p> 701 * Only available if policy access is granted to this package. 702 * See {@link #isNotificationPolicyAccessGranted}. 703 */ getCurrentInterruptionFilter()704 public final int getCurrentInterruptionFilter() { 705 final INotificationManager service = getService(); 706 try { 707 return zenModeToInterruptionFilter(service.getZenMode()); 708 } catch (RemoteException e) { 709 Log.e(TAG, "Unable to talk to notification manager. Woe!", e); 710 } 711 return INTERRUPTION_FILTER_UNKNOWN; 712 } 713 714 /** 715 * Sets the current notification interruption filter. 716 * 717 * <p> 718 * The interruption filter defines which notifications are allowed to interrupt the user 719 * (e.g. via sound & vibration) and is applied globally. 720 * @return One of the INTERRUPTION_FILTER_ constants, or INTERRUPTION_FILTER_UNKNOWN when 721 * unavailable. 722 * 723 * <p> 724 * Only available if policy access is granted to this package. 725 * See {@link #isNotificationPolicyAccessGranted}. 726 */ setInterruptionFilter(int interruptionFilter)727 public final void setInterruptionFilter(int interruptionFilter) { 728 final INotificationManager service = getService(); 729 try { 730 service.setInterruptionFilter(mContext.getOpPackageName(), interruptionFilter); 731 } catch (RemoteException e) { 732 Log.e(TAG, "Unable to talk to notification manager. Woe!", e); 733 } 734 } 735 736 /** @hide */ zenModeToInterruptionFilter(int zen)737 public static int zenModeToInterruptionFilter(int zen) { 738 switch (zen) { 739 case Global.ZEN_MODE_OFF: return INTERRUPTION_FILTER_ALL; 740 case Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS: return INTERRUPTION_FILTER_PRIORITY; 741 case Global.ZEN_MODE_ALARMS: return INTERRUPTION_FILTER_ALARMS; 742 case Global.ZEN_MODE_NO_INTERRUPTIONS: return INTERRUPTION_FILTER_NONE; 743 default: return INTERRUPTION_FILTER_UNKNOWN; 744 } 745 } 746 747 /** @hide */ zenModeFromInterruptionFilter(int interruptionFilter, int defValue)748 public static int zenModeFromInterruptionFilter(int interruptionFilter, int defValue) { 749 switch (interruptionFilter) { 750 case INTERRUPTION_FILTER_ALL: return Global.ZEN_MODE_OFF; 751 case INTERRUPTION_FILTER_PRIORITY: return Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS; 752 case INTERRUPTION_FILTER_ALARMS: return Global.ZEN_MODE_ALARMS; 753 case INTERRUPTION_FILTER_NONE: return Global.ZEN_MODE_NO_INTERRUPTIONS; 754 default: return defValue; 755 } 756 } 757 } 758