blob: ed7aa4a097ebde5c0f3aaf277ffd9478489b56f4 [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 Reynolds0edb50c2016-02-26 14:08:25 -050019import android.annotation.IntDef;
John Spurlock1fc476d2015-04-14 16:05:20 -040020import android.annotation.NonNull;
Julia Reynoldsa7ba45a2018-08-29 09:07:52 -040021import android.annotation.Nullable;
John Spurlockb4782522014-08-22 14:54:46 -040022import android.annotation.SdkConstant;
Julia Reynolds12ad7ca2019-01-28 09:29:16 -050023import android.annotation.SystemApi;
Jeff Sharkeyd86b8fe2017-06-02 17:36:26 -060024import android.annotation.SystemService;
Julia Reynoldsb6c1f992016-11-22 09:26:46 -050025import android.annotation.TestApi;
Mathew Inwood61e8ae62018-08-14 14:17:44 +010026import android.annotation.UnsupportedAppUsage;
Christoph Studer4600f9b2014-07-22 22:44:43 +020027import android.app.Notification.Builder;
John Spurlockb4782522014-08-22 14:54:46 -040028import android.content.ComponentName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080029import android.content.Context;
Julia Reynoldse0d711f2017-09-01 08:50:47 -040030import android.content.Intent;
Dan Sandler994349c2015-04-15 11:02:54 -040031import android.content.pm.ParceledListSlice;
Dan Sandlerd63f9322015-05-06 15:18:49 -040032import android.graphics.drawable.Icon;
John Spurlockb2278d62015-04-07 12:47:12 -040033import android.net.Uri;
Dan Sandler4e787062015-06-17 15:09:48 -040034import android.os.Build;
John Spurlock2b122f42014-08-27 16:29:47 -040035import android.os.Bundle;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080036import android.os.Handler;
37import android.os.IBinder;
John Spurlock1fc476d2015-04-14 16:05:20 -040038import android.os.Parcel;
39import android.os.Parcelable;
Jeff Sharkey69ddab42012-08-25 00:05:46 -070040import android.os.RemoteException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080041import android.os.ServiceManager;
Jeff Sharkeya14acd22013-04-02 18:27:45 -070042import android.os.StrictMode;
Dianne Hackborn41203752012-08-31 14:05:51 -070043import android.os.UserHandle;
John Spurlockb2278d62015-04-07 12:47:12 -040044import android.provider.Settings.Global;
Julia Reynolds68062072018-08-06 15:38:21 -040045import android.service.notification.Condition;
Dan Sandler994349c2015-04-15 11:02:54 -040046import android.service.notification.StatusBarNotification;
John Spurlockcdb57ae2015-02-11 19:04:11 -050047import android.service.notification.ZenModeConfig;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080048import android.util.Log;
Kweku Adams5ec78cd2017-09-25 16:29:54 -070049import android.util.proto.ProtoOutputStream;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080050
Julia Reynolds0edb50c2016-02-26 14:08:25 -050051import java.lang.annotation.Retention;
52import java.lang.annotation.RetentionPolicy;
Beverlyc629ee42018-10-02 16:14:07 -040053import java.util.ArrayList;
Geoffrey Pitsch03533712017-01-05 10:30:07 -050054import java.util.Arrays;
Julia Reynolds361e82d32016-02-26 18:19:49 -050055import java.util.HashMap;
Chris Wren5ab5c742016-05-10 15:32:23 -040056import java.util.List;
Julia Reynolds361e82d32016-02-26 18:19:49 -050057import java.util.Map;
John Spurlock1fc476d2015-04-14 16:05:20 -040058import java.util.Objects;
59
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080060/**
61 * Class to notify the user of events that happen. This is how you tell
62 * the user that something has happened in the background. {@more}
63 *
64 * Notifications can take different forms:
65 * <ul>
66 * <li>A persistent icon that goes in the status bar and is accessible
67 * through the launcher, (when the user selects it, a designated Intent
68 * can be launched),</li>
69 * <li>Turning on or flashing LEDs on the device, or</li>
70 * <li>Alerting the user by flashing the backlight, playing a sound,
71 * or vibrating.</li>
72 * </ul>
73 *
74 * <p>
Peter Collingbourneb97c3492010-10-13 20:04:52 +010075 * Each of the notify methods takes an int id parameter and optionally a
76 * {@link String} tag parameter, which may be {@code null}. These parameters
77 * are used to form a pair (tag, id), or ({@code null}, id) if tag is
78 * unspecified. This pair identifies this notification from your app to the
79 * system, so that pair should be unique within your app. If you call one
80 * of the notify methods with a (tag, id) pair that is currently active and
81 * a new set of notification parameters, it will be updated. For example,
82 * if you pass a new status bar icon, the old icon in the status bar will
83 * be replaced with the new one. This is also the same tag and id you pass
84 * to the {@link #cancel(int)} or {@link #cancel(String, int)} method to clear
85 * this notification.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080086 *
Joe Fernandez558459f2011-10-13 16:47:36 -070087 * <div class="special reference">
88 * <h3>Developer Guides</h3>
89 * <p>For a guide to creating notifications, read the
90 * <a href="{@docRoot}guide/topics/ui/notifiers/notifications.html">Status Bar Notifications</a>
91 * developer guide.</p>
92 * </div>
93 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080094 * @see android.app.Notification
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080095 */
Jeff Sharkeyd86b8fe2017-06-02 17:36:26 -060096@SystemService(Context.NOTIFICATION_SERVICE)
97public class NotificationManager {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080098 private static String TAG = "NotificationManager";
Joe Onorato43a17652011-04-06 19:22:23 -070099 private static boolean localLOGV = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800100
John Spurlockb4782522014-08-22 14:54:46 -0400101 /**
Julia Reynoldsfc9767b2018-01-22 17:45:16 -0500102 * Intent that is broadcast when an application is blocked or unblocked.
103 *
104 * This broadcast is only sent to the app whose block state has changed.
105 *
106 * Input: nothing
Julia Reynolds44ff7c92018-02-05 10:02:30 -0500107 * Output: {@link #EXTRA_BLOCKED_STATE}
Julia Reynoldsfc9767b2018-01-22 17:45:16 -0500108 */
109 @SdkConstant(SdkConstant.SdkConstantType.BROADCAST_INTENT_ACTION)
110 public static final String ACTION_APP_BLOCK_STATE_CHANGED =
111 "android.app.action.APP_BLOCK_STATE_CHANGED";
112
113 /**
Julia Reynolds3eb3ffd2017-11-16 10:11:32 -0500114 * Intent that is broadcast when a {@link NotificationChannel} is blocked
115 * (when {@link NotificationChannel#getImportance()} is {@link #IMPORTANCE_NONE}) or unblocked
116 * (when {@link NotificationChannel#getImportance()} is anything other than
117 * {@link #IMPORTANCE_NONE}).
118 *
119 * This broadcast is only sent to the app that owns the channel that has changed.
120 *
121 * Input: nothing
Julia Reynolds44ff7c92018-02-05 10:02:30 -0500122 * Output: {@link #EXTRA_NOTIFICATION_CHANNEL_ID}
123 * Output: {@link #EXTRA_BLOCKED_STATE}
Julia Reynolds3eb3ffd2017-11-16 10:11:32 -0500124 */
125 @SdkConstant(SdkConstant.SdkConstantType.BROADCAST_INTENT_ACTION)
126 public static final String ACTION_NOTIFICATION_CHANNEL_BLOCK_STATE_CHANGED =
127 "android.app.action.NOTIFICATION_CHANNEL_BLOCK_STATE_CHANGED";
128
129 /**
Julia Reynolds44ff7c92018-02-05 10:02:30 -0500130 * Extra for {@link #ACTION_NOTIFICATION_CHANNEL_BLOCK_STATE_CHANGED} containing the id of the
131 * {@link NotificationChannel} which has a new blocked state.
Julia Reynolds3eb3ffd2017-11-16 10:11:32 -0500132 *
Julia Reynolds44ff7c92018-02-05 10:02:30 -0500133 * The value will be the {@link NotificationChannel#getId()} of the channel.
Julia Reynolds3eb3ffd2017-11-16 10:11:32 -0500134 */
Julia Reynolds44ff7c92018-02-05 10:02:30 -0500135 public static final String EXTRA_NOTIFICATION_CHANNEL_ID =
136 "android.app.extra.NOTIFICATION_CHANNEL_ID";
137
138 /**
139 * Extra for {@link #ACTION_NOTIFICATION_CHANNEL_GROUP_BLOCK_STATE_CHANGED} containing the id
140 * of the {@link NotificationChannelGroup} which has a new blocked state.
141 *
142 * The value will be the {@link NotificationChannelGroup#getId()} of the group.
143 */
144 public static final String EXTRA_NOTIFICATION_CHANNEL_GROUP_ID =
145 "android.app.extra.NOTIFICATION_CHANNEL_GROUP_ID";
146
Julia Reynolds3eb3ffd2017-11-16 10:11:32 -0500147
148 /**
149 * Extra for {@link #ACTION_NOTIFICATION_CHANNEL_BLOCK_STATE_CHANGED} or
150 * {@link #ACTION_NOTIFICATION_CHANNEL_GROUP_BLOCK_STATE_CHANGED} containing the new blocked
151 * state as a boolean.
152 *
153 * The value will be {@code true} if this channel or group is now blocked and {@code false} if
154 * this channel or group is now unblocked.
155 */
156 public static final String EXTRA_BLOCKED_STATE = "android.app.extra.BLOCKED_STATE";
157
Julia Reynolds3eb3ffd2017-11-16 10:11:32 -0500158 /**
159 * Intent that is broadcast when a {@link NotificationChannelGroup} is
160 * {@link NotificationChannelGroup#isBlocked() blocked} or unblocked.
161 *
162 * This broadcast is only sent to the app that owns the channel group that has changed.
163 *
164 * Input: nothing
Julia Reynolds44ff7c92018-02-05 10:02:30 -0500165 * Output: {@link #EXTRA_NOTIFICATION_CHANNEL_GROUP_ID}
166 * Output: {@link #EXTRA_BLOCKED_STATE}
Julia Reynolds3eb3ffd2017-11-16 10:11:32 -0500167 */
168 @SdkConstant(SdkConstant.SdkConstantType.BROADCAST_INTENT_ACTION)
169 public static final String ACTION_NOTIFICATION_CHANNEL_GROUP_BLOCK_STATE_CHANGED =
170 "android.app.action.NOTIFICATION_CHANNEL_GROUP_BLOCK_STATE_CHANGED";
171
172 /**
John Spurlockb4782522014-08-22 14:54:46 -0400173 * Intent that is broadcast when the state of {@link #getEffectsSuppressor()} changes.
174 * This broadcast is only sent to registered receivers.
175 *
176 * @hide
177 */
178 @SdkConstant(SdkConstant.SdkConstantType.BROADCAST_INTENT_ACTION)
179 public static final String ACTION_EFFECTS_SUPPRESSOR_CHANGED
180 = "android.os.action.ACTION_EFFECTS_SUPPRESSOR_CHANGED";
181
John Spurlock1fc476d2015-04-14 16:05:20 -0400182 /**
John Spurlock7c74f782015-06-04 13:01:42 -0400183 * Intent that is broadcast when the state of {@link #isNotificationPolicyAccessGranted()}
184 * changes.
185 *
186 * This broadcast is only sent to registered receivers, and only to the apps that have changed.
187 */
188 @SdkConstant(SdkConstant.SdkConstantType.BROADCAST_INTENT_ACTION)
189 public static final String ACTION_NOTIFICATION_POLICY_ACCESS_GRANTED_CHANGED
190 = "android.app.action.NOTIFICATION_POLICY_ACCESS_GRANTED_CHANGED";
191
192 /**
John Spurlock1fc476d2015-04-14 16:05:20 -0400193 * Intent that is broadcast when the state of getNotificationPolicy() changes.
194 * This broadcast is only sent to registered receivers.
195 */
196 @SdkConstant(SdkConstant.SdkConstantType.BROADCAST_INTENT_ACTION)
197 public static final String ACTION_NOTIFICATION_POLICY_CHANGED
198 = "android.app.action.NOTIFICATION_POLICY_CHANGED";
199
John Spurlock80774932015-05-07 17:38:50 -0400200 /**
201 * Intent that is broadcast when the state of getCurrentInterruptionFilter() changes.
202 * This broadcast is only sent to registered receivers.
203 */
204 @SdkConstant(SdkConstant.SdkConstantType.BROADCAST_INTENT_ACTION)
205 public static final String ACTION_INTERRUPTION_FILTER_CHANGED
206 = "android.app.action.INTERRUPTION_FILTER_CHANGED";
207
208 /**
Jason Monka9927322015-12-13 16:22:37 -0500209 * Intent that is broadcast when the state of getCurrentInterruptionFilter() changes.
210 * @hide
211 */
212 @SdkConstant(SdkConstant.SdkConstantType.BROADCAST_INTENT_ACTION)
213 public static final String ACTION_INTERRUPTION_FILTER_CHANGED_INTERNAL
214 = "android.app.action.INTERRUPTION_FILTER_CHANGED_INTERNAL";
215
Julia Reynolds0edb50c2016-02-26 14:08:25 -0500216 /** @hide */
Jeff Sharkey6503bd82017-04-19 23:24:18 -0600217 @IntDef(prefix = { "INTERRUPTION_FILTER_" }, value = {
218 INTERRUPTION_FILTER_NONE, INTERRUPTION_FILTER_PRIORITY, INTERRUPTION_FILTER_ALARMS,
219 INTERRUPTION_FILTER_ALL, INTERRUPTION_FILTER_UNKNOWN
220 })
Julia Reynolds0edb50c2016-02-26 14:08:25 -0500221 @Retention(RetentionPolicy.SOURCE)
222 public @interface InterruptionFilter {}
223
Jason Monka9927322015-12-13 16:22:37 -0500224 /**
John Spurlock80774932015-05-07 17:38:50 -0400225 * {@link #getCurrentInterruptionFilter() Interruption filter} constant -
Julia Reynoldsdd0605b2016-04-06 10:26:54 -0400226 * Normal interruption filter - no notifications are suppressed.
John Spurlock80774932015-05-07 17:38:50 -0400227 */
228 public static final int INTERRUPTION_FILTER_ALL = 1;
229
230 /**
231 * {@link #getCurrentInterruptionFilter() Interruption filter} constant -
Julia Reynoldsdd0605b2016-04-06 10:26:54 -0400232 * Priority interruption filter - all notifications are suppressed except those that match
233 * the priority criteria. Some audio streams are muted. See
234 * {@link Policy#priorityCallSenders}, {@link Policy#priorityCategories},
235 * {@link Policy#priorityMessageSenders} to define or query this criteria. Users can
236 * additionally specify packages that can bypass this interruption filter.
John Spurlock80774932015-05-07 17:38:50 -0400237 */
238 public static final int INTERRUPTION_FILTER_PRIORITY = 2;
239
240 /**
241 * {@link #getCurrentInterruptionFilter() Interruption filter} constant -
Julia Reynoldsdd0605b2016-04-06 10:26:54 -0400242 * No interruptions filter - all notifications are suppressed and all audio streams (except
243 * those used for phone calls) and vibrations are muted.
John Spurlock80774932015-05-07 17:38:50 -0400244 */
245 public static final int INTERRUPTION_FILTER_NONE = 3;
246
247 /**
248 * {@link #getCurrentInterruptionFilter() Interruption filter} constant -
Julia Reynoldsdd0605b2016-04-06 10:26:54 -0400249 * Alarms only interruption filter - all notifications except those of category
250 * {@link Notification#CATEGORY_ALARM} are suppressed. Some audio streams are muted.
John Spurlock80774932015-05-07 17:38:50 -0400251 */
252 public static final int INTERRUPTION_FILTER_ALARMS = 4;
253
254 /** {@link #getCurrentInterruptionFilter() Interruption filter} constant - returned when
255 * the value is unavailable for any reason.
256 */
257 public static final int INTERRUPTION_FILTER_UNKNOWN = 0;
258
Chris Wren5ab5c742016-05-10 15:32:23 -0400259 /** @hide */
Jeff Sharkey6503bd82017-04-19 23:24:18 -0600260 @IntDef(prefix = { "IMPORTANCE_" }, value = {
261 IMPORTANCE_UNSPECIFIED, IMPORTANCE_NONE,
262 IMPORTANCE_MIN, IMPORTANCE_LOW, IMPORTANCE_DEFAULT, IMPORTANCE_HIGH
263 })
Chris Wren5ab5c742016-05-10 15:32:23 -0400264 @Retention(RetentionPolicy.SOURCE)
265 public @interface Importance {}
266
Julia Reynolds68062072018-08-06 15:38:21 -0400267 /**
268 * Activity Action: Launch an Automatic Zen Rule configuration screen
269 * <p>
270 * Input: Optionally, {@link #EXTRA_AUTOMATIC_RULE_ID}, if the configuration screen for an
271 * existing rule should be displayed. If the rule id is missing or null, apps should display
272 * a configuration screen where users can create a new instance of the rule.
273 * <p>
274 * Output: Nothing
275 * <p>
276 * You can have multiple activities handling this intent, if you support multiple
277 * {@link AutomaticZenRule rules}. In order for the system to properly display all of your
278 * rule types so that users can create new instances or configure existing ones, you need
279 * to add some extra metadata ({@link #META_DATA_AUTOMATIC_RULE_TYPE})
280 * to your activity tag in your manifest. If you'd like to limit the number of rules a user
281 * can create from this flow, you can additionally optionally include
282 * {@link #META_DATA_RULE_INSTANCE_LIMIT}.
283 *
284 * For example,
285 * &lt;meta-data
286 * android:name="android.app.zen.automatic.ruleType"
287 * android:value="@string/my_condition_rule">
288 * &lt;/meta-data>
289 * &lt;meta-data
290 * android:name="android.app.zen.automatic.ruleInstanceLimit"
291 * android:value="1">
292 * &lt;/meta-data>
293 * </p>
294 * </p>
295 *
296 * @see {@link #addAutomaticZenRule(AutomaticZenRule)}
297 */
298 @SdkConstant(SdkConstant.SdkConstantType.ACTIVITY_INTENT_ACTION)
299 public static final String ACTION_AUTOMATIC_ZEN_RULE =
300 "android.app.action.AUTOMATIC_ZEN_RULE";
301
302 /**
303 * Used as an optional string extra on {@link #ACTION_AUTOMATIC_ZEN_RULE} intents. If
304 * provided, contains the id of the {@link AutomaticZenRule} (as returned from
305 * {@link NotificationManager#addAutomaticZenRule(AutomaticZenRule)}) for which configuration
306 * settings should be displayed.
307 */
308 public static final String EXTRA_AUTOMATIC_RULE_ID = "android.app.extra.AUTOMATIC_RULE_ID";
309
310 /**
311 * A required {@code meta-data} tag for activities that handle
312 * {@link #ACTION_AUTOMATIC_ZEN_RULE}.
313 *
314 * This tag should contain a localized name of the type of the zen rule provided by the
315 * activity.
316 */
317 public static final String META_DATA_AUTOMATIC_RULE_TYPE = "android.app.automatic.ruleType";
318
319 /**
320 * An optional {@code meta-data} tag for activities that handle
321 * {@link #ACTION_AUTOMATIC_ZEN_RULE}.
322 *
323 * This tag should contain the maximum number of rule instances that
324 * can be created for this rule type. Omit or enter a value <= 0 to allow unlimited instances.
325 */
326 public static final String META_DATA_RULE_INSTANCE_LIMIT =
327 "android.app.zen.automatic.ruleInstanceLimit";
328
Chris Wren5ab5c742016-05-10 15:32:23 -0400329 /** Value signifying that the user has not expressed a per-app visibility override value.
330 * @hide */
331 public static final int VISIBILITY_NO_OVERRIDE = -1000;
Julia Reynolds85769912016-10-25 09:08:57 -0400332
Chris Wren5ab5c742016-05-10 15:32:23 -0400333 /**
334 * Value signifying that the user has not expressed an importance.
335 *
336 * This value is for persisting preferences, and should never be associated with
337 * an actual notification.
338 */
339 public static final int IMPORTANCE_UNSPECIFIED = -1000;
340
341 /**
Julia Reynoldsbaff4002016-12-15 11:34:26 -0500342 * A notification with no importance: does not show in the shade.
Chris Wren5ab5c742016-05-10 15:32:23 -0400343 */
344 public static final int IMPORTANCE_NONE = 0;
345
346 /**
Dianne Hackborn6e5bd3f2017-07-31 14:22:04 -0700347 * Min notification importance: only shows in the shade, below the fold. This should
348 * not be used with {@link Service#startForeground(int, Notification) Service.startForeground}
349 * since a foreground service is supposed to be something the user cares about so it does
350 * not make semantic sense to mark its notification as minimum importance. If you do this
351 * as of Android version {@link android.os.Build.VERSION_CODES#O}, the system will show
352 * a higher-priority notification about your app running in the background.
Chris Wren5ab5c742016-05-10 15:32:23 -0400353 */
354 public static final int IMPORTANCE_MIN = 1;
355
356 /**
Julia Reynolds12ad7ca2019-01-28 09:29:16 -0500357 * Low notification importance: Shows in the shade, and potentially in the status bar
358 * (see {@link #shouldHideSilentStatusBarIcons()}), but is not audibly intrusive.
Chris Wren5ab5c742016-05-10 15:32:23 -0400359 */
360 public static final int IMPORTANCE_LOW = 2;
361
362 /**
Julia Reynolds85769912016-10-25 09:08:57 -0400363 * Default notification importance: shows everywhere, makes noise, but does not visually
364 * intrude.
Chris Wren5ab5c742016-05-10 15:32:23 -0400365 */
366 public static final int IMPORTANCE_DEFAULT = 3;
367
368 /**
Julia Reynolds85769912016-10-25 09:08:57 -0400369 * Higher notification importance: shows everywhere, makes noise and peeks. May use full screen
370 * intents.
Chris Wren5ab5c742016-05-10 15:32:23 -0400371 */
372 public static final int IMPORTANCE_HIGH = 4;
373
374 /**
Julia Reynolds85769912016-10-25 09:08:57 -0400375 * Unused.
Chris Wren5ab5c742016-05-10 15:32:23 -0400376 */
377 public static final int IMPORTANCE_MAX = 5;
378
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100379 @UnsupportedAppUsage
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800380 private static INotificationManager sService;
381
Dianne Hackbornd8a43f62009-08-17 23:33:56 -0700382 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100383 @UnsupportedAppUsage
Dianne Hackbornd8a43f62009-08-17 23:33:56 -0700384 static public INotificationManager getService()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800385 {
386 if (sService != null) {
387 return sService;
388 }
389 IBinder b = ServiceManager.getService("notification");
390 sService = INotificationManager.Stub.asInterface(b);
391 return sService;
392 }
393
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100394 @UnsupportedAppUsage
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800395 /*package*/ NotificationManager(Context context, Handler handler)
396 {
397 mContext = context;
398 }
399
Jeff Sharkey69ddab42012-08-25 00:05:46 -0700400 /** {@hide} */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100401 @UnsupportedAppUsage
Jeff Sharkey69ddab42012-08-25 00:05:46 -0700402 public static NotificationManager from(Context context) {
403 return (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
404 }
405
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800406 /**
Daniel Sandlere97a3bc2011-02-07 16:47:07 -0500407 * Post a notification to be shown in the status bar. If a notification with
408 * the same id has already been posted by your application and has not yet been canceled, it
409 * will be replaced by the updated information.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800410 *
411 * @param id An identifier for this notification unique within your
412 * application.
Daniel Sandlere97a3bc2011-02-07 16:47:07 -0500413 * @param notification A {@link Notification} object describing what to show the user. Must not
414 * be null.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800415 */
416 public void notify(int id, Notification notification)
417 {
Fred Quintana6ecaff12009-09-25 14:23:13 -0700418 notify(null, id, notification);
419 }
420
421 /**
Julia Reynoldsa7ba45a2018-08-29 09:07:52 -0400422 * Posts a notification to be shown in the status bar. If a notification with
Daniel Sandlere97a3bc2011-02-07 16:47:07 -0500423 * the same tag and id has already been posted by your application and has not yet been
424 * canceled, it will be replaced by the updated information.
Fred Quintana6ecaff12009-09-25 14:23:13 -0700425 *
Julia Reynoldse0d711f2017-09-01 08:50:47 -0400426 * All {@link android.service.notification.NotificationListenerService listener services} will
427 * be granted {@link Intent#FLAG_GRANT_READ_URI_PERMISSION} access to any {@link Uri uris}
428 * provided on this notification or the
429 * {@link NotificationChannel} this notification is posted to using
430 * {@link Context#grantUriPermission(String, Uri, int)}. Permission will be revoked when the
431 * notification is canceled, or you can revoke permissions with
432 * {@link Context#revokeUriPermission(Uri, int)}.
433 *
Peter Collingbourneb97c3492010-10-13 20:04:52 +0100434 * @param tag A string identifier for this notification. May be {@code null}.
435 * @param id An identifier for this notification. The pair (tag, id) must be unique
436 * within your application.
Daniel Sandlere97a3bc2011-02-07 16:47:07 -0500437 * @param notification A {@link Notification} object describing what to
438 * show the user. Must not be null.
Fred Quintana6ecaff12009-09-25 14:23:13 -0700439 */
440 public void notify(String tag, int id, Notification notification)
441 {
Jeff Sharkeyad357d12018-02-02 13:25:31 -0700442 notifyAsUser(tag, id, notification, mContext.getUser());
Dianne Hackborn41203752012-08-31 14:05:51 -0700443 }
444
445 /**
Julia Reynoldsa7ba45a2018-08-29 09:07:52 -0400446 * Posts a notification as a specified package to be shown in the status bar. If a notification
447 * with the same tag and id has already been posted for that package and has not yet been
448 * canceled, it will be replaced by the updated information.
449 *
450 * All {@link android.service.notification.NotificationListenerService listener services} will
451 * be granted {@link Intent#FLAG_GRANT_READ_URI_PERMISSION} access to any {@link Uri uris}
452 * provided on this notification or the
453 * {@link NotificationChannel} this notification is posted to using
454 * {@link Context#grantUriPermission(String, Uri, int)}. Permission will be revoked when the
455 * notification is canceled, or you can revoke permissions with
456 * {@link Context#revokeUriPermission(Uri, int)}.
457 *
458 * @param targetPackage The package to post the notification as. The package must have granted
459 * you access to post notifications on their behalf with
460 * {@link #setNotificationDelegate(String)}.
461 * @param tag A string identifier for this notification. May be {@code null}.
462 * @param id An identifier for this notification. The pair (tag, id) must be unique
463 * within your application.
464 * @param notification A {@link Notification} object describing what to
465 * show the user. Must not be null.
466 */
467 public void notifyAsPackage(@NonNull String targetPackage, @NonNull String tag, int id,
Fabian Kozynski867550e2019-02-28 12:59:57 -0500468 @NonNull Notification notification) {
Julia Reynoldsa7ba45a2018-08-29 09:07:52 -0400469 INotificationManager service = getService();
470 String sender = mContext.getPackageName();
471
472 try {
473 if (localLOGV) Log.v(TAG, sender + ": notify(" + id + ", " + notification + ")");
474 service.enqueueNotificationWithTag(targetPackage, sender, tag, id,
475 fixNotification(notification), mContext.getUser().getIdentifier());
476 } catch (RemoteException e) {
477 throw e.rethrowFromSystemServer();
478 }
479 }
480
481 /**
Dianne Hackborn41203752012-08-31 14:05:51 -0700482 * @hide
483 */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100484 @UnsupportedAppUsage
Dianne Hackborn41203752012-08-31 14:05:51 -0700485 public void notifyAsUser(String tag, int id, Notification notification, UserHandle user)
486 {
Dianne Hackborn41203752012-08-31 14:05:51 -0700487 INotificationManager service = getService();
488 String pkg = mContext.getPackageName();
Julia Reynoldsa7ba45a2018-08-29 09:07:52 -0400489
490 try {
491 if (localLOGV) Log.v(TAG, pkg + ": notify(" + id + ", " + notification + ")");
492 service.enqueueNotificationWithTag(pkg, mContext.getOpPackageName(), tag, id,
493 fixNotification(notification), user.getIdentifier());
494 } catch (RemoteException e) {
495 throw e.rethrowFromSystemServer();
496 }
497 }
498
499 private Notification fixNotification(Notification notification) {
500 String pkg = mContext.getPackageName();
Julia Reynoldsda303542015-11-23 14:00:20 -0500501 // Fix the notification as best we can.
502 Notification.addFieldsFromContext(mContext, notification);
Julia Reynoldse0d711f2017-09-01 08:50:47 -0400503
Jeff Sharkey65c4a2b2012-09-25 17:22:27 -0700504 if (notification.sound != null) {
505 notification.sound = notification.sound.getCanonicalUri();
Jeff Sharkeya14acd22013-04-02 18:27:45 -0700506 if (StrictMode.vmFileUriExposureEnabled()) {
Jeff Sharkeyac3be9a2016-02-01 10:39:30 -0700507 notification.sound.checkFileUriExposed("Notification.sound");
Jeff Sharkeya14acd22013-04-02 18:27:45 -0700508 }
Julia Reynoldse0d711f2017-09-01 08:50:47 -0400509
Jeff Sharkey65c4a2b2012-09-25 17:22:27 -0700510 }
Dan Sandlerd63f9322015-05-06 15:18:49 -0400511 fixLegacySmallIcon(notification, pkg);
Julia Reynoldsd9228f12015-10-20 10:37:27 -0400512 if (mContext.getApplicationInfo().targetSdkVersion > Build.VERSION_CODES.LOLLIPOP_MR1) {
513 if (notification.getSmallIcon() == null) {
514 throw new IllegalArgumentException("Invalid notification (no valid small icon): "
515 + notification);
516 }
517 }
Julia Reynoldsa7ba45a2018-08-29 09:07:52 -0400518
Selim Cinekd0426622017-07-11 13:19:59 +0200519 notification.reduceImageSizes(mContext);
Julia Reynoldse0d711f2017-09-01 08:50:47 -0400520
Julia Reynolds8a3b4592017-06-26 17:15:14 -0400521 ActivityManager am = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
522 boolean isLowRam = am.isLowRamDevice();
Julia Reynoldsa7ba45a2018-08-29 09:07:52 -0400523 return Builder.maybeCloneStrippedForDelivery(notification, isLowRam, mContext);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800524 }
525
Dan Sandlerd63f9322015-05-06 15:18:49 -0400526 private void fixLegacySmallIcon(Notification n, String pkg) {
527 if (n.getSmallIcon() == null && n.icon != 0) {
528 n.setSmallIcon(Icon.createWithResource(pkg, n.icon));
529 }
530 }
531
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800532 /**
533 * Cancel a previously shown notification. If it's transient, the view
534 * will be hidden. If it's persistent, it will be removed from the status
535 * bar.
536 */
537 public void cancel(int id)
538 {
Fred Quintana6ecaff12009-09-25 14:23:13 -0700539 cancel(null, id);
540 }
541
542 /**
543 * Cancel a previously shown notification. If it's transient, the view
544 * will be hidden. If it's persistent, it will be removed from the status
545 * bar.
546 */
547 public void cancel(String tag, int id)
548 {
Jeff Sharkeyad357d12018-02-02 13:25:31 -0700549 cancelAsUser(tag, id, mContext.getUser());
Dianne Hackborn41203752012-08-31 14:05:51 -0700550 }
551
552 /**
553 * @hide
554 */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100555 @UnsupportedAppUsage
Dianne Hackborn41203752012-08-31 14:05:51 -0700556 public void cancelAsUser(String tag, int id, UserHandle user)
557 {
558 INotificationManager service = getService();
559 String pkg = mContext.getPackageName();
560 if (localLOGV) Log.v(TAG, pkg + ": cancel(" + id + ")");
561 try {
562 service.cancelNotificationWithTag(pkg, tag, id, user.getIdentifier());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800563 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -0700564 throw e.rethrowFromSystemServer();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800565 }
566 }
567
568 /**
569 * Cancel all previously shown notifications. See {@link #cancel} for the
570 * detailed behavior.
571 */
572 public void cancelAll()
573 {
574 INotificationManager service = getService();
575 String pkg = mContext.getPackageName();
576 if (localLOGV) Log.v(TAG, pkg + ": cancelAll()");
577 try {
Jeff Sharkeyad357d12018-02-02 13:25:31 -0700578 service.cancelAllNotifications(pkg, mContext.getUserId());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800579 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -0700580 throw e.rethrowFromSystemServer();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800581 }
582 }
583
John Spurlockb4782522014-08-22 14:54:46 -0400584 /**
Julia Reynoldsa7ba45a2018-08-29 09:07:52 -0400585 * Allows a package to post notifications on your behalf using
586 * {@link #notifyAsPackage(String, String, int, Notification)}.
587 *
588 * This can be used to allow persistent processes to post notifications based on messages
589 * received on your behalf from the cloud, without your process having to wake up.
590 *
591 * You can check if you have an allowed delegate with {@link #getNotificationDelegate()} and
Julia Reynoldscbc45e72019-03-07 12:31:52 -0500592 * revoke your delegate by passing null to this method.
Julia Reynoldsa7ba45a2018-08-29 09:07:52 -0400593 *
594 * @param delegate Package name of the app which can send notifications on your behalf.
595 */
Julia Reynoldscbc45e72019-03-07 12:31:52 -0500596 public void setNotificationDelegate(@Nullable String delegate) {
Julia Reynoldsa7ba45a2018-08-29 09:07:52 -0400597 INotificationManager service = getService();
598 String pkg = mContext.getPackageName();
599 if (localLOGV) Log.v(TAG, pkg + ": cancelAll()");
600 try {
601 service.setNotificationDelegate(pkg, delegate);
602 } catch (RemoteException e) {
603 throw e.rethrowFromSystemServer();
604 }
605 }
606
607 /**
Julia Reynoldsa7ba45a2018-08-29 09:07:52 -0400608 * Returns the {@link #setNotificationDelegate(String) delegate} that can post notifications on
609 * your behalf, if there currently is one.
610 */
611 public @Nullable String getNotificationDelegate() {
612 INotificationManager service = getService();
613 String pkg = mContext.getPackageName();
614 try {
615 return service.getNotificationDelegate(pkg);
616 } catch (RemoteException e) {
617 throw e.rethrowFromSystemServer();
618 }
619 }
620
621 /**
622 * Returns whether you are allowed to post notifications on behalf of a given package, with
623 * {@link #notifyAsPackage(String, String, int, Notification)}.
624 *
625 * See {@link #setNotificationDelegate(String)}.
626 */
Fabian Kozynski867550e2019-02-28 12:59:57 -0500627 public boolean canNotifyAsPackage(@NonNull String pkg) {
Julia Reynoldsa7ba45a2018-08-29 09:07:52 -0400628 INotificationManager service = getService();
629 try {
630 return service.canNotifyAsPackage(mContext.getPackageName(), pkg);
631 } catch (RemoteException e) {
632 throw e.rethrowFromSystemServer();
633 }
634 }
635
636 /**
Julia Reynolds59e152e2017-01-25 17:42:53 -0500637 * Creates a group container for {@link NotificationChannel} objects.
638 *
Julia Reynolds1d97e6a2017-03-13 15:05:40 -0400639 * This can be used to rename an existing group.
Julia Reynolds59e152e2017-01-25 17:42:53 -0500640 * <p>
641 * Group information is only used for presentation, not for behavior. Groups are optional
642 * for channels, and you can have a mix of channels that belong to groups and channels
643 * that do not.
644 * </p>
645 * <p>
646 * For example, if your application supports multiple accounts, and those accounts will
647 * have similar channels, you can create a group for each account with account specific
648 * labels instead of appending account information to each channel's label.
649 * </p>
650 *
651 * @param group The group to create
652 */
653 public void createNotificationChannelGroup(@NonNull NotificationChannelGroup group) {
654 createNotificationChannelGroups(Arrays.asList(group));
655 }
656
657 /**
658 * Creates multiple notification channel groups.
659 *
660 * @param groups The list of groups to create
661 */
662 public void createNotificationChannelGroups(@NonNull List<NotificationChannelGroup> groups) {
663 INotificationManager service = getService();
664 try {
665 service.createNotificationChannelGroups(mContext.getPackageName(),
666 new ParceledListSlice(groups));
667 } catch (RemoteException e) {
668 throw e.rethrowFromSystemServer();
669 }
670 }
671
672 /**
Geoffrey Pitsch03533712017-01-05 10:30:07 -0500673 * Creates a notification channel that notifications can be posted to.
674 *
Julia Reynolds2c891c92017-03-17 14:23:47 -0400675 * This can also be used to restore a deleted channel and to update an existing channel's
Julia Reynolds005c8b92017-08-24 10:35:53 -0400676 * name, description, group, and/or importance.
Julia Reynolds0ffc13b2017-04-27 13:54:36 -0400677 *
678 * <p>The name and description should only be changed if the locale changes
Julia Reynolds2c891c92017-03-17 14:23:47 -0400679 * or in response to the user renaming this channel. For example, if a user has a channel
680 * named 'John Doe' that represents messages from a 'John Doe', and 'John Doe' changes his name
681 * to 'John Smith,' the channel can be renamed to match.
Geoffrey Pitsch07532c32017-07-18 11:44:06 -0400682 *
683 * <p>The importance of an existing channel will only be changed if the new importance is lower
684 * than the current value and the user has not altered any settings on this channel.
685 *
Julia Reynolds005c8b92017-08-24 10:35:53 -0400686 * <p>The group an existing channel will only be changed if the channel does not already
687 * belong to a group.
688 *
Julia Reynolds2c891c92017-03-17 14:23:47 -0400689 * All other fields are ignored for channels that already exist.
Julia Reynolds59e152e2017-01-25 17:42:53 -0500690 *
Geoffrey Pitsch03533712017-01-05 10:30:07 -0500691 * @param channel the channel to create. Note that the created channel may differ from this
Julia Reynoldse8665332017-03-13 13:00:41 -0400692 * value. If the provided channel is malformed, a RemoteException will be
Julia Reynolds1d97e6a2017-03-13 15:05:40 -0400693 * thrown.
Julia Reynoldsb5e44b72016-08-16 15:00:25 -0400694 */
Geoffrey Pitsch03533712017-01-05 10:30:07 -0500695 public void createNotificationChannel(@NonNull NotificationChannel channel) {
696 createNotificationChannels(Arrays.asList(channel));
Geoffrey Pitsche75a66e2016-11-22 11:12:11 -0500697 }
698
699 /**
Julia Reynolds1d97e6a2017-03-13 15:05:40 -0400700 * Creates multiple notification channels that different notifications can be posted to. See
701 * {@link #createNotificationChannel(NotificationChannel)}.
Geoffrey Pitsche75a66e2016-11-22 11:12:11 -0500702 *
Julia Reynolds1d97e6a2017-03-13 15:05:40 -0400703 * @param channels the list of channels to attempt to create.
Geoffrey Pitsche75a66e2016-11-22 11:12:11 -0500704 */
Geoffrey Pitsch03533712017-01-05 10:30:07 -0500705 public void createNotificationChannels(@NonNull List<NotificationChannel> channels) {
Julia Reynoldsb5e44b72016-08-16 15:00:25 -0400706 INotificationManager service = getService();
707 try {
Geoffrey Pitsch03533712017-01-05 10:30:07 -0500708 service.createNotificationChannels(mContext.getPackageName(),
709 new ParceledListSlice(channels));
Julia Reynoldsb5e44b72016-08-16 15:00:25 -0400710 } catch (RemoteException e) {
711 throw e.rethrowFromSystemServer();
712 }
713 }
714
715 /**
716 * Returns the notification channel settings for a given channel id.
Julia Reynolds0ffc13b2017-04-27 13:54:36 -0400717 *
718 * The channel must belong to your package, or it will not be returned.
Julia Reynoldsb5e44b72016-08-16 15:00:25 -0400719 */
720 public NotificationChannel getNotificationChannel(String channelId) {
721 INotificationManager service = getService();
722 try {
723 return service.getNotificationChannel(mContext.getPackageName(), channelId);
724 } catch (RemoteException e) {
725 throw e.rethrowFromSystemServer();
726 }
727 }
728
729 /**
Julia Reynolds0ffc13b2017-04-27 13:54:36 -0400730 * Returns all notification channels belonging to the calling package.
Julia Reynoldsb5e44b72016-08-16 15:00:25 -0400731 */
732 public List<NotificationChannel> getNotificationChannels() {
733 INotificationManager service = getService();
734 try {
735 return service.getNotificationChannels(mContext.getPackageName()).getList();
736 } catch (RemoteException e) {
737 throw e.rethrowFromSystemServer();
738 }
739 }
740
741 /**
Julia Reynoldsb5e44b72016-08-16 15:00:25 -0400742 * Deletes the given notification channel.
Julia Reynolds0ffc13b2017-04-27 13:54:36 -0400743 *
744 * <p>If you {@link #createNotificationChannel(NotificationChannel) create} a new channel with
745 * this same id, the deleted channel will be un-deleted with all of the same settings it
746 * had before it was deleted.
Julia Reynoldsb5e44b72016-08-16 15:00:25 -0400747 */
748 public void deleteNotificationChannel(String channelId) {
749 INotificationManager service = getService();
750 try {
751 service.deleteNotificationChannel(mContext.getPackageName(), channelId);
752 } catch (RemoteException e) {
753 throw e.rethrowFromSystemServer();
754 }
755 }
756
757 /**
Julia Reynolds3eb3ffd2017-11-16 10:11:32 -0500758 * Returns the notification channel group settings for a given channel group id.
759 *
760 * The channel group must belong to your package, or null will be returned.
761 */
762 public NotificationChannelGroup getNotificationChannelGroup(String channelGroupId) {
763 INotificationManager service = getService();
764 try {
765 return service.getNotificationChannelGroup(mContext.getPackageName(), channelGroupId);
766 } catch (RemoteException e) {
767 throw e.rethrowFromSystemServer();
768 }
769 }
770
771 /**
Julia Reynolds9bfba592017-03-15 14:03:55 -0400772 * Returns all notification channel groups belonging to the calling app.
773 */
774 public List<NotificationChannelGroup> getNotificationChannelGroups() {
775 INotificationManager service = getService();
776 try {
Beverlyc629ee42018-10-02 16:14:07 -0400777 final ParceledListSlice<NotificationChannelGroup> parceledList =
778 service.getNotificationChannelGroups(mContext.getPackageName());
779 if (parceledList != null) {
780 return parceledList.getList();
781 }
Julia Reynolds9bfba592017-03-15 14:03:55 -0400782 } catch (RemoteException e) {
783 throw e.rethrowFromSystemServer();
784 }
Beverlyc629ee42018-10-02 16:14:07 -0400785 return new ArrayList<>();
Julia Reynolds9bfba592017-03-15 14:03:55 -0400786 }
787
788 /**
Julia Reynolds0ffc13b2017-04-27 13:54:36 -0400789 * Deletes the given notification channel group, and all notification channels that
790 * belong to it.
Julia Reynolds9bfba592017-03-15 14:03:55 -0400791 */
792 public void deleteNotificationChannelGroup(String groupId) {
793 INotificationManager service = getService();
794 try {
795 service.deleteNotificationChannelGroup(mContext.getPackageName(), groupId);
796 } catch (RemoteException e) {
797 throw e.rethrowFromSystemServer();
798 }
799 }
800
801 /**
John Spurlockb4782522014-08-22 14:54:46 -0400802 * @hide
803 */
Julia Reynoldsb6c1f992016-11-22 09:26:46 -0500804 @TestApi
John Spurlockb4782522014-08-22 14:54:46 -0400805 public ComponentName getEffectsSuppressor() {
806 INotificationManager service = getService();
807 try {
808 return service.getEffectsSuppressor();
809 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -0700810 throw e.rethrowFromSystemServer();
John Spurlockb4782522014-08-22 14:54:46 -0400811 }
812 }
813
John Spurlock2b122f42014-08-27 16:29:47 -0400814 /**
815 * @hide
816 */
Julia Reynolds87621942019-01-29 16:19:36 -0500817 @TestApi
John Spurlock2b122f42014-08-27 16:29:47 -0400818 public boolean matchesCallFilter(Bundle extras) {
819 INotificationManager service = getService();
820 try {
821 return service.matchesCallFilter(extras);
822 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -0700823 throw e.rethrowFromSystemServer();
John Spurlock2b122f42014-08-27 16:29:47 -0400824 }
825 }
826
John Spurlock530052a2014-11-30 16:26:19 -0500827 /**
828 * @hide
829 */
830 public boolean isSystemConditionProviderEnabled(String path) {
831 INotificationManager service = getService();
832 try {
833 return service.isSystemConditionProviderEnabled(path);
834 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -0700835 throw e.rethrowFromSystemServer();
John Spurlock530052a2014-11-30 16:26:19 -0500836 }
837 }
838
John Spurlockcdb57ae2015-02-11 19:04:11 -0500839 /**
840 * @hide
841 */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100842 @UnsupportedAppUsage
John Spurlockb2278d62015-04-07 12:47:12 -0400843 public void setZenMode(int mode, Uri conditionId, String reason) {
John Spurlockcdb57ae2015-02-11 19:04:11 -0500844 INotificationManager service = getService();
845 try {
John Spurlockb2278d62015-04-07 12:47:12 -0400846 service.setZenMode(mode, conditionId, reason);
John Spurlockcdb57ae2015-02-11 19:04:11 -0500847 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -0700848 throw e.rethrowFromSystemServer();
John Spurlockcdb57ae2015-02-11 19:04:11 -0500849 }
850 }
851
852 /**
853 * @hide
854 */
John Spurlockb2278d62015-04-07 12:47:12 -0400855 public int getZenMode() {
John Spurlockcdb57ae2015-02-11 19:04:11 -0500856 INotificationManager service = getService();
857 try {
John Spurlockb2278d62015-04-07 12:47:12 -0400858 return service.getZenMode();
John Spurlockcdb57ae2015-02-11 19:04:11 -0500859 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -0700860 throw e.rethrowFromSystemServer();
John Spurlockcdb57ae2015-02-11 19:04:11 -0500861 }
862 }
863
864 /**
865 * @hide
866 */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100867 @UnsupportedAppUsage
John Spurlockb2278d62015-04-07 12:47:12 -0400868 public ZenModeConfig getZenModeConfig() {
John Spurlockcdb57ae2015-02-11 19:04:11 -0500869 INotificationManager service = getService();
870 try {
John Spurlockb2278d62015-04-07 12:47:12 -0400871 return service.getZenModeConfig();
John Spurlockcdb57ae2015-02-11 19:04:11 -0500872 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -0700873 throw e.rethrowFromSystemServer();
John Spurlockcdb57ae2015-02-11 19:04:11 -0500874 }
John Spurlockcdb57ae2015-02-11 19:04:11 -0500875 }
876
John Spurlock1fc476d2015-04-14 16:05:20 -0400877 /**
Julia Reynolds43b70cd2016-01-14 15:05:34 -0500878 * @hide
879 */
Beverlyff2df9b2018-10-10 16:54:10 -0400880 public NotificationManager.Policy getConsolidatedNotificationPolicy() {
881 INotificationManager service = getService();
882 try {
883 return service.getConsolidatedNotificationPolicy();
884 } catch (RemoteException e) {
885 throw e.rethrowFromSystemServer();
886 }
887 }
888
889 /**
890 * @hide
891 */
Julia Reynolds43b70cd2016-01-14 15:05:34 -0500892 public int getRuleInstanceCount(ComponentName owner) {
893 INotificationManager service = getService();
894 try {
895 return service.getRuleInstanceCount(owner);
896 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -0700897 throw e.rethrowFromSystemServer();
Julia Reynolds43b70cd2016-01-14 15:05:34 -0500898 }
Julia Reynolds43b70cd2016-01-14 15:05:34 -0500899 }
900
901 /**
Julia Reynoldsa47a27f2015-08-24 08:31:47 -0400902 * Returns AutomaticZenRules owned by the caller.
903 *
904 * <p>
Julia Reynolds361e82d32016-02-26 18:19:49 -0500905 * Throws a SecurityException if policy access is granted to this package.
Julia Reynoldsa47a27f2015-08-24 08:31:47 -0400906 * See {@link #isNotificationPolicyAccessGranted}.
907 */
Julia Reynolds361e82d32016-02-26 18:19:49 -0500908 public Map<String, AutomaticZenRule> getAutomaticZenRules() {
Julia Reynoldsa47a27f2015-08-24 08:31:47 -0400909 INotificationManager service = getService();
910 try {
Julia Reynolds361e82d32016-02-26 18:19:49 -0500911 List<ZenModeConfig.ZenRule> rules = service.getZenRules();
912 Map<String, AutomaticZenRule> ruleMap = new HashMap<>();
913 for (ZenModeConfig.ZenRule rule : rules) {
Julia Reynolds68062072018-08-06 15:38:21 -0400914 ruleMap.put(rule.id, new AutomaticZenRule(rule.name, rule.component,
915 rule.configurationActivity, rule.conditionId, rule.zenPolicy,
916 zenModeToInterruptionFilter(rule.zenMode), rule.enabled,
917 rule.creationTime));
Julia Reynolds361e82d32016-02-26 18:19:49 -0500918 }
919 return ruleMap;
Julia Reynoldsa47a27f2015-08-24 08:31:47 -0400920 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -0700921 throw e.rethrowFromSystemServer();
Julia Reynoldsa47a27f2015-08-24 08:31:47 -0400922 }
Julia Reynoldsa47a27f2015-08-24 08:31:47 -0400923 }
924
925 /**
Julia Reynolds4fe98d62015-10-06 16:23:41 -0400926 * Returns the AutomaticZenRule with the given id, if it exists and the caller has access.
Julia Reynoldsa47a27f2015-08-24 08:31:47 -0400927 *
928 * <p>
Julia Reynolds361e82d32016-02-26 18:19:49 -0500929 * Throws a SecurityException if policy access is granted to this package.
Julia Reynoldsa47a27f2015-08-24 08:31:47 -0400930 * See {@link #isNotificationPolicyAccessGranted}.
931 *
932 * <p>
Julia Reynolds4fe98d62015-10-06 16:23:41 -0400933 * 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 -0400934 * doesn't own the matching rule. See {@link AutomaticZenRule#getOwner}.
935 */
Julia Reynolds4fe98d62015-10-06 16:23:41 -0400936 public AutomaticZenRule getAutomaticZenRule(String id) {
Julia Reynoldsa47a27f2015-08-24 08:31:47 -0400937 INotificationManager service = getService();
938 try {
Julia Reynolds4fe98d62015-10-06 16:23:41 -0400939 return service.getAutomaticZenRule(id);
Julia Reynoldsa47a27f2015-08-24 08:31:47 -0400940 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -0700941 throw e.rethrowFromSystemServer();
Julia Reynoldsa47a27f2015-08-24 08:31:47 -0400942 }
Julia Reynoldsa47a27f2015-08-24 08:31:47 -0400943 }
944
945 /**
Julia Reynolds4fe98d62015-10-06 16:23:41 -0400946 * Creates the given zen rule.
Julia Reynoldsa47a27f2015-08-24 08:31:47 -0400947 *
948 * <p>
Julia Reynolds361e82d32016-02-26 18:19:49 -0500949 * Throws a SecurityException if policy access is granted to this package.
Julia Reynoldsa47a27f2015-08-24 08:31:47 -0400950 * See {@link #isNotificationPolicyAccessGranted}.
951 *
Julia Reynolds4fe98d62015-10-06 16:23:41 -0400952 * @param automaticZenRule the rule to create.
Julia Reynolds361e82d32016-02-26 18:19:49 -0500953 * @return The id of the newly created rule; null if the rule could not be created.
Julia Reynoldsa47a27f2015-08-24 08:31:47 -0400954 */
Julia Reynolds361e82d32016-02-26 18:19:49 -0500955 public String addAutomaticZenRule(AutomaticZenRule automaticZenRule) {
Julia Reynoldsa47a27f2015-08-24 08:31:47 -0400956 INotificationManager service = getService();
957 try {
Julia Reynolds4fe98d62015-10-06 16:23:41 -0400958 return service.addAutomaticZenRule(automaticZenRule);
Julia Reynoldsa47a27f2015-08-24 08:31:47 -0400959 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -0700960 throw e.rethrowFromSystemServer();
Julia Reynoldsa47a27f2015-08-24 08:31:47 -0400961 }
Julia Reynoldsa47a27f2015-08-24 08:31:47 -0400962 }
963
964 /**
Julia Reynolds4fe98d62015-10-06 16:23:41 -0400965 * Updates the given zen rule.
Julia Reynoldsa47a27f2015-08-24 08:31:47 -0400966 *
967 * <p>
Julia Reynolds361e82d32016-02-26 18:19:49 -0500968 * Throws a SecurityException if policy access is granted to this package.
Julia Reynoldsa47a27f2015-08-24 08:31:47 -0400969 * See {@link #isNotificationPolicyAccessGranted}.
970 *
971 * <p>
972 * Callers can only update rules that they own. See {@link AutomaticZenRule#getOwner}.
Julia Reynolds361e82d32016-02-26 18:19:49 -0500973 * @param id The id of the rule to update
Geoffrey Pitsche75a66e2016-11-22 11:12:11 -0500974 * @param automaticZenRule the rule to update.
Julia Reynoldsa47a27f2015-08-24 08:31:47 -0400975 * @return Whether the rule was successfully updated.
976 */
Julia Reynolds361e82d32016-02-26 18:19:49 -0500977 public boolean updateAutomaticZenRule(String id, AutomaticZenRule automaticZenRule) {
Julia Reynoldsa47a27f2015-08-24 08:31:47 -0400978 INotificationManager service = getService();
979 try {
Julia Reynolds361e82d32016-02-26 18:19:49 -0500980 return service.updateAutomaticZenRule(id, automaticZenRule);
Julia Reynoldsa47a27f2015-08-24 08:31:47 -0400981 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -0700982 throw e.rethrowFromSystemServer();
Julia Reynoldsa47a27f2015-08-24 08:31:47 -0400983 }
Julia Reynoldsa47a27f2015-08-24 08:31:47 -0400984 }
985
986 /**
Julia Reynolds68062072018-08-06 15:38:21 -0400987 * Informs the notification manager that the state of an {@link AutomaticZenRule} has changed.
988 * Use this method to put the system into Do Not Disturb mode or request that it exits Do Not
989 * Disturb mode. The calling app must own the provided {@link android.app.AutomaticZenRule}.
990 * <p>
991 * This method can be used in conjunction with or as a replacement to
992 * {@link android.service.notification.ConditionProviderService#notifyCondition(Condition)}.
993 * </p>
994 * @param id The id of the rule whose state should change
995 * @param condition The new state of this rule
996 */
Fabian Kozynski867550e2019-02-28 12:59:57 -0500997 public void setAutomaticZenRuleState(@NonNull String id, @NonNull Condition condition) {
Julia Reynolds68062072018-08-06 15:38:21 -0400998 INotificationManager service = getService();
999 try {
1000 service.setAutomaticZenRuleState(id, condition);
1001 } catch (RemoteException e) {
1002 throw e.rethrowFromSystemServer();
1003 }
1004 }
1005
1006 /**
Julia Reynolds4fe98d62015-10-06 16:23:41 -04001007 * Deletes the automatic zen rule with the given id.
Julia Reynoldsa47a27f2015-08-24 08:31:47 -04001008 *
1009 * <p>
Julia Reynolds361e82d32016-02-26 18:19:49 -05001010 * Throws a SecurityException if policy access is granted to this package.
Julia Reynoldsa47a27f2015-08-24 08:31:47 -04001011 * See {@link #isNotificationPolicyAccessGranted}.
1012 *
1013 * <p>
1014 * Callers can only delete rules that they own. See {@link AutomaticZenRule#getOwner}.
Julia Reynolds4fe98d62015-10-06 16:23:41 -04001015 * @param id the id of the rule to delete.
Julia Reynoldsa47a27f2015-08-24 08:31:47 -04001016 * @return Whether the rule was successfully deleted.
1017 */
Julia Reynolds4fe98d62015-10-06 16:23:41 -04001018 public boolean removeAutomaticZenRule(String id) {
Julia Reynoldsa47a27f2015-08-24 08:31:47 -04001019 INotificationManager service = getService();
1020 try {
Julia Reynolds4fe98d62015-10-06 16:23:41 -04001021 return service.removeAutomaticZenRule(id);
Julia Reynoldsa47a27f2015-08-24 08:31:47 -04001022 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07001023 throw e.rethrowFromSystemServer();
Julia Reynoldsa47a27f2015-08-24 08:31:47 -04001024 }
Julia Reynoldsa47a27f2015-08-24 08:31:47 -04001025 }
1026
1027 /**
Julia Reynoldsc8e54e82015-11-30 16:43:05 -05001028 * Deletes all automatic zen rules owned by the given package.
1029 *
1030 * @hide
1031 */
1032 public boolean removeAutomaticZenRules(String packageName) {
1033 INotificationManager service = getService();
1034 try {
1035 return service.removeAutomaticZenRules(packageName);
1036 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07001037 throw e.rethrowFromSystemServer();
Julia Reynoldsc8e54e82015-11-30 16:43:05 -05001038 }
Julia Reynoldsc8e54e82015-11-30 16:43:05 -05001039 }
1040
Julia Reynolds0edb50c2016-02-26 14:08:25 -05001041 /**
Jeff Sharkey6503bd82017-04-19 23:24:18 -06001042 * Returns the user specified importance for notifications from the calling
1043 * package.
Julia Reynolds0edb50c2016-02-26 14:08:25 -05001044 */
Chris Wren5ab5c742016-05-10 15:32:23 -04001045 public @Importance int getImportance() {
Julia Reynolds81afbcd2016-02-09 14:54:08 -05001046 INotificationManager service = getService();
1047 try {
Julia Reynoldsef37f282016-02-12 09:11:27 -05001048 return service.getPackageImportance(mContext.getPackageName());
Julia Reynolds81afbcd2016-02-09 14:54:08 -05001049 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07001050 throw e.rethrowFromSystemServer();
Julia Reynolds81afbcd2016-02-09 14:54:08 -05001051 }
Julia Reynolds81afbcd2016-02-09 14:54:08 -05001052 }
1053
Julia Reynolds0edb50c2016-02-26 14:08:25 -05001054 /**
1055 * Returns whether notifications from the calling package are blocked.
1056 */
Julia Reynolds81afbcd2016-02-09 14:54:08 -05001057 public boolean areNotificationsEnabled() {
1058 INotificationManager service = getService();
1059 try {
1060 return service.areNotificationsEnabled(mContext.getPackageName());
1061 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07001062 throw e.rethrowFromSystemServer();
Julia Reynolds81afbcd2016-02-09 14:54:08 -05001063 }
Julia Reynolds81afbcd2016-02-09 14:54:08 -05001064 }
1065
Julia Reynolds33ab8a02018-12-17 16:19:52 -05001066
1067 /**
1068 * Sets whether notifications posted by this app can appear outside of the
1069 * notification shade, floating over other apps' content.
1070 *
1071 * <p>This value will be ignored for notifications that are posted to channels that do not
Mady Mellorc39b4ae2019-01-09 17:11:37 -08001072 * allow bubbles ({@link NotificationChannel#canBubble()}.
Julia Reynolds33ab8a02018-12-17 16:19:52 -05001073 *
Mady Mellorc39b4ae2019-01-09 17:11:37 -08001074 * @see Notification#getBubbleMetadata()
Julia Reynolds33ab8a02018-12-17 16:19:52 -05001075 */
Mady Mellorc39b4ae2019-01-09 17:11:37 -08001076 public boolean areBubblesAllowed() {
Julia Reynolds33ab8a02018-12-17 16:19:52 -05001077 INotificationManager service = getService();
1078 try {
Mady Mellorc39b4ae2019-01-09 17:11:37 -08001079 return service.areBubblesAllowed(mContext.getPackageName());
Julia Reynolds33ab8a02018-12-17 16:19:52 -05001080 } catch (RemoteException e) {
1081 throw e.rethrowFromSystemServer();
1082 }
1083 }
1084
Julia Reynoldsc8e54e82015-11-30 16:43:05 -05001085 /**
Julia Reynoldsb40cd092019-01-25 09:35:02 -05001086 * Returns whether notifications from this package are temporarily hidden. This
1087 * could be done because the package was marked as distracting to the user via
1088 * {@code PackageManager#setDistractingPackageRestrictions(String[], int)} or because the
1089 * package is {@code PackageManager#setPackagesSuspended(String[], boolean, PersistableBundle,
1090 * PersistableBundle, SuspendDialogInfo) suspended}.
1091 */
1092 public boolean areNotificationsPaused() {
1093 INotificationManager service = getService();
1094 try {
1095 return service.isPackagePaused(mContext.getPackageName());
1096 } catch (RemoteException e) {
1097 throw e.rethrowFromSystemServer();
1098 }
1099 }
1100
1101 /**
Beverly312ef3e2017-11-15 11:12:51 -05001102 * Checks the ability to modify notification do not disturb policy for the calling package.
John Spurlock1fc476d2015-04-14 16:05:20 -04001103 *
John Spurlock7c74f782015-06-04 13:01:42 -04001104 * <p>
Beverly312ef3e2017-11-15 11:12:51 -05001105 * Returns true if the calling package can modify notification policy.
John Spurlock7c74f782015-06-04 13:01:42 -04001106 *
1107 * <p>
Julia Reynoldsb852e562017-06-06 16:14:18 -04001108 * Apps can request policy access by sending the user to the activity that matches the system
1109 * intent action {@link android.provider.Settings#ACTION_NOTIFICATION_POLICY_ACCESS_SETTINGS}.
John Spurlock7c74f782015-06-04 13:01:42 -04001110 *
1111 * <p>
1112 * Use {@link #ACTION_NOTIFICATION_POLICY_ACCESS_GRANTED_CHANGED} to listen for
1113 * user grant or denial of this access.
John Spurlock1fc476d2015-04-14 16:05:20 -04001114 */
John Spurlock80774932015-05-07 17:38:50 -04001115 public boolean isNotificationPolicyAccessGranted() {
John Spurlock1fc476d2015-04-14 16:05:20 -04001116 INotificationManager service = getService();
1117 try {
John Spurlock80774932015-05-07 17:38:50 -04001118 return service.isNotificationPolicyAccessGranted(mContext.getOpPackageName());
1119 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07001120 throw e.rethrowFromSystemServer();
John Spurlock80774932015-05-07 17:38:50 -04001121 }
John Spurlock80774932015-05-07 17:38:50 -04001122 }
1123
Julia Reynoldsb852e562017-06-06 16:14:18 -04001124 /**
1125 * Checks whether the user has approved a given
1126 * {@link android.service.notification.NotificationListenerService}.
1127 *
1128 * <p>
1129 * The listener service must belong to the calling app.
1130 *
1131 * <p>
1132 * Apps can request notification listener access by sending the user to the activity that
1133 * matches the system intent action
1134 * {@link android.provider.Settings#ACTION_NOTIFICATION_LISTENER_SETTINGS}.
1135 */
1136 public boolean isNotificationListenerAccessGranted(ComponentName listener) {
1137 INotificationManager service = getService();
1138 try {
1139 return service.isNotificationListenerAccessGranted(listener);
1140 } catch (RemoteException e) {
1141 throw e.rethrowFromSystemServer();
1142 }
1143 }
1144
Fabian Kozynskid9425662019-01-29 13:08:30 -05001145 /**
1146 * Checks whether the user has approved a given
1147 * {@link android.service.notification.NotificationAssistantService}.
1148 *
1149 * <p>
1150 * The assistant service must belong to the calling app.
1151 *
1152 * <p>
1153 * Apps can request notification assistant access by sending the user to the activity that
1154 * matches the system intent action
1155 * TODO: STOPSHIP: Add correct intent
1156 * {@link android.provider.Settings#ACTION_MANAGE_DEFAULT_APPS_SETTINGS}.
Julia Reynoldsd0ceefa2019-03-03 16:10:52 -05001157 * @hide
Fabian Kozynskid9425662019-01-29 13:08:30 -05001158 */
Julia Reynoldsd0ceefa2019-03-03 16:10:52 -05001159 @SystemApi
Fabian Kozynski867550e2019-02-28 12:59:57 -05001160 public boolean isNotificationAssistantAccessGranted(@NonNull ComponentName assistant) {
Julia Reynoldsb852e562017-06-06 16:14:18 -04001161 INotificationManager service = getService();
1162 try {
1163 return service.isNotificationAssistantAccessGranted(assistant);
1164 } catch (RemoteException e) {
1165 throw e.rethrowFromSystemServer();
1166 }
1167 }
1168
Julia Reynolds12ad7ca2019-01-28 09:29:16 -05001169 /**
1170 * Returns whether the user wants silent notifications (see {@link #IMPORTANCE_LOW} to appear
1171 * in the status bar.
1172 *
1173 * <p>Only available for {@link #isNotificationListenerAccessGranted(ComponentName) notification
1174 * listeners}.
1175 */
1176 public boolean shouldHideSilentStatusBarIcons() {
1177 INotificationManager service = getService();
1178 try {
1179 return service.shouldHideSilentStatusIcons(mContext.getOpPackageName());
1180 } catch (RemoteException e) {
1181 throw e.rethrowFromSystemServer();
1182 }
1183 }
1184
John Spurlock80774932015-05-07 17:38:50 -04001185 /** @hide */
1186 public boolean isNotificationPolicyAccessGrantedForPackage(String pkg) {
1187 INotificationManager service = getService();
1188 try {
1189 return service.isNotificationPolicyAccessGrantedForPackage(pkg);
John Spurlock1fc476d2015-04-14 16:05:20 -04001190 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07001191 throw e.rethrowFromSystemServer();
John Spurlock1fc476d2015-04-14 16:05:20 -04001192 }
John Spurlock1fc476d2015-04-14 16:05:20 -04001193 }
1194
1195 /**
Julia Reynoldsb852e562017-06-06 16:14:18 -04001196 * @hide
1197 */
1198 public List<String> getEnabledNotificationListenerPackages() {
1199 INotificationManager service = getService();
1200 try {
1201 return service.getEnabledNotificationListenerPackages();
1202 } catch (RemoteException e) {
1203 throw e.rethrowFromSystemServer();
1204 }
1205 }
1206
1207 /**
Beverlyff2df9b2018-10-10 16:54:10 -04001208 * Gets the current user-specified default notification policy.
John Spurlock1fc476d2015-04-14 16:05:20 -04001209 *
John Spurlock80774932015-05-07 17:38:50 -04001210 * <p>
John Spurlock1fc476d2015-04-14 16:05:20 -04001211 */
John Spurlock80774932015-05-07 17:38:50 -04001212 public Policy getNotificationPolicy() {
John Spurlock1fc476d2015-04-14 16:05:20 -04001213 INotificationManager service = getService();
1214 try {
John Spurlock80774932015-05-07 17:38:50 -04001215 return service.getNotificationPolicy(mContext.getOpPackageName());
John Spurlock1fc476d2015-04-14 16:05:20 -04001216 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07001217 throw e.rethrowFromSystemServer();
John Spurlock1fc476d2015-04-14 16:05:20 -04001218 }
John Spurlock1fc476d2015-04-14 16:05:20 -04001219 }
1220
1221 /**
1222 * Sets the current notification policy.
1223 *
John Spurlock80774932015-05-07 17:38:50 -04001224 * <p>
John Spurlock7c74f782015-06-04 13:01:42 -04001225 * Only available if policy access is granted to this package.
1226 * See {@link #isNotificationPolicyAccessGranted}.
John Spurlock80774932015-05-07 17:38:50 -04001227 *
John Spurlock1fc476d2015-04-14 16:05:20 -04001228 * @param policy The new desired policy.
1229 */
John Spurlock80774932015-05-07 17:38:50 -04001230 public void setNotificationPolicy(@NonNull Policy policy) {
John Spurlock1fc476d2015-04-14 16:05:20 -04001231 checkRequired("policy", policy);
1232 INotificationManager service = getService();
1233 try {
John Spurlock80774932015-05-07 17:38:50 -04001234 service.setNotificationPolicy(mContext.getOpPackageName(), policy);
John Spurlock1fc476d2015-04-14 16:05:20 -04001235 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07001236 throw e.rethrowFromSystemServer();
John Spurlock1fc476d2015-04-14 16:05:20 -04001237 }
1238 }
1239
John Spurlock80774932015-05-07 17:38:50 -04001240 /** @hide */
1241 public void setNotificationPolicyAccessGranted(String pkg, boolean granted) {
1242 INotificationManager service = getService();
1243 try {
1244 service.setNotificationPolicyAccessGranted(pkg, granted);
1245 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07001246 throw e.rethrowFromSystemServer();
John Spurlock80774932015-05-07 17:38:50 -04001247 }
1248 }
1249
1250 /** @hide */
Julia Reynoldsb852e562017-06-06 16:14:18 -04001251 public void setNotificationListenerAccessGranted(ComponentName listener, boolean granted) {
John Spurlock80774932015-05-07 17:38:50 -04001252 INotificationManager service = getService();
1253 try {
Julia Reynoldsb852e562017-06-06 16:14:18 -04001254 service.setNotificationListenerAccessGranted(listener, granted);
John Spurlock80774932015-05-07 17:38:50 -04001255 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07001256 throw e.rethrowFromSystemServer();
John Spurlock80774932015-05-07 17:38:50 -04001257 }
Julia Reynoldsb852e562017-06-06 16:14:18 -04001258 }
1259
1260 /** @hide */
1261 public void setNotificationListenerAccessGrantedForUser(ComponentName listener, int userId,
1262 boolean granted) {
1263 INotificationManager service = getService();
1264 try {
1265 service.setNotificationListenerAccessGrantedForUser(listener, userId, granted);
1266 } catch (RemoteException e) {
1267 throw e.rethrowFromSystemServer();
1268 }
1269 }
1270
Fabian Kozynskid9425662019-01-29 13:08:30 -05001271 /**
1272 * Grants/revokes Notification Assistant access to {@code assistant} for current user.
1273 *
1274 * @param assistant Name of component to grant/revoke access or {@code null} to revoke access to
1275 * current assistant
1276 * @param granted Grant/revoke access
1277 * @hide
1278 */
1279 @SystemApi
1280 public void setNotificationAssistantAccessGranted(ComponentName assistant, boolean granted) {
1281 INotificationManager service = getService();
1282 try {
1283 service.setNotificationAssistantAccessGranted(assistant, granted);
1284 } catch (RemoteException e) {
1285 throw e.rethrowFromSystemServer();
1286 }
1287 }
1288
1289 /**
1290 * Grants/revokes Notification Assistant access to {@code assistant} for given user.
1291 *
1292 * @param assistant Name of component to grant/revoke access or {@code null} to revoke access to
1293 * current assistant
1294 * @param user handle to associate assistant with
1295 * @param granted Grant/revoke access
1296 * @hide
1297 */
1298 @SystemApi
1299 public void setNotificationAssistantAccessGrantedForUser(ComponentName assistant,
1300 UserHandle user, boolean granted) {
1301 INotificationManager service = getService();
1302 try {
1303 service.setNotificationAssistantAccessGrantedForUser(assistant, user.getIdentifier(),
1304 granted);
1305 } catch (RemoteException e) {
1306 throw e.rethrowFromSystemServer();
1307 }
1308 }
1309
Julia Reynoldsb852e562017-06-06 16:14:18 -04001310 /** @hide */
1311 public List<ComponentName> getEnabledNotificationListeners(int userId) {
1312 INotificationManager service = getService();
1313 try {
1314 return service.getEnabledNotificationListeners(userId);
1315 } catch (RemoteException e) {
1316 throw e.rethrowFromSystemServer();
1317 }
John Spurlock80774932015-05-07 17:38:50 -04001318 }
1319
Fabian Kozynskid9425662019-01-29 13:08:30 -05001320 /** @hide */
1321 @SystemApi
1322 public @Nullable ComponentName getAllowedNotificationAssistantForUser(UserHandle user) {
1323 INotificationManager service = getService();
1324 try {
1325 return service.getAllowedNotificationAssistantForUser(user.getIdentifier());
1326 } catch (RemoteException e) {
1327 throw e.rethrowFromSystemServer();
1328 }
1329 }
1330
1331 /** @hide */
1332 @SystemApi
1333 public @Nullable ComponentName getAllowedNotificationAssistant() {
1334 INotificationManager service = getService();
1335 try {
1336 return service.getAllowedNotificationAssistant();
1337 } catch (RemoteException e) {
1338 throw e.rethrowFromSystemServer();
1339 }
1340 }
1341
1342
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001343 private Context mContext;
John Spurlock1fc476d2015-04-14 16:05:20 -04001344
1345 private static void checkRequired(String name, Object value) {
1346 if (value == null) {
1347 throw new IllegalArgumentException(name + " is required");
1348 }
1349 }
1350
1351 /**
1352 * Notification policy configuration. Represents user-preferences for notification
Julia Reynoldscedacef2016-03-04 08:18:47 -05001353 * filtering.
John Spurlock1fc476d2015-04-14 16:05:20 -04001354 */
1355 public static class Policy implements android.os.Parcelable {
1356 /** Reminder notifications are prioritized. */
1357 public static final int PRIORITY_CATEGORY_REMINDERS = 1 << 0;
1358 /** Event notifications are prioritized. */
1359 public static final int PRIORITY_CATEGORY_EVENTS = 1 << 1;
1360 /** Message notifications are prioritized. */
1361 public static final int PRIORITY_CATEGORY_MESSAGES = 1 << 2;
1362 /** Calls are prioritized. */
1363 public static final int PRIORITY_CATEGORY_CALLS = 1 << 3;
1364 /** Calls from repeat callers are prioritized. */
1365 public static final int PRIORITY_CATEGORY_REPEAT_CALLERS = 1 << 4;
Beverly04216872017-09-28 10:55:32 -04001366 /** Alarms are prioritized */
1367 public static final int PRIORITY_CATEGORY_ALARMS = 1 << 5;
Beverlyd6964762018-02-16 14:07:03 -05001368 /** Media, game, voice navigation are prioritized */
1369 public static final int PRIORITY_CATEGORY_MEDIA = 1 << 6;
1370 /**System (catch-all for non-never suppressible sounds) are prioritized */
1371 public static final int PRIORITY_CATEGORY_SYSTEM = 1 << 7;
John Spurlock1fc476d2015-04-14 16:05:20 -04001372
Beverlyd6964762018-02-16 14:07:03 -05001373 /**
1374 * @hide
1375 */
1376 public static final int[] ALL_PRIORITY_CATEGORIES = {
Beverly04216872017-09-28 10:55:32 -04001377 PRIORITY_CATEGORY_ALARMS,
Beverlyd6964762018-02-16 14:07:03 -05001378 PRIORITY_CATEGORY_MEDIA,
1379 PRIORITY_CATEGORY_SYSTEM,
John Spurlock1fc476d2015-04-14 16:05:20 -04001380 PRIORITY_CATEGORY_REMINDERS,
1381 PRIORITY_CATEGORY_EVENTS,
1382 PRIORITY_CATEGORY_MESSAGES,
1383 PRIORITY_CATEGORY_CALLS,
1384 PRIORITY_CATEGORY_REPEAT_CALLERS,
1385 };
1386
1387 /** Any sender is prioritized. */
1388 public static final int PRIORITY_SENDERS_ANY = 0;
1389 /** Saved contacts are prioritized. */
1390 public static final int PRIORITY_SENDERS_CONTACTS = 1;
1391 /** Only starred contacts are prioritized. */
1392 public static final int PRIORITY_SENDERS_STARRED = 2;
1393
1394 /** Notification categories to prioritize. Bitmask of PRIORITY_CATEGORY_* constants. */
1395 public final int priorityCategories;
1396
John Spurlock80774932015-05-07 17:38:50 -04001397 /** Notification senders to prioritize for calls. One of:
John Spurlock1fc476d2015-04-14 16:05:20 -04001398 * PRIORITY_SENDERS_ANY, PRIORITY_SENDERS_CONTACTS, PRIORITY_SENDERS_STARRED */
John Spurlock80774932015-05-07 17:38:50 -04001399 public final int priorityCallSenders;
John Spurlock1fc476d2015-04-14 16:05:20 -04001400
John Spurlock80774932015-05-07 17:38:50 -04001401 /** Notification senders to prioritize for messages. One of:
1402 * PRIORITY_SENDERS_ANY, PRIORITY_SENDERS_CONTACTS, PRIORITY_SENDERS_STARRED */
1403 public final int priorityMessageSenders;
1404
Julia Reynoldsd5607292016-02-05 15:25:58 -05001405 /**
1406 * @hide
1407 */
Julia Reynoldsf612869ae2015-11-05 16:48:55 -05001408 public static final int SUPPRESSED_EFFECTS_UNSET = -1;
Julia Reynoldsccc6ae62018-03-01 16:24:49 -05001409
Julia Reynoldsd5607292016-02-05 15:25:58 -05001410 /**
Julia Reynoldscedacef2016-03-04 08:18:47 -05001411 * Whether notifications suppressed by DND should not interrupt visually (e.g. with
1412 * notification lights or by turning the screen on) when the screen is off.
Julia Reynoldsccc6ae62018-03-01 16:24:49 -05001413 *
1414 * @deprecated use {@link #SUPPRESSED_EFFECT_FULL_SCREEN_INTENT} and
1415 * {@link #SUPPRESSED_EFFECT_AMBIENT} and {@link #SUPPRESSED_EFFECT_LIGHTS} individually.
Julia Reynoldsd5607292016-02-05 15:25:58 -05001416 */
Julia Reynoldsccc6ae62018-03-01 16:24:49 -05001417 @Deprecated
Julia Reynoldsd5607292016-02-05 15:25:58 -05001418 public static final int SUPPRESSED_EFFECT_SCREEN_OFF = 1 << 0;
1419 /**
Julia Reynoldscedacef2016-03-04 08:18:47 -05001420 * Whether notifications suppressed by DND should not interrupt visually when the screen
1421 * is on (e.g. by peeking onto the screen).
Julia Reynoldsccc6ae62018-03-01 16:24:49 -05001422 *
1423 * @deprecated use {@link #SUPPRESSED_EFFECT_PEEK}.
Julia Reynoldsd5607292016-02-05 15:25:58 -05001424 */
Julia Reynoldsccc6ae62018-03-01 16:24:49 -05001425 @Deprecated
Julia Reynoldsd5607292016-02-05 15:25:58 -05001426 public static final int SUPPRESSED_EFFECT_SCREEN_ON = 1 << 1;
Julia Reynoldsf612869ae2015-11-05 16:48:55 -05001427
Julia Reynoldsccc6ae62018-03-01 16:24:49 -05001428 /**
1429 * Whether {@link Notification#fullScreenIntent full screen intents} from
1430 * notifications intercepted by DND are blocked.
1431 */
1432 public static final int SUPPRESSED_EFFECT_FULL_SCREEN_INTENT = 1 << 2;
1433
1434 /**
1435 * Whether {@link NotificationChannel#shouldShowLights() notification lights} from
1436 * notifications intercepted by DND are blocked.
1437 */
1438 public static final int SUPPRESSED_EFFECT_LIGHTS = 1 << 3;
1439
1440 /**
1441 * Whether notifications intercepted by DND are prevented from peeking.
1442 */
1443 public static final int SUPPRESSED_EFFECT_PEEK = 1 << 4;
1444
1445 /**
1446 * Whether notifications intercepted by DND are prevented from appearing in the status bar,
1447 * on devices that support status bars.
1448 */
1449 public static final int SUPPRESSED_EFFECT_STATUS_BAR = 1 << 5;
1450
1451 /**
1452 * Whether {@link NotificationChannel#canShowBadge() badges} from
1453 * notifications intercepted by DND are blocked on devices that support badging.
1454 */
1455 public static final int SUPPRESSED_EFFECT_BADGE = 1 << 6;
1456
1457 /**
1458 * Whether notification intercepted by DND are prevented from appearing on ambient displays
1459 * on devices that support ambient display.
1460 */
1461 public static final int SUPPRESSED_EFFECT_AMBIENT = 1 << 7;
1462
1463 /**
1464 * Whether notification intercepted by DND are prevented from appearing in notification
1465 * list views like the notification shade or lockscreen on devices that support those
1466 * views.
1467 */
1468 public static final int SUPPRESSED_EFFECT_NOTIFICATION_LIST = 1 << 8;
1469
Julia Reynoldsf612869ae2015-11-05 16:48:55 -05001470 private static final int[] ALL_SUPPRESSED_EFFECTS = {
Julia Reynoldsd5607292016-02-05 15:25:58 -05001471 SUPPRESSED_EFFECT_SCREEN_OFF,
Julia Reynolds61721582016-01-05 08:35:25 -05001472 SUPPRESSED_EFFECT_SCREEN_ON,
Julia Reynoldsccc6ae62018-03-01 16:24:49 -05001473 SUPPRESSED_EFFECT_FULL_SCREEN_INTENT,
1474 SUPPRESSED_EFFECT_LIGHTS,
1475 SUPPRESSED_EFFECT_PEEK,
1476 SUPPRESSED_EFFECT_STATUS_BAR,
1477 SUPPRESSED_EFFECT_BADGE,
1478 SUPPRESSED_EFFECT_AMBIENT,
1479 SUPPRESSED_EFFECT_NOTIFICATION_LIST
Julia Reynoldsf612869ae2015-11-05 16:48:55 -05001480 };
1481
Julia Reynolds47f42802018-04-09 08:47:39 -04001482 private static final int[] SCREEN_OFF_SUPPRESSED_EFFECTS = {
1483 SUPPRESSED_EFFECT_SCREEN_OFF,
1484 SUPPRESSED_EFFECT_FULL_SCREEN_INTENT,
1485 SUPPRESSED_EFFECT_LIGHTS,
1486 SUPPRESSED_EFFECT_AMBIENT,
1487 };
1488
1489 private static final int[] SCREEN_ON_SUPPRESSED_EFFECTS = {
1490 SUPPRESSED_EFFECT_SCREEN_ON,
1491 SUPPRESSED_EFFECT_PEEK,
1492 SUPPRESSED_EFFECT_STATUS_BAR,
1493 SUPPRESSED_EFFECT_BADGE,
1494 SUPPRESSED_EFFECT_NOTIFICATION_LIST
1495 };
1496
Julia Reynoldsf612869ae2015-11-05 16:48:55 -05001497 /**
1498 * Visual effects to suppress for a notification that is filtered by Do Not Disturb mode.
1499 * Bitmask of SUPPRESSED_EFFECT_* constants.
1500 */
1501 public final int suppressedVisualEffects;
1502
Julia Reynoldscedacef2016-03-04 08:18:47 -05001503 /**
Beverly86d076f2018-04-17 14:44:52 -04001504 * @hide
1505 */
1506 public static final int STATE_CHANNELS_BYPASSING_DND = 1 << 0;
1507
1508 /**
1509 * @hide
1510 */
1511 public static final int STATE_UNSET = -1;
1512
1513 /**
1514 * Notification state information that is necessary to determine Do Not Disturb behavior.
1515 * Bitmask of STATE_* constants.
1516 * @hide
1517 */
1518 public final int state;
1519
1520 /**
Julia Reynoldscedacef2016-03-04 08:18:47 -05001521 * Constructs a policy for Do Not Disturb priority mode behavior.
1522 *
Julia Reynoldsccc6ae62018-03-01 16:24:49 -05001523 * <p>
1524 * Apps that target API levels below {@link Build.VERSION_CODES#P} cannot
1525 * change user-designated values to allow or disallow
1526 * {@link Policy#PRIORITY_CATEGORY_ALARMS}, {@link Policy#PRIORITY_CATEGORY_SYSTEM}, and
1527 * {@link Policy#PRIORITY_CATEGORY_MEDIA} from bypassing dnd.
1528 *
Julia Reynoldscedacef2016-03-04 08:18:47 -05001529 * @param priorityCategories bitmask of categories of notifications that can bypass DND.
1530 * @param priorityCallSenders which callers can bypass DND.
1531 * @param priorityMessageSenders which message senders can bypass DND.
1532 */
John Spurlock80774932015-05-07 17:38:50 -04001533 public Policy(int priorityCategories, int priorityCallSenders, int priorityMessageSenders) {
Julia Reynoldsf612869ae2015-11-05 16:48:55 -05001534 this(priorityCategories, priorityCallSenders, priorityMessageSenders,
Beverly86d076f2018-04-17 14:44:52 -04001535 SUPPRESSED_EFFECTS_UNSET, STATE_UNSET);
Julia Reynoldsf612869ae2015-11-05 16:48:55 -05001536 }
1537
Julia Reynoldscedacef2016-03-04 08:18:47 -05001538 /**
1539 * Constructs a policy for Do Not Disturb priority mode behavior.
1540 *
Julia Reynoldsccc6ae62018-03-01 16:24:49 -05001541 * <p>
1542 * Apps that target API levels below {@link Build.VERSION_CODES#P} cannot
1543 * change user-designated values to allow or disallow
1544 * {@link Policy#PRIORITY_CATEGORY_ALARMS}, {@link Policy#PRIORITY_CATEGORY_SYSTEM}, and
1545 * {@link Policy#PRIORITY_CATEGORY_MEDIA} from bypassing dnd.
1546 * <p>
1547 * Additionally, apps that target API levels below {@link Build.VERSION_CODES#P} can
1548 * only modify the {@link #SUPPRESSED_EFFECT_SCREEN_ON} and
1549 * {@link #SUPPRESSED_EFFECT_SCREEN_OFF} bits of the suppressed visual effects field.
1550 * All other suppressed effects will be ignored and reconstituted from the screen on
1551 * and screen off values.
1552 * <p>
1553 * Apps that target {@link Build.VERSION_CODES#P} or above can set any
1554 * suppressed visual effects. However, if any suppressed effects >
1555 * {@link #SUPPRESSED_EFFECT_SCREEN_ON} are set, {@link #SUPPRESSED_EFFECT_SCREEN_ON}
1556 * and {@link #SUPPRESSED_EFFECT_SCREEN_OFF} will be ignored and reconstituted from
1557 * the more specific suppressed visual effect bits. Apps should migrate to targeting
1558 * specific effects instead of the deprecated {@link #SUPPRESSED_EFFECT_SCREEN_ON} and
1559 * {@link #SUPPRESSED_EFFECT_SCREEN_OFF} effects.
1560 *
Julia Reynoldscedacef2016-03-04 08:18:47 -05001561 * @param priorityCategories bitmask of categories of notifications that can bypass DND.
1562 * @param priorityCallSenders which callers can bypass DND.
1563 * @param priorityMessageSenders which message senders can bypass DND.
1564 * @param suppressedVisualEffects which visual interruptions should be suppressed from
1565 * notifications that are filtered by DND.
1566 */
Julia Reynoldsf612869ae2015-11-05 16:48:55 -05001567 public Policy(int priorityCategories, int priorityCallSenders, int priorityMessageSenders,
1568 int suppressedVisualEffects) {
John Spurlock1fc476d2015-04-14 16:05:20 -04001569 this.priorityCategories = priorityCategories;
John Spurlock80774932015-05-07 17:38:50 -04001570 this.priorityCallSenders = priorityCallSenders;
1571 this.priorityMessageSenders = priorityMessageSenders;
Julia Reynoldsf612869ae2015-11-05 16:48:55 -05001572 this.suppressedVisualEffects = suppressedVisualEffects;
Beverly86d076f2018-04-17 14:44:52 -04001573 this.state = STATE_UNSET;
1574 }
1575
1576 /** @hide */
1577 public Policy(int priorityCategories, int priorityCallSenders, int priorityMessageSenders,
1578 int suppressedVisualEffects, int state) {
1579 this.priorityCategories = priorityCategories;
1580 this.priorityCallSenders = priorityCallSenders;
1581 this.priorityMessageSenders = priorityMessageSenders;
1582 this.suppressedVisualEffects = suppressedVisualEffects;
1583 this.state = state;
John Spurlock1fc476d2015-04-14 16:05:20 -04001584 }
1585
1586 /** @hide */
1587 public Policy(Parcel source) {
Beverly86d076f2018-04-17 14:44:52 -04001588 this(source.readInt(), source.readInt(), source.readInt(), source.readInt(),
1589 source.readInt());
John Spurlock1fc476d2015-04-14 16:05:20 -04001590 }
1591
1592 @Override
1593 public void writeToParcel(Parcel dest, int flags) {
1594 dest.writeInt(priorityCategories);
John Spurlock80774932015-05-07 17:38:50 -04001595 dest.writeInt(priorityCallSenders);
1596 dest.writeInt(priorityMessageSenders);
Julia Reynoldsf612869ae2015-11-05 16:48:55 -05001597 dest.writeInt(suppressedVisualEffects);
Beverly86d076f2018-04-17 14:44:52 -04001598 dest.writeInt(state);
John Spurlock1fc476d2015-04-14 16:05:20 -04001599 }
1600
1601 @Override
1602 public int describeContents() {
1603 return 0;
1604 }
1605
1606 @Override
1607 public int hashCode() {
Julia Reynoldsf612869ae2015-11-05 16:48:55 -05001608 return Objects.hash(priorityCategories, priorityCallSenders, priorityMessageSenders,
1609 suppressedVisualEffects);
John Spurlock1fc476d2015-04-14 16:05:20 -04001610 }
1611
1612 @Override
1613 public boolean equals(Object o) {
1614 if (!(o instanceof Policy)) return false;
1615 if (o == this) return true;
1616 final Policy other = (Policy) o;
1617 return other.priorityCategories == priorityCategories
John Spurlock80774932015-05-07 17:38:50 -04001618 && other.priorityCallSenders == priorityCallSenders
Julia Reynoldsf612869ae2015-11-05 16:48:55 -05001619 && other.priorityMessageSenders == priorityMessageSenders
Beverly9cb05c92018-11-28 10:03:23 -05001620 && suppressedVisualEffectsEqual(suppressedVisualEffects,
1621 other.suppressedVisualEffects);
1622 }
1623
1624
1625 private boolean suppressedVisualEffectsEqual(int suppressedEffects,
1626 int otherSuppressedVisualEffects) {
1627 if (suppressedEffects == otherSuppressedVisualEffects) {
1628 return true;
1629 }
1630
1631 if ((suppressedEffects & SUPPRESSED_EFFECT_SCREEN_ON) != 0) {
1632 suppressedEffects |= SUPPRESSED_EFFECT_PEEK;
1633 }
1634 if ((suppressedEffects & SUPPRESSED_EFFECT_SCREEN_OFF) != 0) {
1635 suppressedEffects |= SUPPRESSED_EFFECT_FULL_SCREEN_INTENT;
1636 suppressedEffects |= SUPPRESSED_EFFECT_LIGHTS;
1637 suppressedEffects |= SUPPRESSED_EFFECT_AMBIENT;
1638 }
1639
1640 if ((otherSuppressedVisualEffects & SUPPRESSED_EFFECT_SCREEN_ON) != 0) {
1641 otherSuppressedVisualEffects |= SUPPRESSED_EFFECT_PEEK;
1642 }
1643 if ((otherSuppressedVisualEffects & SUPPRESSED_EFFECT_SCREEN_OFF) != 0) {
1644 otherSuppressedVisualEffects |= SUPPRESSED_EFFECT_FULL_SCREEN_INTENT;
1645 otherSuppressedVisualEffects |= SUPPRESSED_EFFECT_LIGHTS;
1646 otherSuppressedVisualEffects |= SUPPRESSED_EFFECT_AMBIENT;
1647 }
1648
1649 if ((suppressedEffects & SUPPRESSED_EFFECT_SCREEN_ON)
1650 != (otherSuppressedVisualEffects & SUPPRESSED_EFFECT_SCREEN_ON)) {
1651 int currSuppressedEffects = (suppressedEffects & SUPPRESSED_EFFECT_SCREEN_ON) != 0
1652 ? otherSuppressedVisualEffects : suppressedEffects;
1653 if ((currSuppressedEffects & SUPPRESSED_EFFECT_PEEK) == 0) {
1654 return false;
1655 }
1656 }
1657
1658 if ((suppressedEffects & SUPPRESSED_EFFECT_SCREEN_OFF)
1659 != (otherSuppressedVisualEffects & SUPPRESSED_EFFECT_SCREEN_OFF)) {
1660 int currSuppressedEffects = (suppressedEffects & SUPPRESSED_EFFECT_SCREEN_OFF) != 0
1661 ? otherSuppressedVisualEffects : suppressedEffects;
1662 if ((currSuppressedEffects & SUPPRESSED_EFFECT_FULL_SCREEN_INTENT) == 0
1663 || (currSuppressedEffects & SUPPRESSED_EFFECT_LIGHTS) == 0
1664 || (currSuppressedEffects & SUPPRESSED_EFFECT_AMBIENT) == 0) {
1665 return false;
1666 }
1667 }
1668
1669 int thisWithoutOldEffects = suppressedEffects
1670 & ~SUPPRESSED_EFFECT_SCREEN_ON
1671 & ~SUPPRESSED_EFFECT_SCREEN_OFF;
1672 int otherWithoutOldEffects = otherSuppressedVisualEffects
1673 & ~SUPPRESSED_EFFECT_SCREEN_ON
1674 & ~SUPPRESSED_EFFECT_SCREEN_OFF;
1675 return thisWithoutOldEffects == otherWithoutOldEffects;
John Spurlock1fc476d2015-04-14 16:05:20 -04001676 }
1677
1678 @Override
1679 public String toString() {
1680 return "NotificationManager.Policy["
1681 + "priorityCategories=" + priorityCategoriesToString(priorityCategories)
John Spurlock80774932015-05-07 17:38:50 -04001682 + ",priorityCallSenders=" + prioritySendersToString(priorityCallSenders)
1683 + ",priorityMessageSenders=" + prioritySendersToString(priorityMessageSenders)
Julia Reynoldsf612869ae2015-11-05 16:48:55 -05001684 + ",suppressedVisualEffects="
1685 + suppressedEffectsToString(suppressedVisualEffects)
Beverly86d076f2018-04-17 14:44:52 -04001686 + ",areChannelsBypassingDnd=" + (((state & STATE_CHANNELS_BYPASSING_DND) != 0)
1687 ? "true" : "false")
John Spurlock1fc476d2015-04-14 16:05:20 -04001688 + "]";
1689 }
1690
Kweku Adams5ec78cd2017-09-25 16:29:54 -07001691 /** @hide */
Kweku Adamsbc84aec2018-01-23 13:33:12 -08001692 public void writeToProto(ProtoOutputStream proto, long fieldId) {
Kweku Adams5ec78cd2017-09-25 16:29:54 -07001693 final long pToken = proto.start(fieldId);
1694
1695 bitwiseToProtoEnum(proto, PolicyProto.PRIORITY_CATEGORIES, priorityCategories);
1696 proto.write(PolicyProto.PRIORITY_CALL_SENDER, priorityCallSenders);
1697 proto.write(PolicyProto.PRIORITY_MESSAGE_SENDER, priorityMessageSenders);
1698 bitwiseToProtoEnum(
1699 proto, PolicyProto.SUPPRESSED_VISUAL_EFFECTS, suppressedVisualEffects);
1700
1701 proto.end(pToken);
1702 }
1703
1704 private static void bitwiseToProtoEnum(ProtoOutputStream proto, long fieldId, int data) {
1705 for (int i = 1; data > 0; ++i, data >>>= 1) {
1706 if ((data & 1) == 1) {
1707 proto.write(fieldId, i);
1708 }
1709 }
1710 }
1711
Julia Reynoldsccc6ae62018-03-01 16:24:49 -05001712 /**
1713 * @hide
1714 */
1715 public static int getAllSuppressedVisualEffects() {
1716 int effects = 0;
1717 for (int i = 0; i < ALL_SUPPRESSED_EFFECTS.length; i++) {
1718 effects |= ALL_SUPPRESSED_EFFECTS[i];
1719 }
1720 return effects;
1721 }
1722
1723 /**
1724 * @hide
1725 */
1726 public static boolean areAllVisualEffectsSuppressed(int effects) {
1727 for (int i = 0; i < ALL_SUPPRESSED_EFFECTS.length; i++) {
1728 final int effect = ALL_SUPPRESSED_EFFECTS[i];
1729 if ((effects & effect) == 0) {
1730 return false;
1731 }
1732 }
1733 return true;
1734 }
1735
Julia Reynolds9aa1c9e2018-04-09 11:31:15 -04001736 private static int toggleEffects(int currentEffects, int[] effects, boolean suppress) {
1737 for (int i = 0; i < effects.length; i++) {
1738 final int effect = effects[i];
1739 if (suppress) {
1740 currentEffects |= effect;
1741 } else {
1742 currentEffects &= ~effect;
1743 }
1744 }
1745 return currentEffects;
1746 }
1747
Julia Reynoldsf612869ae2015-11-05 16:48:55 -05001748 public static String suppressedEffectsToString(int effects) {
1749 if (effects <= 0) return "";
1750 final StringBuilder sb = new StringBuilder();
1751 for (int i = 0; i < ALL_SUPPRESSED_EFFECTS.length; i++) {
1752 final int effect = ALL_SUPPRESSED_EFFECTS[i];
1753 if ((effects & effect) != 0) {
1754 if (sb.length() > 0) sb.append(',');
1755 sb.append(effectToString(effect));
1756 }
1757 effects &= ~effect;
1758 }
1759 if (effects != 0) {
1760 if (sb.length() > 0) sb.append(',');
1761 sb.append("UNKNOWN_").append(effects);
1762 }
1763 return sb.toString();
1764 }
1765
John Spurlock1fc476d2015-04-14 16:05:20 -04001766 public static String priorityCategoriesToString(int priorityCategories) {
1767 if (priorityCategories == 0) return "";
1768 final StringBuilder sb = new StringBuilder();
1769 for (int i = 0; i < ALL_PRIORITY_CATEGORIES.length; i++) {
1770 final int priorityCategory = ALL_PRIORITY_CATEGORIES[i];
1771 if ((priorityCategories & priorityCategory) != 0) {
1772 if (sb.length() > 0) sb.append(',');
1773 sb.append(priorityCategoryToString(priorityCategory));
1774 }
1775 priorityCategories &= ~priorityCategory;
1776 }
1777 if (priorityCategories != 0) {
1778 if (sb.length() > 0) sb.append(',');
1779 sb.append("PRIORITY_CATEGORY_UNKNOWN_").append(priorityCategories);
1780 }
1781 return sb.toString();
1782 }
1783
Julia Reynoldsf612869ae2015-11-05 16:48:55 -05001784 private static String effectToString(int effect) {
1785 switch (effect) {
Julia Reynoldsccc6ae62018-03-01 16:24:49 -05001786 case SUPPRESSED_EFFECT_FULL_SCREEN_INTENT:
1787 return "SUPPRESSED_EFFECT_FULL_SCREEN_INTENT";
1788 case SUPPRESSED_EFFECT_LIGHTS:
1789 return "SUPPRESSED_EFFECT_LIGHTS";
1790 case SUPPRESSED_EFFECT_PEEK:
1791 return "SUPPRESSED_EFFECT_PEEK";
1792 case SUPPRESSED_EFFECT_STATUS_BAR:
1793 return "SUPPRESSED_EFFECT_STATUS_BAR";
1794 case SUPPRESSED_EFFECT_BADGE:
1795 return "SUPPRESSED_EFFECT_BADGE";
1796 case SUPPRESSED_EFFECT_AMBIENT:
1797 return "SUPPRESSED_EFFECT_AMBIENT";
1798 case SUPPRESSED_EFFECT_NOTIFICATION_LIST:
1799 return "SUPPRESSED_EFFECT_NOTIFICATION_LIST";
1800 case SUPPRESSED_EFFECT_SCREEN_OFF:
1801 return "SUPPRESSED_EFFECT_SCREEN_OFF";
1802 case SUPPRESSED_EFFECT_SCREEN_ON:
1803 return "SUPPRESSED_EFFECT_SCREEN_ON";
1804 case SUPPRESSED_EFFECTS_UNSET:
1805 return "SUPPRESSED_EFFECTS_UNSET";
Julia Reynoldsf612869ae2015-11-05 16:48:55 -05001806 default: return "UNKNOWN_" + effect;
1807 }
1808 }
1809
John Spurlock1fc476d2015-04-14 16:05:20 -04001810 private static String priorityCategoryToString(int priorityCategory) {
1811 switch (priorityCategory) {
1812 case PRIORITY_CATEGORY_REMINDERS: return "PRIORITY_CATEGORY_REMINDERS";
1813 case PRIORITY_CATEGORY_EVENTS: return "PRIORITY_CATEGORY_EVENTS";
1814 case PRIORITY_CATEGORY_MESSAGES: return "PRIORITY_CATEGORY_MESSAGES";
1815 case PRIORITY_CATEGORY_CALLS: return "PRIORITY_CATEGORY_CALLS";
1816 case PRIORITY_CATEGORY_REPEAT_CALLERS: return "PRIORITY_CATEGORY_REPEAT_CALLERS";
Beverly04216872017-09-28 10:55:32 -04001817 case PRIORITY_CATEGORY_ALARMS: return "PRIORITY_CATEGORY_ALARMS";
Beverlyd6964762018-02-16 14:07:03 -05001818 case PRIORITY_CATEGORY_MEDIA: return "PRIORITY_CATEGORY_MEDIA";
1819 case PRIORITY_CATEGORY_SYSTEM: return "PRIORITY_CATEGORY_SYSTEM";
John Spurlock1fc476d2015-04-14 16:05:20 -04001820 default: return "PRIORITY_CATEGORY_UNKNOWN_" + priorityCategory;
1821 }
1822 }
1823
1824 public static String prioritySendersToString(int prioritySenders) {
1825 switch (prioritySenders) {
1826 case PRIORITY_SENDERS_ANY: return "PRIORITY_SENDERS_ANY";
1827 case PRIORITY_SENDERS_CONTACTS: return "PRIORITY_SENDERS_CONTACTS";
1828 case PRIORITY_SENDERS_STARRED: return "PRIORITY_SENDERS_STARRED";
1829 default: return "PRIORITY_SENDERS_UNKNOWN_" + prioritySenders;
1830 }
1831 }
1832
Jeff Sharkey9e8f83d2019-02-28 12:06:45 -07001833 public static final @android.annotation.NonNull Parcelable.Creator<Policy> CREATOR = new Parcelable.Creator<Policy>() {
John Spurlock1fc476d2015-04-14 16:05:20 -04001834 @Override
1835 public Policy createFromParcel(Parcel in) {
1836 return new Policy(in);
1837 }
1838
1839 @Override
1840 public Policy[] newArray(int size) {
1841 return new Policy[size];
1842 }
1843 };
Beverlyff2df9b2018-10-10 16:54:10 -04001844
1845 /** @hide **/
1846 public boolean allowAlarms() {
1847 return (priorityCategories & PRIORITY_CATEGORY_ALARMS) != 0;
1848 }
1849
1850 /** @hide **/
1851 public boolean allowMedia() {
1852 return (priorityCategories & PRIORITY_CATEGORY_MEDIA) != 0;
1853 }
1854
1855 /** @hide **/
1856 public boolean allowSystem() {
1857 return (priorityCategories & PRIORITY_CATEGORY_SYSTEM) != 0;
1858 }
1859
1860 /** @hide **/
1861 public boolean allowRepeatCallers() {
1862 return (priorityCategories & PRIORITY_CATEGORY_REPEAT_CALLERS) != 0;
1863 }
1864
1865 /** @hide **/
1866 public boolean allowCalls() {
1867 return (priorityCategories & PRIORITY_CATEGORY_CALLS) != 0;
1868 }
1869
1870 /** @hide **/
1871 public boolean allowMessages() {
1872 return (priorityCategories & PRIORITY_CATEGORY_MESSAGES) != 0;
1873 }
1874
1875 /** @hide **/
1876 public boolean allowEvents() {
1877 return (priorityCategories & PRIORITY_CATEGORY_EVENTS) != 0;
1878 }
1879
1880 /** @hide **/
1881 public boolean allowReminders() {
1882 return (priorityCategories & PRIORITY_CATEGORY_REMINDERS) != 0;
1883 }
1884
1885 /** @hide **/
1886 public int allowCallsFrom() {
1887 return priorityCallSenders;
1888 }
1889
1890 /** @hide **/
1891 public int allowMessagesFrom() {
1892 return priorityMessageSenders;
1893 }
1894
Beverly12196702018-12-12 15:05:51 -05001895 /** @hide **/
1896 public boolean showFullScreenIntents() {
1897 return (suppressedVisualEffects & SUPPRESSED_EFFECT_FULL_SCREEN_INTENT) == 0;
1898 }
1899
1900 /** @hide **/
1901 public boolean showLights() {
1902 return (suppressedVisualEffects & SUPPRESSED_EFFECT_LIGHTS) == 0;
1903 }
1904
1905 /** @hide **/
1906 public boolean showPeeking() {
1907 return (suppressedVisualEffects & SUPPRESSED_EFFECT_PEEK) == 0;
1908 }
1909
1910 /** @hide **/
1911 public boolean showStatusBarIcons() {
1912 return (suppressedVisualEffects & SUPPRESSED_EFFECT_STATUS_BAR) == 0;
1913 }
1914
1915 /** @hide **/
1916 public boolean showAmbient() {
1917 return (suppressedVisualEffects & SUPPRESSED_EFFECT_AMBIENT) == 0;
1918 }
1919
1920 /** @hide **/
1921 public boolean showBadges() {
1922 return (suppressedVisualEffects & SUPPRESSED_EFFECT_BADGE) == 0;
1923 }
1924
1925 /** @hide **/
1926 public boolean showInNotificationList() {
1927 return (suppressedVisualEffects & SUPPRESSED_EFFECT_NOTIFICATION_LIST) == 0;
1928 }
1929
Beverlyff2df9b2018-10-10 16:54:10 -04001930 /**
1931 * returns a deep copy of this policy
1932 * @hide
1933 */
1934 public Policy copy() {
1935 final Parcel parcel = Parcel.obtain();
1936 try {
1937 writeToParcel(parcel, 0);
1938 parcel.setDataPosition(0);
1939 return new Policy(parcel);
1940 } finally {
1941 parcel.recycle();
1942 }
1943 }
John Spurlock1fc476d2015-04-14 16:05:20 -04001944 }
1945
Dan Sandler994349c2015-04-15 11:02:54 -04001946 /**
1947 * Recover a list of active notifications: ones that have been posted by the calling app that
1948 * have not yet been dismissed by the user or {@link #cancel(String, int)}ed by the app.
1949 *
Julia Reynoldsd12392c2018-12-17 14:06:04 -05001950 * <p><Each notification is embedded in a {@link StatusBarNotification} object, including the
Dan Sandler994349c2015-04-15 11:02:54 -04001951 * original <code>tag</code> and <code>id</code> supplied to
1952 * {@link #notify(String, int, Notification) notify()}
1953 * (via {@link StatusBarNotification#getTag() getTag()} and
1954 * {@link StatusBarNotification#getId() getId()}) as well as a copy of the original
1955 * {@link Notification} object (via {@link StatusBarNotification#getNotification()}).
Julia Reynoldsd12392c2018-12-17 14:06:04 -05001956 * </p>
1957 * <p>From {@link Build.VERSION_CODES#Q}, will also return notifications you've posted as an
1958 * app's notification delegate via
1959 * {@link NotificationManager#notifyAsPackage(String, String, int, Notification)}.
1960 * </p>
Dan Sandler994349c2015-04-15 11:02:54 -04001961 *
1962 * @return An array of {@link StatusBarNotification}.
1963 */
1964 public StatusBarNotification[] getActiveNotifications() {
1965 final INotificationManager service = getService();
1966 final String pkg = mContext.getPackageName();
1967 try {
1968 final ParceledListSlice<StatusBarNotification> parceledList
Jeff Sharkeyad357d12018-02-02 13:25:31 -07001969 = service.getAppActiveNotifications(pkg, mContext.getUserId());
Julia Reynolds34a80842018-09-21 13:01:00 -04001970 if (parceledList != null) {
1971 final List<StatusBarNotification> list = parceledList.getList();
1972 return list.toArray(new StatusBarNotification[list.size()]);
1973 }
Dan Sandler994349c2015-04-15 11:02:54 -04001974 } catch (RemoteException e) {
Jeff Sharkeyc53962d2016-03-01 19:27:23 -07001975 throw e.rethrowFromSystemServer();
Dan Sandler994349c2015-04-15 11:02:54 -04001976 }
Julia Reynolds34a80842018-09-21 13:01:00 -04001977 return new StatusBarNotification[0];
Dan Sandler994349c2015-04-15 11:02:54 -04001978 }
John Spurlock80774932015-05-07 17:38:50 -04001979
1980 /**
1981 * Gets the current notification interruption filter.
John Spurlock80774932015-05-07 17:38:50 -04001982 * <p>
Jeff Sharkey6503bd82017-04-19 23:24:18 -06001983 * The interruption filter defines which notifications are allowed to
1984 * interrupt the user (e.g. via sound &amp; vibration) and is applied
1985 * globally.
John Spurlock80774932015-05-07 17:38:50 -04001986 */
Julia Reynolds0edb50c2016-02-26 14:08:25 -05001987 public final @InterruptionFilter int getCurrentInterruptionFilter() {
John Spurlock80774932015-05-07 17:38:50 -04001988 final INotificationManager service = getService();
1989 try {
1990 return zenModeToInterruptionFilter(service.getZenMode());
1991 } catch (RemoteException e) {
Jeff Sharkeyc53962d2016-03-01 19:27:23 -07001992 throw e.rethrowFromSystemServer();
John Spurlock80774932015-05-07 17:38:50 -04001993 }
John Spurlock80774932015-05-07 17:38:50 -04001994 }
1995
1996 /**
1997 * Sets the current notification interruption filter.
John Spurlock80774932015-05-07 17:38:50 -04001998 * <p>
Jeff Sharkey6503bd82017-04-19 23:24:18 -06001999 * The interruption filter defines which notifications are allowed to
2000 * interrupt the user (e.g. via sound &amp; vibration) and is applied
2001 * globally.
John Spurlock80774932015-05-07 17:38:50 -04002002 * <p>
Jeff Sharkey6503bd82017-04-19 23:24:18 -06002003 * Only available if policy access is granted to this package. See
2004 * {@link #isNotificationPolicyAccessGranted}.
John Spurlock80774932015-05-07 17:38:50 -04002005 */
Jeff Sharkey6503bd82017-04-19 23:24:18 -06002006 public final void setInterruptionFilter(@InterruptionFilter int interruptionFilter) {
John Spurlock80774932015-05-07 17:38:50 -04002007 final INotificationManager service = getService();
2008 try {
2009 service.setInterruptionFilter(mContext.getOpPackageName(), interruptionFilter);
2010 } catch (RemoteException e) {
Jeff Sharkeyc53962d2016-03-01 19:27:23 -07002011 throw e.rethrowFromSystemServer();
John Spurlock80774932015-05-07 17:38:50 -04002012 }
2013 }
2014
2015 /** @hide */
2016 public static int zenModeToInterruptionFilter(int zen) {
2017 switch (zen) {
2018 case Global.ZEN_MODE_OFF: return INTERRUPTION_FILTER_ALL;
2019 case Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS: return INTERRUPTION_FILTER_PRIORITY;
2020 case Global.ZEN_MODE_ALARMS: return INTERRUPTION_FILTER_ALARMS;
2021 case Global.ZEN_MODE_NO_INTERRUPTIONS: return INTERRUPTION_FILTER_NONE;
2022 default: return INTERRUPTION_FILTER_UNKNOWN;
2023 }
2024 }
2025
2026 /** @hide */
2027 public static int zenModeFromInterruptionFilter(int interruptionFilter, int defValue) {
2028 switch (interruptionFilter) {
2029 case INTERRUPTION_FILTER_ALL: return Global.ZEN_MODE_OFF;
2030 case INTERRUPTION_FILTER_PRIORITY: return Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS;
2031 case INTERRUPTION_FILTER_ALARMS: return Global.ZEN_MODE_ALARMS;
2032 case INTERRUPTION_FILTER_NONE: return Global.ZEN_MODE_NO_INTERRUPTIONS;
2033 default: return defValue;
2034 }
2035 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002036}