blob: 324a0ab8fc0cc4ad77a17594ae3a8f135decf311 [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
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
Julia Reynolds81afbcd2016-02-09 14:54:08 -050019import com.android.internal.util.Preconditions;
20
John Spurlock1fc476d2015-04-14 16:05:20 -040021import android.annotation.NonNull;
22import android.annotation.Nullable;
John Spurlockb4782522014-08-22 14:54:46 -040023import android.annotation.SdkConstant;
Christoph Studer4600f9b2014-07-22 22:44:43 +020024import android.app.Notification.Builder;
John Spurlockb4782522014-08-22 14:54:46 -040025import android.content.ComponentName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080026import android.content.Context;
Dan Sandler994349c2015-04-15 11:02:54 -040027import android.content.pm.ParceledListSlice;
Dan Sandlerd63f9322015-05-06 15:18:49 -040028import android.graphics.drawable.Icon;
John Spurlockb2278d62015-04-07 12:47:12 -040029import android.net.Uri;
Dan Sandler4e787062015-06-17 15:09:48 -040030import android.os.Build;
John Spurlock2b122f42014-08-27 16:29:47 -040031import android.os.Bundle;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080032import android.os.Handler;
33import android.os.IBinder;
John Spurlock1fc476d2015-04-14 16:05:20 -040034import android.os.Parcel;
35import android.os.Parcelable;
Jeff Sharkey69ddab42012-08-25 00:05:46 -070036import android.os.RemoteException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080037import android.os.ServiceManager;
Jeff Sharkeya14acd22013-04-02 18:27:45 -070038import android.os.StrictMode;
Dianne Hackborn41203752012-08-31 14:05:51 -070039import android.os.UserHandle;
John Spurlockb2278d62015-04-07 12:47:12 -040040import android.provider.Settings.Global;
John Spurlockcdb57ae2015-02-11 19:04:11 -050041import android.service.notification.IConditionListener;
Julia Reynolds81afbcd2016-02-09 14:54:08 -050042import android.service.notification.NotificationListenerService;
Dan Sandler994349c2015-04-15 11:02:54 -040043import android.service.notification.StatusBarNotification;
John Spurlockcdb57ae2015-02-11 19:04:11 -050044import android.service.notification.ZenModeConfig;
John Spurlock80774932015-05-07 17:38:50 -040045import android.util.ArraySet;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080046import android.util.Log;
47
John Spurlock1fc476d2015-04-14 16:05:20 -040048import java.util.Objects;
Dan Sandler994349c2015-04-15 11:02:54 -040049import java.util.List;
John Spurlock1fc476d2015-04-14 16:05:20 -040050
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080051/**
52 * Class to notify the user of events that happen. This is how you tell
53 * the user that something has happened in the background. {@more}
54 *
55 * Notifications can take different forms:
56 * <ul>
57 * <li>A persistent icon that goes in the status bar and is accessible
58 * through the launcher, (when the user selects it, a designated Intent
59 * can be launched),</li>
60 * <li>Turning on or flashing LEDs on the device, or</li>
61 * <li>Alerting the user by flashing the backlight, playing a sound,
62 * or vibrating.</li>
63 * </ul>
64 *
65 * <p>
Peter Collingbourneb97c3492010-10-13 20:04:52 +010066 * Each of the notify methods takes an int id parameter and optionally a
67 * {@link String} tag parameter, which may be {@code null}. These parameters
68 * are used to form a pair (tag, id), or ({@code null}, id) if tag is
69 * unspecified. This pair identifies this notification from your app to the
70 * system, so that pair should be unique within your app. If you call one
71 * of the notify methods with a (tag, id) pair that is currently active and
72 * a new set of notification parameters, it will be updated. For example,
73 * if you pass a new status bar icon, the old icon in the status bar will
74 * be replaced with the new one. This is also the same tag and id you pass
75 * to the {@link #cancel(int)} or {@link #cancel(String, int)} method to clear
76 * this notification.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080077 *
78 * <p>
79 * You do not instantiate this class directly; instead, retrieve it through
80 * {@link android.content.Context#getSystemService}.
81 *
Joe Fernandez558459f2011-10-13 16:47:36 -070082 * <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 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080089 * @see android.app.Notification
90 * @see android.content.Context#getSystemService
91 */
92public class NotificationManager
93{
94 private static String TAG = "NotificationManager";
Joe Onorato43a17652011-04-06 19:22:23 -070095 private static boolean localLOGV = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080096
John Spurlockb4782522014-08-22 14:54:46 -040097 /**
98 * Intent that is broadcast when the state of {@link #getEffectsSuppressor()} changes.
99 * This broadcast is only sent to registered receivers.
100 *
101 * @hide
102 */
103 @SdkConstant(SdkConstant.SdkConstantType.BROADCAST_INTENT_ACTION)
104 public static final String ACTION_EFFECTS_SUPPRESSOR_CHANGED
105 = "android.os.action.ACTION_EFFECTS_SUPPRESSOR_CHANGED";
106
John Spurlock1fc476d2015-04-14 16:05:20 -0400107 /**
John Spurlock7c74f782015-06-04 13:01:42 -0400108 * Intent that is broadcast when the state of {@link #isNotificationPolicyAccessGranted()}
109 * changes.
110 *
111 * This broadcast is only sent to registered receivers, and only to the apps that have changed.
112 */
113 @SdkConstant(SdkConstant.SdkConstantType.BROADCAST_INTENT_ACTION)
114 public static final String ACTION_NOTIFICATION_POLICY_ACCESS_GRANTED_CHANGED
115 = "android.app.action.NOTIFICATION_POLICY_ACCESS_GRANTED_CHANGED";
116
117 /**
John Spurlock1fc476d2015-04-14 16:05:20 -0400118 * Intent that is broadcast when the state of getNotificationPolicy() changes.
119 * This broadcast is only sent to registered receivers.
120 */
121 @SdkConstant(SdkConstant.SdkConstantType.BROADCAST_INTENT_ACTION)
122 public static final String ACTION_NOTIFICATION_POLICY_CHANGED
123 = "android.app.action.NOTIFICATION_POLICY_CHANGED";
124
John Spurlock80774932015-05-07 17:38:50 -0400125 /**
126 * Intent that is broadcast when the state of getCurrentInterruptionFilter() changes.
127 * This broadcast is only sent to registered receivers.
128 */
129 @SdkConstant(SdkConstant.SdkConstantType.BROADCAST_INTENT_ACTION)
130 public static final String ACTION_INTERRUPTION_FILTER_CHANGED
131 = "android.app.action.INTERRUPTION_FILTER_CHANGED";
132
133 /**
Jason Monka9927322015-12-13 16:22:37 -0500134 * Intent that is broadcast when the state of getCurrentInterruptionFilter() changes.
135 * @hide
136 */
137 @SdkConstant(SdkConstant.SdkConstantType.BROADCAST_INTENT_ACTION)
138 public static final String ACTION_INTERRUPTION_FILTER_CHANGED_INTERNAL
139 = "android.app.action.INTERRUPTION_FILTER_CHANGED_INTERNAL";
140
141 /**
John Spurlock80774932015-05-07 17:38:50 -0400142 * {@link #getCurrentInterruptionFilter() Interruption filter} constant -
143 * Normal interruption filter.
144 */
145 public static final int INTERRUPTION_FILTER_ALL = 1;
146
147 /**
148 * {@link #getCurrentInterruptionFilter() Interruption filter} constant -
149 * Priority interruption filter.
150 */
151 public static final int INTERRUPTION_FILTER_PRIORITY = 2;
152
153 /**
154 * {@link #getCurrentInterruptionFilter() Interruption filter} constant -
155 * No interruptions filter.
156 */
157 public static final int INTERRUPTION_FILTER_NONE = 3;
158
159 /**
160 * {@link #getCurrentInterruptionFilter() Interruption filter} constant -
161 * Alarms only interruption filter.
162 */
163 public static final int INTERRUPTION_FILTER_ALARMS = 4;
164
165 /** {@link #getCurrentInterruptionFilter() Interruption filter} constant - returned when
166 * the value is unavailable for any reason.
167 */
168 public static final int INTERRUPTION_FILTER_UNKNOWN = 0;
169
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800170 private static INotificationManager sService;
171
Dianne Hackbornd8a43f62009-08-17 23:33:56 -0700172 /** @hide */
173 static public INotificationManager getService()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800174 {
175 if (sService != null) {
176 return sService;
177 }
178 IBinder b = ServiceManager.getService("notification");
179 sService = INotificationManager.Stub.asInterface(b);
180 return sService;
181 }
182
183 /*package*/ NotificationManager(Context context, Handler handler)
184 {
185 mContext = context;
186 }
187
Jeff Sharkey69ddab42012-08-25 00:05:46 -0700188 /** {@hide} */
189 public static NotificationManager from(Context context) {
190 return (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
191 }
192
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800193 /**
Daniel Sandlere97a3bc2011-02-07 16:47:07 -0500194 * Post a notification to be shown in the status bar. If a notification with
195 * the same id has already been posted by your application and has not yet been canceled, it
196 * will be replaced by the updated information.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800197 *
198 * @param id An identifier for this notification unique within your
199 * application.
Daniel Sandlere97a3bc2011-02-07 16:47:07 -0500200 * @param notification A {@link Notification} object describing what to show the user. Must not
201 * be null.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800202 */
203 public void notify(int id, Notification notification)
204 {
Fred Quintana6ecaff12009-09-25 14:23:13 -0700205 notify(null, id, notification);
206 }
207
208 /**
Daniel Sandlere97a3bc2011-02-07 16:47:07 -0500209 * Post a notification to be shown in the status bar. If a notification with
210 * the same tag and id has already been posted by your application and has not yet been
211 * canceled, it will be replaced by the updated information.
Fred Quintana6ecaff12009-09-25 14:23:13 -0700212 *
Peter Collingbourneb97c3492010-10-13 20:04:52 +0100213 * @param tag A string identifier for this notification. May be {@code null}.
214 * @param id An identifier for this notification. The pair (tag, id) must be unique
215 * within your application.
Daniel Sandlere97a3bc2011-02-07 16:47:07 -0500216 * @param notification A {@link Notification} object describing what to
217 * show the user. Must not be null.
Fred Quintana6ecaff12009-09-25 14:23:13 -0700218 */
219 public void notify(String tag, int id, Notification notification)
220 {
Julia Reynoldsd9228f12015-10-20 10:37:27 -0400221 notifyAsUser(tag, id, notification, new UserHandle(UserHandle.myUserId()));
Dianne Hackborn41203752012-08-31 14:05:51 -0700222 }
223
224 /**
225 * @hide
226 */
227 public void notifyAsUser(String tag, int id, Notification notification, UserHandle user)
228 {
229 int[] idOut = new int[1];
230 INotificationManager service = getService();
231 String pkg = mContext.getPackageName();
Julia Reynoldsda303542015-11-23 14:00:20 -0500232 // Fix the notification as best we can.
233 Notification.addFieldsFromContext(mContext, notification);
Jeff Sharkey65c4a2b2012-09-25 17:22:27 -0700234 if (notification.sound != null) {
235 notification.sound = notification.sound.getCanonicalUri();
Jeff Sharkeya14acd22013-04-02 18:27:45 -0700236 if (StrictMode.vmFileUriExposureEnabled()) {
Jeff Sharkeyac3be9a2016-02-01 10:39:30 -0700237 notification.sound.checkFileUriExposed("Notification.sound");
Jeff Sharkeya14acd22013-04-02 18:27:45 -0700238 }
Jeff Sharkey65c4a2b2012-09-25 17:22:27 -0700239 }
Dan Sandlerd63f9322015-05-06 15:18:49 -0400240 fixLegacySmallIcon(notification, pkg);
Julia Reynoldsd9228f12015-10-20 10:37:27 -0400241 if (mContext.getApplicationInfo().targetSdkVersion > Build.VERSION_CODES.LOLLIPOP_MR1) {
242 if (notification.getSmallIcon() == null) {
243 throw new IllegalArgumentException("Invalid notification (no valid small icon): "
244 + notification);
245 }
246 }
Dianne Hackborn41203752012-08-31 14:05:51 -0700247 if (localLOGV) Log.v(TAG, pkg + ": notify(" + id + ", " + notification + ")");
Julia Reynoldsd9228f12015-10-20 10:37:27 -0400248 final Notification copy = notification.clone();
Julia Reynoldsd4ea7412016-02-17 14:00:56 -0500249 Builder.stripForDelivery(copy);
Dianne Hackborn41203752012-08-31 14:05:51 -0700250 try {
Dianne Hackborn95d78532013-09-11 09:51:14 -0700251 service.enqueueNotificationWithTag(pkg, mContext.getOpPackageName(), tag, id,
Julia Reynoldsd9228f12015-10-20 10:37:27 -0400252 copy, idOut, user.getIdentifier());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800253 if (id != idOut[0]) {
254 Log.w(TAG, "notify: id corrupted: sent " + id + ", got back " + idOut[0]);
255 }
256 } catch (RemoteException e) {
257 }
258 }
259
Dan Sandlerd63f9322015-05-06 15:18:49 -0400260 private void fixLegacySmallIcon(Notification n, String pkg) {
261 if (n.getSmallIcon() == null && n.icon != 0) {
262 n.setSmallIcon(Icon.createWithResource(pkg, n.icon));
263 }
264 }
265
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800266 /**
267 * Cancel a previously shown notification. If it's transient, the view
268 * will be hidden. If it's persistent, it will be removed from the status
269 * bar.
270 */
271 public void cancel(int id)
272 {
Fred Quintana6ecaff12009-09-25 14:23:13 -0700273 cancel(null, id);
274 }
275
276 /**
277 * Cancel a previously shown notification. If it's transient, the view
278 * will be hidden. If it's persistent, it will be removed from the status
279 * bar.
280 */
281 public void cancel(String tag, int id)
282 {
Julia Reynoldsd9228f12015-10-20 10:37:27 -0400283 cancelAsUser(tag, id, new UserHandle(UserHandle.myUserId()));
Dianne Hackborn41203752012-08-31 14:05:51 -0700284 }
285
286 /**
287 * @hide
288 */
289 public void cancelAsUser(String tag, int id, UserHandle user)
290 {
291 INotificationManager service = getService();
292 String pkg = mContext.getPackageName();
293 if (localLOGV) Log.v(TAG, pkg + ": cancel(" + id + ")");
294 try {
295 service.cancelNotificationWithTag(pkg, tag, id, user.getIdentifier());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800296 } catch (RemoteException e) {
297 }
298 }
299
300 /**
301 * Cancel all previously shown notifications. See {@link #cancel} for the
302 * detailed behavior.
303 */
304 public void cancelAll()
305 {
306 INotificationManager service = getService();
307 String pkg = mContext.getPackageName();
308 if (localLOGV) Log.v(TAG, pkg + ": cancelAll()");
309 try {
Dianne Hackborn41203752012-08-31 14:05:51 -0700310 service.cancelAllNotifications(pkg, UserHandle.myUserId());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800311 } catch (RemoteException e) {
312 }
313 }
314
John Spurlockb4782522014-08-22 14:54:46 -0400315 /**
316 * @hide
317 */
318 public ComponentName getEffectsSuppressor() {
319 INotificationManager service = getService();
320 try {
321 return service.getEffectsSuppressor();
322 } catch (RemoteException e) {
323 return null;
324 }
325 }
326
John Spurlock2b122f42014-08-27 16:29:47 -0400327 /**
328 * @hide
329 */
330 public boolean matchesCallFilter(Bundle extras) {
331 INotificationManager service = getService();
332 try {
333 return service.matchesCallFilter(extras);
334 } catch (RemoteException e) {
335 return false;
336 }
337 }
338
John Spurlock530052a2014-11-30 16:26:19 -0500339 /**
340 * @hide
341 */
342 public boolean isSystemConditionProviderEnabled(String path) {
343 INotificationManager service = getService();
344 try {
345 return service.isSystemConditionProviderEnabled(path);
346 } catch (RemoteException e) {
347 return false;
348 }
349 }
350
John Spurlockcdb57ae2015-02-11 19:04:11 -0500351 /**
352 * @hide
353 */
John Spurlockb2278d62015-04-07 12:47:12 -0400354 public void setZenMode(int mode, Uri conditionId, String reason) {
John Spurlockcdb57ae2015-02-11 19:04:11 -0500355 INotificationManager service = getService();
356 try {
John Spurlockb2278d62015-04-07 12:47:12 -0400357 service.setZenMode(mode, conditionId, reason);
John Spurlockcdb57ae2015-02-11 19:04:11 -0500358 } catch (RemoteException e) {
359 }
360 }
361
362 /**
363 * @hide
364 */
John Spurlockb2278d62015-04-07 12:47:12 -0400365 public int getZenMode() {
John Spurlockcdb57ae2015-02-11 19:04:11 -0500366 INotificationManager service = getService();
367 try {
John Spurlockb2278d62015-04-07 12:47:12 -0400368 return service.getZenMode();
John Spurlockcdb57ae2015-02-11 19:04:11 -0500369 } catch (RemoteException e) {
370 }
John Spurlockb2278d62015-04-07 12:47:12 -0400371 return Global.ZEN_MODE_OFF;
John Spurlockcdb57ae2015-02-11 19:04:11 -0500372 }
373
374 /**
375 * @hide
376 */
John Spurlockb2278d62015-04-07 12:47:12 -0400377 public ZenModeConfig getZenModeConfig() {
John Spurlockcdb57ae2015-02-11 19:04:11 -0500378 INotificationManager service = getService();
379 try {
John Spurlockb2278d62015-04-07 12:47:12 -0400380 return service.getZenModeConfig();
John Spurlockcdb57ae2015-02-11 19:04:11 -0500381 } catch (RemoteException e) {
382 }
383 return null;
384 }
385
John Spurlock1fc476d2015-04-14 16:05:20 -0400386 /**
Julia Reynolds43b70cd2016-01-14 15:05:34 -0500387 * @hide
388 */
389 public int getRuleInstanceCount(ComponentName owner) {
390 INotificationManager service = getService();
391 try {
392 return service.getRuleInstanceCount(owner);
393 } catch (RemoteException e) {
394 }
395 return 0;
396 }
397
398 /**
Julia Reynoldsa47a27f2015-08-24 08:31:47 -0400399 * Returns AutomaticZenRules owned by the caller.
400 *
401 * <p>
402 * Only available if policy access is granted to this package.
403 * See {@link #isNotificationPolicyAccessGranted}.
404 */
405 public List<AutomaticZenRule> getAutomaticZenRules() {
406 INotificationManager service = getService();
407 try {
408 return service.getAutomaticZenRules();
409 } catch (RemoteException e) {
410 }
411 return null;
412 }
413
414 /**
Julia Reynolds4fe98d62015-10-06 16:23:41 -0400415 * Returns the AutomaticZenRule with the given id, if it exists and the caller has access.
Julia Reynoldsa47a27f2015-08-24 08:31:47 -0400416 *
417 * <p>
418 * Only available if policy access is granted to this package.
419 * See {@link #isNotificationPolicyAccessGranted}.
420 *
421 * <p>
Julia Reynolds4fe98d62015-10-06 16:23:41 -0400422 * Returns null if there are no zen rules that match the given id, or if the calling package
Julia Reynoldsa47a27f2015-08-24 08:31:47 -0400423 * doesn't own the matching rule. See {@link AutomaticZenRule#getOwner}.
424 */
Julia Reynolds4fe98d62015-10-06 16:23:41 -0400425 public AutomaticZenRule getAutomaticZenRule(String id) {
Julia Reynoldsa47a27f2015-08-24 08:31:47 -0400426 INotificationManager service = getService();
427 try {
Julia Reynolds4fe98d62015-10-06 16:23:41 -0400428 return service.getAutomaticZenRule(id);
Julia Reynoldsa47a27f2015-08-24 08:31:47 -0400429 } catch (RemoteException e) {
430 }
431 return null;
432 }
433
434 /**
Julia Reynolds4fe98d62015-10-06 16:23:41 -0400435 * Creates the given zen rule.
Julia Reynoldsa47a27f2015-08-24 08:31:47 -0400436 *
437 * <p>
438 * Only available if policy access is granted to this package.
439 * See {@link #isNotificationPolicyAccessGranted}.
440 *
Julia Reynolds4fe98d62015-10-06 16:23:41 -0400441 * @param automaticZenRule the rule to create.
442 * @return A fully populated {@link AutomaticZenRule} if the rule was persisted successfully,
443 * null otherwise.
Julia Reynoldsa47a27f2015-08-24 08:31:47 -0400444 */
Julia Reynolds4fe98d62015-10-06 16:23:41 -0400445 public AutomaticZenRule addAutomaticZenRule(AutomaticZenRule automaticZenRule) {
Julia Reynoldsa47a27f2015-08-24 08:31:47 -0400446 INotificationManager service = getService();
447 try {
Julia Reynolds4fe98d62015-10-06 16:23:41 -0400448 return service.addAutomaticZenRule(automaticZenRule);
Julia Reynoldsa47a27f2015-08-24 08:31:47 -0400449 } catch (RemoteException e) {
450 }
Julia Reynolds4fe98d62015-10-06 16:23:41 -0400451 return null;
Julia Reynoldsa47a27f2015-08-24 08:31:47 -0400452 }
453
454 /**
Julia Reynolds4fe98d62015-10-06 16:23:41 -0400455 * Updates the given zen rule.
Julia Reynoldsa47a27f2015-08-24 08:31:47 -0400456 *
457 * <p>
458 * Only available if policy access is granted to this package.
459 * See {@link #isNotificationPolicyAccessGranted}.
460 *
461 * <p>
462 * Callers can only update rules that they own. See {@link AutomaticZenRule#getOwner}.
Julia Reynolds4fe98d62015-10-06 16:23:41 -0400463 * @param automaticZenRule the rule to update.
Julia Reynoldsa47a27f2015-08-24 08:31:47 -0400464 * @return Whether the rule was successfully updated.
465 */
Julia Reynolds4fe98d62015-10-06 16:23:41 -0400466 public boolean updateAutomaticZenRule(AutomaticZenRule automaticZenRule) {
Julia Reynoldsa47a27f2015-08-24 08:31:47 -0400467 INotificationManager service = getService();
468 try {
Julia Reynolds4fe98d62015-10-06 16:23:41 -0400469 return service.updateAutomaticZenRule(automaticZenRule);
Julia Reynoldsa47a27f2015-08-24 08:31:47 -0400470 } catch (RemoteException e) {
471 }
472 return false;
473 }
474
475 /**
Julia Reynolds4fe98d62015-10-06 16:23:41 -0400476 * Deletes the automatic zen rule with the given id.
Julia Reynoldsa47a27f2015-08-24 08:31:47 -0400477 *
478 * <p>
479 * Only available if policy access is granted to this package.
480 * See {@link #isNotificationPolicyAccessGranted}.
481 *
482 * <p>
483 * Callers can only delete rules that they own. See {@link AutomaticZenRule#getOwner}.
Julia Reynolds4fe98d62015-10-06 16:23:41 -0400484 * @param id the id of the rule to delete.
Julia Reynoldsa47a27f2015-08-24 08:31:47 -0400485 * @return Whether the rule was successfully deleted.
486 */
Julia Reynolds4fe98d62015-10-06 16:23:41 -0400487 public boolean removeAutomaticZenRule(String id) {
Julia Reynoldsa47a27f2015-08-24 08:31:47 -0400488 INotificationManager service = getService();
489 try {
Julia Reynolds4fe98d62015-10-06 16:23:41 -0400490 return service.removeAutomaticZenRule(id);
Julia Reynoldsa47a27f2015-08-24 08:31:47 -0400491 } catch (RemoteException e) {
492 }
493 return false;
494 }
495
496 /**
Julia Reynoldsc8e54e82015-11-30 16:43:05 -0500497 * Deletes all automatic zen rules owned by the given package.
498 *
499 * @hide
500 */
501 public boolean removeAutomaticZenRules(String packageName) {
502 INotificationManager service = getService();
503 try {
504 return service.removeAutomaticZenRules(packageName);
505 } catch (RemoteException e) {
506 }
507 return false;
508 }
509
Julia Reynoldsef37f282016-02-12 09:11:27 -0500510 public int getImportance() {
Julia Reynolds81afbcd2016-02-09 14:54:08 -0500511 INotificationManager service = getService();
512 try {
Julia Reynoldsef37f282016-02-12 09:11:27 -0500513 return service.getPackageImportance(mContext.getPackageName());
Julia Reynolds81afbcd2016-02-09 14:54:08 -0500514 } catch (RemoteException e) {
515 }
516 return NotificationListenerService.Ranking.IMPORTANCE_UNSPECIFIED;
517 }
518
519 public boolean areNotificationsEnabled() {
520 INotificationManager service = getService();
521 try {
522 return service.areNotificationsEnabled(mContext.getPackageName());
523 } catch (RemoteException e) {
524 }
525 return false;
526 }
527
Julia Reynoldsc8e54e82015-11-30 16:43:05 -0500528 /**
John Spurlock80774932015-05-07 17:38:50 -0400529 * Checks the ability to read/modify notification policy for the calling package.
John Spurlock1fc476d2015-04-14 16:05:20 -0400530 *
John Spurlock7c74f782015-06-04 13:01:42 -0400531 * <p>
John Spurlock80774932015-05-07 17:38:50 -0400532 * Returns true if the calling package can read/modify notification policy.
John Spurlock7c74f782015-06-04 13:01:42 -0400533 *
534 * <p>
535 * Request policy access by sending the user to the activity that matches the system intent
536 * action {@link android.provider.Settings#ACTION_NOTIFICATION_POLICY_ACCESS_SETTINGS}.
537 *
538 * <p>
539 * Use {@link #ACTION_NOTIFICATION_POLICY_ACCESS_GRANTED_CHANGED} to listen for
540 * user grant or denial of this access.
John Spurlock1fc476d2015-04-14 16:05:20 -0400541 */
John Spurlock80774932015-05-07 17:38:50 -0400542 public boolean isNotificationPolicyAccessGranted() {
John Spurlock1fc476d2015-04-14 16:05:20 -0400543 INotificationManager service = getService();
544 try {
John Spurlock80774932015-05-07 17:38:50 -0400545 return service.isNotificationPolicyAccessGranted(mContext.getOpPackageName());
546 } catch (RemoteException e) {
547 }
548 return false;
549 }
550
551 /** @hide */
552 public boolean isNotificationPolicyAccessGrantedForPackage(String pkg) {
553 INotificationManager service = getService();
554 try {
555 return service.isNotificationPolicyAccessGrantedForPackage(pkg);
John Spurlock1fc476d2015-04-14 16:05:20 -0400556 } catch (RemoteException e) {
557 }
558 return false;
559 }
560
561 /**
562 * Gets the current notification policy.
563 *
John Spurlock80774932015-05-07 17:38:50 -0400564 * <p>
John Spurlock7c74f782015-06-04 13:01:42 -0400565 * Only available if policy access is granted to this package.
566 * See {@link #isNotificationPolicyAccessGranted}.
John Spurlock1fc476d2015-04-14 16:05:20 -0400567 */
John Spurlock80774932015-05-07 17:38:50 -0400568 public Policy getNotificationPolicy() {
John Spurlock1fc476d2015-04-14 16:05:20 -0400569 INotificationManager service = getService();
570 try {
John Spurlock80774932015-05-07 17:38:50 -0400571 return service.getNotificationPolicy(mContext.getOpPackageName());
John Spurlock1fc476d2015-04-14 16:05:20 -0400572 } catch (RemoteException e) {
573 }
574 return null;
575 }
576
577 /**
578 * Sets the current notification policy.
579 *
John Spurlock80774932015-05-07 17:38:50 -0400580 * <p>
John Spurlock7c74f782015-06-04 13:01:42 -0400581 * Only available if policy access is granted to this package.
582 * See {@link #isNotificationPolicyAccessGranted}.
John Spurlock80774932015-05-07 17:38:50 -0400583 *
John Spurlock1fc476d2015-04-14 16:05:20 -0400584 * @param policy The new desired policy.
585 */
John Spurlock80774932015-05-07 17:38:50 -0400586 public void setNotificationPolicy(@NonNull Policy policy) {
John Spurlock1fc476d2015-04-14 16:05:20 -0400587 checkRequired("policy", policy);
588 INotificationManager service = getService();
589 try {
John Spurlock80774932015-05-07 17:38:50 -0400590 service.setNotificationPolicy(mContext.getOpPackageName(), policy);
John Spurlock1fc476d2015-04-14 16:05:20 -0400591 } catch (RemoteException e) {
592 }
593 }
594
John Spurlock80774932015-05-07 17:38:50 -0400595 /** @hide */
596 public void setNotificationPolicyAccessGranted(String pkg, boolean granted) {
597 INotificationManager service = getService();
598 try {
599 service.setNotificationPolicyAccessGranted(pkg, granted);
600 } catch (RemoteException e) {
601 }
602 }
603
604 /** @hide */
605 public ArraySet<String> getPackagesRequestingNotificationPolicyAccess() {
606 INotificationManager service = getService();
607 try {
608 final String[] pkgs = service.getPackagesRequestingNotificationPolicyAccess();
609 if (pkgs != null && pkgs.length > 0) {
610 final ArraySet<String> rt = new ArraySet<>(pkgs.length);
611 for (int i = 0; i < pkgs.length; i++) {
612 rt.add(pkgs[i]);
613 }
614 return rt;
615 }
616 } catch (RemoteException e) {
617 }
618 return new ArraySet<String>();
619 }
620
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800621 private Context mContext;
John Spurlock1fc476d2015-04-14 16:05:20 -0400622
623 private static void checkRequired(String name, Object value) {
624 if (value == null) {
625 throw new IllegalArgumentException(name + " is required");
626 }
627 }
628
629 /**
630 * Notification policy configuration. Represents user-preferences for notification
631 * filtering and prioritization.
632 */
633 public static class Policy implements android.os.Parcelable {
634 /** Reminder notifications are prioritized. */
635 public static final int PRIORITY_CATEGORY_REMINDERS = 1 << 0;
636 /** Event notifications are prioritized. */
637 public static final int PRIORITY_CATEGORY_EVENTS = 1 << 1;
638 /** Message notifications are prioritized. */
639 public static final int PRIORITY_CATEGORY_MESSAGES = 1 << 2;
640 /** Calls are prioritized. */
641 public static final int PRIORITY_CATEGORY_CALLS = 1 << 3;
642 /** Calls from repeat callers are prioritized. */
643 public static final int PRIORITY_CATEGORY_REPEAT_CALLERS = 1 << 4;
644
645 private static final int[] ALL_PRIORITY_CATEGORIES = {
646 PRIORITY_CATEGORY_REMINDERS,
647 PRIORITY_CATEGORY_EVENTS,
648 PRIORITY_CATEGORY_MESSAGES,
649 PRIORITY_CATEGORY_CALLS,
650 PRIORITY_CATEGORY_REPEAT_CALLERS,
651 };
652
653 /** Any sender is prioritized. */
654 public static final int PRIORITY_SENDERS_ANY = 0;
655 /** Saved contacts are prioritized. */
656 public static final int PRIORITY_SENDERS_CONTACTS = 1;
657 /** Only starred contacts are prioritized. */
658 public static final int PRIORITY_SENDERS_STARRED = 2;
659
660 /** Notification categories to prioritize. Bitmask of PRIORITY_CATEGORY_* constants. */
661 public final int priorityCategories;
662
John Spurlock80774932015-05-07 17:38:50 -0400663 /** Notification senders to prioritize for calls. One of:
John Spurlock1fc476d2015-04-14 16:05:20 -0400664 * PRIORITY_SENDERS_ANY, PRIORITY_SENDERS_CONTACTS, PRIORITY_SENDERS_STARRED */
John Spurlock80774932015-05-07 17:38:50 -0400665 public final int priorityCallSenders;
John Spurlock1fc476d2015-04-14 16:05:20 -0400666
John Spurlock80774932015-05-07 17:38:50 -0400667 /** Notification senders to prioritize for messages. One of:
668 * PRIORITY_SENDERS_ANY, PRIORITY_SENDERS_CONTACTS, PRIORITY_SENDERS_STARRED */
669 public final int priorityMessageSenders;
670
Julia Reynoldsd5607292016-02-05 15:25:58 -0500671 /**
672 * @hide
673 */
Julia Reynoldsf612869ae2015-11-05 16:48:55 -0500674 public static final int SUPPRESSED_EFFECTS_UNSET = -1;
Julia Reynoldsd5607292016-02-05 15:25:58 -0500675 /**
676 * Whether notification suppressed by DND should not interruption visually when the screen
677 * is off.
678 */
679 public static final int SUPPRESSED_EFFECT_SCREEN_OFF = 1 << 0;
680 /**
681 * Whether notification suppressed by DND should not interruption visually when the screen
682 * is on.
683 */
684 public static final int SUPPRESSED_EFFECT_SCREEN_ON = 1 << 1;
Julia Reynoldsf612869ae2015-11-05 16:48:55 -0500685
686 private static final int[] ALL_SUPPRESSED_EFFECTS = {
Julia Reynoldsd5607292016-02-05 15:25:58 -0500687 SUPPRESSED_EFFECT_SCREEN_OFF,
Julia Reynolds61721582016-01-05 08:35:25 -0500688 SUPPRESSED_EFFECT_SCREEN_ON,
Julia Reynoldsf612869ae2015-11-05 16:48:55 -0500689 };
690
691 /**
692 * Visual effects to suppress for a notification that is filtered by Do Not Disturb mode.
693 * Bitmask of SUPPRESSED_EFFECT_* constants.
694 */
695 public final int suppressedVisualEffects;
696
697
698 @Deprecated
John Spurlock80774932015-05-07 17:38:50 -0400699 public Policy(int priorityCategories, int priorityCallSenders, int priorityMessageSenders) {
Julia Reynoldsf612869ae2015-11-05 16:48:55 -0500700 this(priorityCategories, priorityCallSenders, priorityMessageSenders,
701 SUPPRESSED_EFFECTS_UNSET);
702 }
703
704 public Policy(int priorityCategories, int priorityCallSenders, int priorityMessageSenders,
705 int suppressedVisualEffects) {
John Spurlock1fc476d2015-04-14 16:05:20 -0400706 this.priorityCategories = priorityCategories;
John Spurlock80774932015-05-07 17:38:50 -0400707 this.priorityCallSenders = priorityCallSenders;
708 this.priorityMessageSenders = priorityMessageSenders;
Julia Reynoldsf612869ae2015-11-05 16:48:55 -0500709 this.suppressedVisualEffects = suppressedVisualEffects;
John Spurlock1fc476d2015-04-14 16:05:20 -0400710 }
711
712 /** @hide */
713 public Policy(Parcel source) {
Julia Reynoldsf612869ae2015-11-05 16:48:55 -0500714 this(source.readInt(), source.readInt(), source.readInt(), source.readInt());
John Spurlock1fc476d2015-04-14 16:05:20 -0400715 }
716
717 @Override
718 public void writeToParcel(Parcel dest, int flags) {
719 dest.writeInt(priorityCategories);
John Spurlock80774932015-05-07 17:38:50 -0400720 dest.writeInt(priorityCallSenders);
721 dest.writeInt(priorityMessageSenders);
Julia Reynoldsf612869ae2015-11-05 16:48:55 -0500722 dest.writeInt(suppressedVisualEffects);
John Spurlock1fc476d2015-04-14 16:05:20 -0400723 }
724
725 @Override
726 public int describeContents() {
727 return 0;
728 }
729
730 @Override
731 public int hashCode() {
Julia Reynoldsf612869ae2015-11-05 16:48:55 -0500732 return Objects.hash(priorityCategories, priorityCallSenders, priorityMessageSenders,
733 suppressedVisualEffects);
John Spurlock1fc476d2015-04-14 16:05:20 -0400734 }
735
736 @Override
737 public boolean equals(Object o) {
738 if (!(o instanceof Policy)) return false;
739 if (o == this) return true;
740 final Policy other = (Policy) o;
741 return other.priorityCategories == priorityCategories
John Spurlock80774932015-05-07 17:38:50 -0400742 && other.priorityCallSenders == priorityCallSenders
Julia Reynoldsf612869ae2015-11-05 16:48:55 -0500743 && other.priorityMessageSenders == priorityMessageSenders
744 && other.suppressedVisualEffects == suppressedVisualEffects;
John Spurlock1fc476d2015-04-14 16:05:20 -0400745 }
746
747 @Override
748 public String toString() {
749 return "NotificationManager.Policy["
750 + "priorityCategories=" + priorityCategoriesToString(priorityCategories)
John Spurlock80774932015-05-07 17:38:50 -0400751 + ",priorityCallSenders=" + prioritySendersToString(priorityCallSenders)
752 + ",priorityMessageSenders=" + prioritySendersToString(priorityMessageSenders)
Julia Reynoldsf612869ae2015-11-05 16:48:55 -0500753 + ",suppressedVisualEffects="
754 + suppressedEffectsToString(suppressedVisualEffects)
John Spurlock1fc476d2015-04-14 16:05:20 -0400755 + "]";
756 }
757
Julia Reynoldsf612869ae2015-11-05 16:48:55 -0500758 public static String suppressedEffectsToString(int effects) {
759 if (effects <= 0) return "";
760 final StringBuilder sb = new StringBuilder();
761 for (int i = 0; i < ALL_SUPPRESSED_EFFECTS.length; i++) {
762 final int effect = ALL_SUPPRESSED_EFFECTS[i];
763 if ((effects & effect) != 0) {
764 if (sb.length() > 0) sb.append(',');
765 sb.append(effectToString(effect));
766 }
767 effects &= ~effect;
768 }
769 if (effects != 0) {
770 if (sb.length() > 0) sb.append(',');
771 sb.append("UNKNOWN_").append(effects);
772 }
773 return sb.toString();
774 }
775
John Spurlock1fc476d2015-04-14 16:05:20 -0400776 public static String priorityCategoriesToString(int priorityCategories) {
777 if (priorityCategories == 0) return "";
778 final StringBuilder sb = new StringBuilder();
779 for (int i = 0; i < ALL_PRIORITY_CATEGORIES.length; i++) {
780 final int priorityCategory = ALL_PRIORITY_CATEGORIES[i];
781 if ((priorityCategories & priorityCategory) != 0) {
782 if (sb.length() > 0) sb.append(',');
783 sb.append(priorityCategoryToString(priorityCategory));
784 }
785 priorityCategories &= ~priorityCategory;
786 }
787 if (priorityCategories != 0) {
788 if (sb.length() > 0) sb.append(',');
789 sb.append("PRIORITY_CATEGORY_UNKNOWN_").append(priorityCategories);
790 }
791 return sb.toString();
792 }
793
Julia Reynoldsf612869ae2015-11-05 16:48:55 -0500794 private static String effectToString(int effect) {
795 switch (effect) {
Julia Reynoldsd5607292016-02-05 15:25:58 -0500796 case SUPPRESSED_EFFECT_SCREEN_OFF: return "SUPPRESSED_EFFECT_SCREEN_OFF";
Julia Reynolds61721582016-01-05 08:35:25 -0500797 case SUPPRESSED_EFFECT_SCREEN_ON: return "SUPPRESSED_EFFECT_SCREEN_ON";
Julia Reynoldsf612869ae2015-11-05 16:48:55 -0500798 case SUPPRESSED_EFFECTS_UNSET: return "SUPPRESSED_EFFECTS_UNSET";
799 default: return "UNKNOWN_" + effect;
800 }
801 }
802
John Spurlock1fc476d2015-04-14 16:05:20 -0400803 private static String priorityCategoryToString(int priorityCategory) {
804 switch (priorityCategory) {
805 case PRIORITY_CATEGORY_REMINDERS: return "PRIORITY_CATEGORY_REMINDERS";
806 case PRIORITY_CATEGORY_EVENTS: return "PRIORITY_CATEGORY_EVENTS";
807 case PRIORITY_CATEGORY_MESSAGES: return "PRIORITY_CATEGORY_MESSAGES";
808 case PRIORITY_CATEGORY_CALLS: return "PRIORITY_CATEGORY_CALLS";
809 case PRIORITY_CATEGORY_REPEAT_CALLERS: return "PRIORITY_CATEGORY_REPEAT_CALLERS";
810 default: return "PRIORITY_CATEGORY_UNKNOWN_" + priorityCategory;
811 }
812 }
813
814 public static String prioritySendersToString(int prioritySenders) {
815 switch (prioritySenders) {
816 case PRIORITY_SENDERS_ANY: return "PRIORITY_SENDERS_ANY";
817 case PRIORITY_SENDERS_CONTACTS: return "PRIORITY_SENDERS_CONTACTS";
818 case PRIORITY_SENDERS_STARRED: return "PRIORITY_SENDERS_STARRED";
819 default: return "PRIORITY_SENDERS_UNKNOWN_" + prioritySenders;
820 }
821 }
822
823 public static final Parcelable.Creator<Policy> CREATOR = new Parcelable.Creator<Policy>() {
824 @Override
825 public Policy createFromParcel(Parcel in) {
826 return new Policy(in);
827 }
828
829 @Override
830 public Policy[] newArray(int size) {
831 return new Policy[size];
832 }
833 };
834
John Spurlock1fc476d2015-04-14 16:05:20 -0400835 }
836
Dan Sandler994349c2015-04-15 11:02:54 -0400837 /**
838 * Recover a list of active notifications: ones that have been posted by the calling app that
839 * have not yet been dismissed by the user or {@link #cancel(String, int)}ed by the app.
840 *
841 * Each notification is embedded in a {@link StatusBarNotification} object, including the
842 * original <code>tag</code> and <code>id</code> supplied to
843 * {@link #notify(String, int, Notification) notify()}
844 * (via {@link StatusBarNotification#getTag() getTag()} and
845 * {@link StatusBarNotification#getId() getId()}) as well as a copy of the original
846 * {@link Notification} object (via {@link StatusBarNotification#getNotification()}).
847 *
848 * @return An array of {@link StatusBarNotification}.
849 */
850 public StatusBarNotification[] getActiveNotifications() {
851 final INotificationManager service = getService();
852 final String pkg = mContext.getPackageName();
853 try {
854 final ParceledListSlice<StatusBarNotification> parceledList
855 = service.getAppActiveNotifications(pkg, UserHandle.myUserId());
856 final List<StatusBarNotification> list = parceledList.getList();
857 return list.toArray(new StatusBarNotification[list.size()]);
858 } catch (RemoteException e) {
859 Log.e(TAG, "Unable to talk to notification manager. Woe!", e);
860 }
861 return new StatusBarNotification[0];
862 }
John Spurlock80774932015-05-07 17:38:50 -0400863
864 /**
865 * Gets the current notification interruption filter.
866 *
867 * <p>
868 * The interruption filter defines which notifications are allowed to interrupt the user
869 * (e.g. via sound &amp; vibration) and is applied globally.
870 * @return One of the INTERRUPTION_FILTER_ constants, or INTERRUPTION_FILTER_UNKNOWN when
871 * unavailable.
872 *
873 * <p>
John Spurlock7c74f782015-06-04 13:01:42 -0400874 * Only available if policy access is granted to this package.
875 * See {@link #isNotificationPolicyAccessGranted}.
John Spurlock80774932015-05-07 17:38:50 -0400876 */
877 public final int getCurrentInterruptionFilter() {
878 final INotificationManager service = getService();
879 try {
880 return zenModeToInterruptionFilter(service.getZenMode());
881 } catch (RemoteException e) {
882 Log.e(TAG, "Unable to talk to notification manager. Woe!", e);
883 }
884 return INTERRUPTION_FILTER_UNKNOWN;
885 }
886
887 /**
888 * Sets the current notification interruption filter.
889 *
890 * <p>
891 * The interruption filter defines which notifications are allowed to interrupt the user
892 * (e.g. via sound &amp; vibration) and is applied globally.
893 * @return One of the INTERRUPTION_FILTER_ constants, or INTERRUPTION_FILTER_UNKNOWN when
894 * unavailable.
895 *
896 * <p>
John Spurlock7c74f782015-06-04 13:01:42 -0400897 * Only available if policy access is granted to this package.
898 * See {@link #isNotificationPolicyAccessGranted}.
John Spurlock80774932015-05-07 17:38:50 -0400899 */
900 public final void setInterruptionFilter(int interruptionFilter) {
901 final INotificationManager service = getService();
902 try {
903 service.setInterruptionFilter(mContext.getOpPackageName(), interruptionFilter);
904 } catch (RemoteException e) {
905 Log.e(TAG, "Unable to talk to notification manager. Woe!", e);
906 }
907 }
908
909 /** @hide */
910 public static int zenModeToInterruptionFilter(int zen) {
911 switch (zen) {
912 case Global.ZEN_MODE_OFF: return INTERRUPTION_FILTER_ALL;
913 case Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS: return INTERRUPTION_FILTER_PRIORITY;
914 case Global.ZEN_MODE_ALARMS: return INTERRUPTION_FILTER_ALARMS;
915 case Global.ZEN_MODE_NO_INTERRUPTIONS: return INTERRUPTION_FILTER_NONE;
916 default: return INTERRUPTION_FILTER_UNKNOWN;
917 }
918 }
919
920 /** @hide */
921 public static int zenModeFromInterruptionFilter(int interruptionFilter, int defValue) {
922 switch (interruptionFilter) {
923 case INTERRUPTION_FILTER_ALL: return Global.ZEN_MODE_OFF;
924 case INTERRUPTION_FILTER_PRIORITY: return Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS;
925 case INTERRUPTION_FILTER_ALARMS: return Global.ZEN_MODE_ALARMS;
926 case INTERRUPTION_FILTER_NONE: return Global.ZEN_MODE_NO_INTERRUPTIONS;
927 default: return defValue;
928 }
929 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800930}