blob: 850645dd81e2b120ecea7731b398d842f6468329 [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 Reynoldsad6dd352019-03-07 16:46:22 -050045import android.service.notification.Adjustment;
Julia Reynolds68062072018-08-06 15:38:21 -040046import android.service.notification.Condition;
Dan Sandler994349c2015-04-15 11:02:54 -040047import android.service.notification.StatusBarNotification;
John Spurlockcdb57ae2015-02-11 19:04:11 -050048import android.service.notification.ZenModeConfig;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080049import android.util.Log;
Kweku Adams5ec78cd2017-09-25 16:29:54 -070050import android.util.proto.ProtoOutputStream;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080051
Julia Reynolds0edb50c2016-02-26 14:08:25 -050052import java.lang.annotation.Retention;
53import java.lang.annotation.RetentionPolicy;
Beverlyc629ee42018-10-02 16:14:07 -040054import java.util.ArrayList;
Geoffrey Pitsch03533712017-01-05 10:30:07 -050055import java.util.Arrays;
Julia Reynolds361e82d32016-02-26 18:19:49 -050056import java.util.HashMap;
Chris Wren5ab5c742016-05-10 15:32:23 -040057import java.util.List;
Julia Reynolds361e82d32016-02-26 18:19:49 -050058import java.util.Map;
John Spurlock1fc476d2015-04-14 16:05:20 -040059import java.util.Objects;
60
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080061/**
62 * Class to notify the user of events that happen. This is how you tell
63 * the user that something has happened in the background. {@more}
64 *
65 * Notifications can take different forms:
66 * <ul>
67 * <li>A persistent icon that goes in the status bar and is accessible
68 * through the launcher, (when the user selects it, a designated Intent
69 * can be launched),</li>
70 * <li>Turning on or flashing LEDs on the device, or</li>
71 * <li>Alerting the user by flashing the backlight, playing a sound,
72 * or vibrating.</li>
73 * </ul>
74 *
75 * <p>
Peter Collingbourneb97c3492010-10-13 20:04:52 +010076 * Each of the notify methods takes an int id parameter and optionally a
77 * {@link String} tag parameter, which may be {@code null}. These parameters
78 * are used to form a pair (tag, id), or ({@code null}, id) if tag is
79 * unspecified. This pair identifies this notification from your app to the
80 * system, so that pair should be unique within your app. If you call one
81 * of the notify methods with a (tag, id) pair that is currently active and
82 * a new set of notification parameters, it will be updated. For example,
83 * if you pass a new status bar icon, the old icon in the status bar will
84 * be replaced with the new one. This is also the same tag and id you pass
85 * to the {@link #cancel(int)} or {@link #cancel(String, int)} method to clear
86 * this notification.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080087 *
Joe Fernandez558459f2011-10-13 16:47:36 -070088 * <div class="special reference">
89 * <h3>Developer Guides</h3>
90 * <p>For a guide to creating notifications, read the
91 * <a href="{@docRoot}guide/topics/ui/notifiers/notifications.html">Status Bar Notifications</a>
92 * developer guide.</p>
93 * </div>
94 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080095 * @see android.app.Notification
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080096 */
Jeff Sharkeyd86b8fe2017-06-02 17:36:26 -060097@SystemService(Context.NOTIFICATION_SERVICE)
98public class NotificationManager {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080099 private static String TAG = "NotificationManager";
Joe Onorato43a17652011-04-06 19:22:23 -0700100 private static boolean localLOGV = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800101
John Spurlockb4782522014-08-22 14:54:46 -0400102 /**
Julia Reynoldsfc9767b2018-01-22 17:45:16 -0500103 * Intent that is broadcast when an application is blocked or unblocked.
104 *
105 * This broadcast is only sent to the app whose block state has changed.
106 *
107 * Input: nothing
Julia Reynolds44ff7c92018-02-05 10:02:30 -0500108 * Output: {@link #EXTRA_BLOCKED_STATE}
Julia Reynoldsfc9767b2018-01-22 17:45:16 -0500109 */
110 @SdkConstant(SdkConstant.SdkConstantType.BROADCAST_INTENT_ACTION)
111 public static final String ACTION_APP_BLOCK_STATE_CHANGED =
112 "android.app.action.APP_BLOCK_STATE_CHANGED";
113
114 /**
Julia Reynolds3eb3ffd2017-11-16 10:11:32 -0500115 * Intent that is broadcast when a {@link NotificationChannel} is blocked
116 * (when {@link NotificationChannel#getImportance()} is {@link #IMPORTANCE_NONE}) or unblocked
117 * (when {@link NotificationChannel#getImportance()} is anything other than
118 * {@link #IMPORTANCE_NONE}).
119 *
120 * This broadcast is only sent to the app that owns the channel that has changed.
121 *
122 * Input: nothing
Julia Reynolds44ff7c92018-02-05 10:02:30 -0500123 * Output: {@link #EXTRA_NOTIFICATION_CHANNEL_ID}
124 * Output: {@link #EXTRA_BLOCKED_STATE}
Julia Reynolds3eb3ffd2017-11-16 10:11:32 -0500125 */
126 @SdkConstant(SdkConstant.SdkConstantType.BROADCAST_INTENT_ACTION)
127 public static final String ACTION_NOTIFICATION_CHANNEL_BLOCK_STATE_CHANGED =
128 "android.app.action.NOTIFICATION_CHANNEL_BLOCK_STATE_CHANGED";
129
130 /**
Julia Reynolds44ff7c92018-02-05 10:02:30 -0500131 * Extra for {@link #ACTION_NOTIFICATION_CHANNEL_BLOCK_STATE_CHANGED} containing the id of the
132 * {@link NotificationChannel} which has a new blocked state.
Julia Reynolds3eb3ffd2017-11-16 10:11:32 -0500133 *
Julia Reynolds44ff7c92018-02-05 10:02:30 -0500134 * The value will be the {@link NotificationChannel#getId()} of the channel.
Julia Reynolds3eb3ffd2017-11-16 10:11:32 -0500135 */
Julia Reynolds44ff7c92018-02-05 10:02:30 -0500136 public static final String EXTRA_NOTIFICATION_CHANNEL_ID =
137 "android.app.extra.NOTIFICATION_CHANNEL_ID";
138
139 /**
140 * Extra for {@link #ACTION_NOTIFICATION_CHANNEL_GROUP_BLOCK_STATE_CHANGED} containing the id
141 * of the {@link NotificationChannelGroup} which has a new blocked state.
142 *
143 * The value will be the {@link NotificationChannelGroup#getId()} of the group.
144 */
145 public static final String EXTRA_NOTIFICATION_CHANNEL_GROUP_ID =
146 "android.app.extra.NOTIFICATION_CHANNEL_GROUP_ID";
147
Julia Reynolds3eb3ffd2017-11-16 10:11:32 -0500148
149 /**
150 * Extra for {@link #ACTION_NOTIFICATION_CHANNEL_BLOCK_STATE_CHANGED} or
151 * {@link #ACTION_NOTIFICATION_CHANNEL_GROUP_BLOCK_STATE_CHANGED} containing the new blocked
152 * state as a boolean.
153 *
154 * The value will be {@code true} if this channel or group is now blocked and {@code false} if
155 * this channel or group is now unblocked.
156 */
157 public static final String EXTRA_BLOCKED_STATE = "android.app.extra.BLOCKED_STATE";
158
Julia Reynolds3eb3ffd2017-11-16 10:11:32 -0500159 /**
160 * Intent that is broadcast when a {@link NotificationChannelGroup} is
161 * {@link NotificationChannelGroup#isBlocked() blocked} or unblocked.
162 *
163 * This broadcast is only sent to the app that owns the channel group that has changed.
164 *
165 * Input: nothing
Julia Reynolds44ff7c92018-02-05 10:02:30 -0500166 * Output: {@link #EXTRA_NOTIFICATION_CHANNEL_GROUP_ID}
167 * Output: {@link #EXTRA_BLOCKED_STATE}
Julia Reynolds3eb3ffd2017-11-16 10:11:32 -0500168 */
169 @SdkConstant(SdkConstant.SdkConstantType.BROADCAST_INTENT_ACTION)
170 public static final String ACTION_NOTIFICATION_CHANNEL_GROUP_BLOCK_STATE_CHANGED =
171 "android.app.action.NOTIFICATION_CHANNEL_GROUP_BLOCK_STATE_CHANGED";
172
173 /**
Julia Reynolds3ec93302019-07-11 15:27:31 -0400174 * Intent that is broadcast when the status of an {@link AutomaticZenRule} has changed.
175 *
176 * <p>Use this to know whether you need to continue monitor to device state in order to
177 * provide up-to-date states (with {@link #setAutomaticZenRuleState(String, Condition)}) for
178 * this rule.</p>
179 *
180 * Input: nothing
181 * Output: {@link #EXTRA_AUTOMATIC_ZEN_RULE_ID}
182 * Output: {@link #EXTRA_AUTOMATIC_ZEN_RULE_STATUS}
183 */
184 @SdkConstant(SdkConstant.SdkConstantType.BROADCAST_INTENT_ACTION)
185 public static final String ACTION_AUTOMATIC_ZEN_RULE_STATUS_CHANGED =
186 "android.app.action.AUTOMATIC_ZEN_RULE_STATUS_CHANGED";
187
188 /**
189 * Integer extra for {@link #ACTION_AUTOMATIC_ZEN_RULE_STATUS_CHANGED} containing the state of
190 * the {@link AutomaticZenRule}.
191 *
192 * <p>
193 * The value will be one of {@link #AUTOMATIC_RULE_STATUS_ENABLED},
194 * {@link #AUTOMATIC_RULE_STATUS_DISABLED}, {@link #AUTOMATIC_RULE_STATUS_REMOVED},
195 * {@link #AUTOMATIC_RULE_STATUS_UNKNOWN}.
196 * </p>
197 */
198 public static final String EXTRA_AUTOMATIC_ZEN_RULE_STATUS =
199 "android.app.extra.AUTOMATIC_ZEN_RULE_STATUS";
200
201 /**
202 * String extra for {@link #ACTION_AUTOMATIC_ZEN_RULE_STATUS_CHANGED} containing the id of the
203 * {@link AutomaticZenRule} (see {@link #addAutomaticZenRule(AutomaticZenRule)}) that has
204 * changed.
205 */
206 public static final String EXTRA_AUTOMATIC_ZEN_RULE_ID =
207 "android.app.extra.AUTOMATIC_ZEN_RULE_ID";
208
209 /** @hide */
210 @IntDef(prefix = { "AUTOMATIC_RULE_STATUS" }, value = {
211 AUTOMATIC_RULE_STATUS_ENABLED, AUTOMATIC_RULE_STATUS_DISABLED,
212 AUTOMATIC_RULE_STATUS_REMOVED, AUTOMATIC_RULE_STATUS_UNKNOWN
213 })
214 @Retention(RetentionPolicy.SOURCE)
215 public @interface AutomaticZenRuleStatus {}
216
217 /**
218 * Constant value for {@link #EXTRA_AUTOMATIC_ZEN_RULE_STATUS} - the current status of the
219 * rule is unknown at your target sdk version, and you should continue to provide state changes
220 * via {@link #setAutomaticZenRuleState(String, Condition)}.
221 */
222 public static final int AUTOMATIC_RULE_STATUS_UNKNOWN = -1;
223
224 /**
225 * Constant value for {@link #EXTRA_AUTOMATIC_ZEN_RULE_STATUS} - the given rule currently
226 * exists and is enabled. You should continue to provide state changes via
227 * {@link #setAutomaticZenRuleState(String, Condition)}.
228 */
229 public static final int AUTOMATIC_RULE_STATUS_ENABLED = 1;
230
231 /**
232 * Constant value for {@link #EXTRA_AUTOMATIC_ZEN_RULE_STATUS} - the given rule currently
233 * exists but is disabled. You do not need to continue to provide state changes via
234 * {@link #setAutomaticZenRuleState(String, Condition)} until the rule is reenabled.
235 */
236 public static final int AUTOMATIC_RULE_STATUS_DISABLED = 2;
237
238 /**
239 * Constant value for {@link #EXTRA_AUTOMATIC_ZEN_RULE_STATUS} - the given rule has been
240 * deleted. Further calls to {@link #setAutomaticZenRuleState(String, Condition)} will be
241 * ignored.
242 */
243 public static final int AUTOMATIC_RULE_STATUS_REMOVED = 3;
244
245 /**
John Spurlockb4782522014-08-22 14:54:46 -0400246 * Intent that is broadcast when the state of {@link #getEffectsSuppressor()} changes.
247 * This broadcast is only sent to registered receivers.
248 *
249 * @hide
250 */
251 @SdkConstant(SdkConstant.SdkConstantType.BROADCAST_INTENT_ACTION)
252 public static final String ACTION_EFFECTS_SUPPRESSOR_CHANGED
253 = "android.os.action.ACTION_EFFECTS_SUPPRESSOR_CHANGED";
254
John Spurlock1fc476d2015-04-14 16:05:20 -0400255 /**
John Spurlock7c74f782015-06-04 13:01:42 -0400256 * Intent that is broadcast when the state of {@link #isNotificationPolicyAccessGranted()}
257 * changes.
258 *
259 * This broadcast is only sent to registered receivers, and only to the apps that have changed.
260 */
261 @SdkConstant(SdkConstant.SdkConstantType.BROADCAST_INTENT_ACTION)
262 public static final String ACTION_NOTIFICATION_POLICY_ACCESS_GRANTED_CHANGED
263 = "android.app.action.NOTIFICATION_POLICY_ACCESS_GRANTED_CHANGED";
264
265 /**
John Spurlock1fc476d2015-04-14 16:05:20 -0400266 * Intent that is broadcast when the state of getNotificationPolicy() changes.
267 * This broadcast is only sent to registered receivers.
268 */
269 @SdkConstant(SdkConstant.SdkConstantType.BROADCAST_INTENT_ACTION)
270 public static final String ACTION_NOTIFICATION_POLICY_CHANGED
271 = "android.app.action.NOTIFICATION_POLICY_CHANGED";
272
John Spurlock80774932015-05-07 17:38:50 -0400273 /**
274 * Intent that is broadcast when the state of getCurrentInterruptionFilter() changes.
275 * This broadcast is only sent to registered receivers.
276 */
277 @SdkConstant(SdkConstant.SdkConstantType.BROADCAST_INTENT_ACTION)
278 public static final String ACTION_INTERRUPTION_FILTER_CHANGED
279 = "android.app.action.INTERRUPTION_FILTER_CHANGED";
280
281 /**
Jason Monka9927322015-12-13 16:22:37 -0500282 * Intent that is broadcast when the state of getCurrentInterruptionFilter() changes.
283 * @hide
284 */
285 @SdkConstant(SdkConstant.SdkConstantType.BROADCAST_INTENT_ACTION)
286 public static final String ACTION_INTERRUPTION_FILTER_CHANGED_INTERNAL
287 = "android.app.action.INTERRUPTION_FILTER_CHANGED_INTERNAL";
288
Julia Reynolds0edb50c2016-02-26 14:08:25 -0500289 /** @hide */
Jeff Sharkey6503bd82017-04-19 23:24:18 -0600290 @IntDef(prefix = { "INTERRUPTION_FILTER_" }, value = {
291 INTERRUPTION_FILTER_NONE, INTERRUPTION_FILTER_PRIORITY, INTERRUPTION_FILTER_ALARMS,
292 INTERRUPTION_FILTER_ALL, INTERRUPTION_FILTER_UNKNOWN
293 })
Julia Reynolds0edb50c2016-02-26 14:08:25 -0500294 @Retention(RetentionPolicy.SOURCE)
295 public @interface InterruptionFilter {}
296
Jason Monka9927322015-12-13 16:22:37 -0500297 /**
John Spurlock80774932015-05-07 17:38:50 -0400298 * {@link #getCurrentInterruptionFilter() Interruption filter} constant -
Julia Reynoldsdd0605b2016-04-06 10:26:54 -0400299 * Normal interruption filter - no notifications are suppressed.
John Spurlock80774932015-05-07 17:38:50 -0400300 */
301 public static final int INTERRUPTION_FILTER_ALL = 1;
302
303 /**
304 * {@link #getCurrentInterruptionFilter() Interruption filter} constant -
Julia Reynoldsdd0605b2016-04-06 10:26:54 -0400305 * Priority interruption filter - all notifications are suppressed except those that match
306 * the priority criteria. Some audio streams are muted. See
307 * {@link Policy#priorityCallSenders}, {@link Policy#priorityCategories},
308 * {@link Policy#priorityMessageSenders} to define or query this criteria. Users can
309 * additionally specify packages that can bypass this interruption filter.
John Spurlock80774932015-05-07 17:38:50 -0400310 */
311 public static final int INTERRUPTION_FILTER_PRIORITY = 2;
312
313 /**
314 * {@link #getCurrentInterruptionFilter() Interruption filter} constant -
Julia Reynoldsdd0605b2016-04-06 10:26:54 -0400315 * No interruptions filter - all notifications are suppressed and all audio streams (except
316 * those used for phone calls) and vibrations are muted.
John Spurlock80774932015-05-07 17:38:50 -0400317 */
318 public static final int INTERRUPTION_FILTER_NONE = 3;
319
320 /**
321 * {@link #getCurrentInterruptionFilter() Interruption filter} constant -
Julia Reynoldsdd0605b2016-04-06 10:26:54 -0400322 * Alarms only interruption filter - all notifications except those of category
323 * {@link Notification#CATEGORY_ALARM} are suppressed. Some audio streams are muted.
John Spurlock80774932015-05-07 17:38:50 -0400324 */
325 public static final int INTERRUPTION_FILTER_ALARMS = 4;
326
327 /** {@link #getCurrentInterruptionFilter() Interruption filter} constant - returned when
328 * the value is unavailable for any reason.
329 */
330 public static final int INTERRUPTION_FILTER_UNKNOWN = 0;
331
Chris Wren5ab5c742016-05-10 15:32:23 -0400332 /** @hide */
Jeff Sharkey6503bd82017-04-19 23:24:18 -0600333 @IntDef(prefix = { "IMPORTANCE_" }, value = {
334 IMPORTANCE_UNSPECIFIED, IMPORTANCE_NONE,
335 IMPORTANCE_MIN, IMPORTANCE_LOW, IMPORTANCE_DEFAULT, IMPORTANCE_HIGH
336 })
Chris Wren5ab5c742016-05-10 15:32:23 -0400337 @Retention(RetentionPolicy.SOURCE)
338 public @interface Importance {}
339
Julia Reynolds68062072018-08-06 15:38:21 -0400340 /**
341 * Activity Action: Launch an Automatic Zen Rule configuration screen
342 * <p>
343 * Input: Optionally, {@link #EXTRA_AUTOMATIC_RULE_ID}, if the configuration screen for an
344 * existing rule should be displayed. If the rule id is missing or null, apps should display
345 * a configuration screen where users can create a new instance of the rule.
346 * <p>
347 * Output: Nothing
348 * <p>
349 * You can have multiple activities handling this intent, if you support multiple
350 * {@link AutomaticZenRule rules}. In order for the system to properly display all of your
351 * rule types so that users can create new instances or configure existing ones, you need
352 * to add some extra metadata ({@link #META_DATA_AUTOMATIC_RULE_TYPE})
353 * to your activity tag in your manifest. If you'd like to limit the number of rules a user
354 * can create from this flow, you can additionally optionally include
355 * {@link #META_DATA_RULE_INSTANCE_LIMIT}.
356 *
357 * For example,
358 * &lt;meta-data
359 * android:name="android.app.zen.automatic.ruleType"
360 * android:value="@string/my_condition_rule">
361 * &lt;/meta-data>
362 * &lt;meta-data
363 * android:name="android.app.zen.automatic.ruleInstanceLimit"
364 * android:value="1">
365 * &lt;/meta-data>
366 * </p>
367 * </p>
368 *
369 * @see {@link #addAutomaticZenRule(AutomaticZenRule)}
370 */
371 @SdkConstant(SdkConstant.SdkConstantType.ACTIVITY_INTENT_ACTION)
372 public static final String ACTION_AUTOMATIC_ZEN_RULE =
373 "android.app.action.AUTOMATIC_ZEN_RULE";
374
375 /**
376 * Used as an optional string extra on {@link #ACTION_AUTOMATIC_ZEN_RULE} intents. If
377 * provided, contains the id of the {@link AutomaticZenRule} (as returned from
378 * {@link NotificationManager#addAutomaticZenRule(AutomaticZenRule)}) for which configuration
379 * settings should be displayed.
380 */
381 public static final String EXTRA_AUTOMATIC_RULE_ID = "android.app.extra.AUTOMATIC_RULE_ID";
382
383 /**
384 * A required {@code meta-data} tag for activities that handle
385 * {@link #ACTION_AUTOMATIC_ZEN_RULE}.
386 *
387 * This tag should contain a localized name of the type of the zen rule provided by the
388 * activity.
389 */
Julia Reynolds395bf7052019-03-21 11:41:17 -0400390 public static final String META_DATA_AUTOMATIC_RULE_TYPE =
391 "android.service.zen.automatic.ruleType";
Julia Reynolds68062072018-08-06 15:38:21 -0400392
393 /**
394 * An optional {@code meta-data} tag for activities that handle
395 * {@link #ACTION_AUTOMATIC_ZEN_RULE}.
396 *
397 * This tag should contain the maximum number of rule instances that
398 * can be created for this rule type. Omit or enter a value <= 0 to allow unlimited instances.
399 */
400 public static final String META_DATA_RULE_INSTANCE_LIMIT =
Julia Reynolds395bf7052019-03-21 11:41:17 -0400401 "android.service.zen.automatic.ruleInstanceLimit";
Julia Reynolds68062072018-08-06 15:38:21 -0400402
Chris Wren5ab5c742016-05-10 15:32:23 -0400403 /** Value signifying that the user has not expressed a per-app visibility override value.
404 * @hide */
405 public static final int VISIBILITY_NO_OVERRIDE = -1000;
Julia Reynolds85769912016-10-25 09:08:57 -0400406
Chris Wren5ab5c742016-05-10 15:32:23 -0400407 /**
408 * Value signifying that the user has not expressed an importance.
409 *
410 * This value is for persisting preferences, and should never be associated with
411 * an actual notification.
412 */
413 public static final int IMPORTANCE_UNSPECIFIED = -1000;
414
415 /**
Julia Reynoldsbaff4002016-12-15 11:34:26 -0500416 * A notification with no importance: does not show in the shade.
Chris Wren5ab5c742016-05-10 15:32:23 -0400417 */
418 public static final int IMPORTANCE_NONE = 0;
419
420 /**
Dianne Hackborn6e5bd3f2017-07-31 14:22:04 -0700421 * Min notification importance: only shows in the shade, below the fold. This should
422 * not be used with {@link Service#startForeground(int, Notification) Service.startForeground}
423 * since a foreground service is supposed to be something the user cares about so it does
424 * not make semantic sense to mark its notification as minimum importance. If you do this
425 * as of Android version {@link android.os.Build.VERSION_CODES#O}, the system will show
426 * a higher-priority notification about your app running in the background.
Chris Wren5ab5c742016-05-10 15:32:23 -0400427 */
428 public static final int IMPORTANCE_MIN = 1;
429
430 /**
Julia Reynolds12ad7ca2019-01-28 09:29:16 -0500431 * Low notification importance: Shows in the shade, and potentially in the status bar
432 * (see {@link #shouldHideSilentStatusBarIcons()}), but is not audibly intrusive.
Chris Wren5ab5c742016-05-10 15:32:23 -0400433 */
434 public static final int IMPORTANCE_LOW = 2;
435
436 /**
Julia Reynolds85769912016-10-25 09:08:57 -0400437 * Default notification importance: shows everywhere, makes noise, but does not visually
438 * intrude.
Chris Wren5ab5c742016-05-10 15:32:23 -0400439 */
440 public static final int IMPORTANCE_DEFAULT = 3;
441
442 /**
Julia Reynolds85769912016-10-25 09:08:57 -0400443 * Higher notification importance: shows everywhere, makes noise and peeks. May use full screen
444 * intents.
Chris Wren5ab5c742016-05-10 15:32:23 -0400445 */
446 public static final int IMPORTANCE_HIGH = 4;
447
448 /**
Julia Reynolds85769912016-10-25 09:08:57 -0400449 * Unused.
Chris Wren5ab5c742016-05-10 15:32:23 -0400450 */
451 public static final int IMPORTANCE_MAX = 5;
452
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100453 @UnsupportedAppUsage
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800454 private static INotificationManager sService;
455
Dianne Hackbornd8a43f62009-08-17 23:33:56 -0700456 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100457 @UnsupportedAppUsage
Dianne Hackbornd8a43f62009-08-17 23:33:56 -0700458 static public INotificationManager getService()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800459 {
460 if (sService != null) {
461 return sService;
462 }
463 IBinder b = ServiceManager.getService("notification");
464 sService = INotificationManager.Stub.asInterface(b);
465 return sService;
466 }
467
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100468 @UnsupportedAppUsage
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800469 /*package*/ NotificationManager(Context context, Handler handler)
470 {
471 mContext = context;
472 }
473
Jeff Sharkey69ddab42012-08-25 00:05:46 -0700474 /** {@hide} */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100475 @UnsupportedAppUsage
Jeff Sharkey69ddab42012-08-25 00:05:46 -0700476 public static NotificationManager from(Context context) {
477 return (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
478 }
479
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800480 /**
Daniel Sandlere97a3bc2011-02-07 16:47:07 -0500481 * Post a notification to be shown in the status bar. If a notification with
482 * the same id has already been posted by your application and has not yet been canceled, it
483 * will be replaced by the updated information.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800484 *
485 * @param id An identifier for this notification unique within your
486 * application.
Daniel Sandlere97a3bc2011-02-07 16:47:07 -0500487 * @param notification A {@link Notification} object describing what to show the user. Must not
488 * be null.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800489 */
490 public void notify(int id, Notification notification)
491 {
Fred Quintana6ecaff12009-09-25 14:23:13 -0700492 notify(null, id, notification);
493 }
494
495 /**
Julia Reynoldsa7ba45a2018-08-29 09:07:52 -0400496 * Posts a notification to be shown in the status bar. If a notification with
Daniel Sandlere97a3bc2011-02-07 16:47:07 -0500497 * the same tag and id has already been posted by your application and has not yet been
498 * canceled, it will be replaced by the updated information.
Fred Quintana6ecaff12009-09-25 14:23:13 -0700499 *
Julia Reynoldse0d711f2017-09-01 08:50:47 -0400500 * All {@link android.service.notification.NotificationListenerService listener services} will
501 * be granted {@link Intent#FLAG_GRANT_READ_URI_PERMISSION} access to any {@link Uri uris}
502 * provided on this notification or the
503 * {@link NotificationChannel} this notification is posted to using
504 * {@link Context#grantUriPermission(String, Uri, int)}. Permission will be revoked when the
505 * notification is canceled, or you can revoke permissions with
506 * {@link Context#revokeUriPermission(Uri, int)}.
507 *
Peter Collingbourneb97c3492010-10-13 20:04:52 +0100508 * @param tag A string identifier for this notification. May be {@code null}.
509 * @param id An identifier for this notification. The pair (tag, id) must be unique
510 * within your application.
Daniel Sandlere97a3bc2011-02-07 16:47:07 -0500511 * @param notification A {@link Notification} object describing what to
512 * show the user. Must not be null.
Fred Quintana6ecaff12009-09-25 14:23:13 -0700513 */
514 public void notify(String tag, int id, Notification notification)
515 {
Jeff Sharkeyad357d12018-02-02 13:25:31 -0700516 notifyAsUser(tag, id, notification, mContext.getUser());
Dianne Hackborn41203752012-08-31 14:05:51 -0700517 }
518
519 /**
Julia Reynoldsa7ba45a2018-08-29 09:07:52 -0400520 * Posts a notification as a specified package to be shown in the status bar. If a notification
521 * with the same tag and id has already been posted for that package and has not yet been
522 * canceled, it will be replaced by the updated information.
523 *
524 * All {@link android.service.notification.NotificationListenerService listener services} will
525 * be granted {@link Intent#FLAG_GRANT_READ_URI_PERMISSION} access to any {@link Uri uris}
526 * provided on this notification or the
527 * {@link NotificationChannel} this notification is posted to using
528 * {@link Context#grantUriPermission(String, Uri, int)}. Permission will be revoked when the
529 * notification is canceled, or you can revoke permissions with
530 * {@link Context#revokeUriPermission(Uri, int)}.
531 *
532 * @param targetPackage The package to post the notification as. The package must have granted
533 * you access to post notifications on their behalf with
534 * {@link #setNotificationDelegate(String)}.
535 * @param tag A string identifier for this notification. May be {@code null}.
536 * @param id An identifier for this notification. The pair (tag, id) must be unique
537 * within your application.
538 * @param notification A {@link Notification} object describing what to
539 * show the user. Must not be null.
540 */
Julia Reynoldse4a47dd2019-06-07 13:40:59 -0400541 public void notifyAsPackage(@NonNull String targetPackage, @Nullable String tag, int id,
Fabian Kozynski867550e2019-02-28 12:59:57 -0500542 @NonNull Notification notification) {
Julia Reynoldsa7ba45a2018-08-29 09:07:52 -0400543 INotificationManager service = getService();
544 String sender = mContext.getPackageName();
545
546 try {
547 if (localLOGV) Log.v(TAG, sender + ": notify(" + id + ", " + notification + ")");
548 service.enqueueNotificationWithTag(targetPackage, sender, tag, id,
549 fixNotification(notification), mContext.getUser().getIdentifier());
550 } catch (RemoteException e) {
551 throw e.rethrowFromSystemServer();
552 }
553 }
554
555 /**
Dianne Hackborn41203752012-08-31 14:05:51 -0700556 * @hide
557 */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100558 @UnsupportedAppUsage
Dianne Hackborn41203752012-08-31 14:05:51 -0700559 public void notifyAsUser(String tag, int id, Notification notification, UserHandle user)
560 {
Dianne Hackborn41203752012-08-31 14:05:51 -0700561 INotificationManager service = getService();
562 String pkg = mContext.getPackageName();
Julia Reynoldsa7ba45a2018-08-29 09:07:52 -0400563
564 try {
565 if (localLOGV) Log.v(TAG, pkg + ": notify(" + id + ", " + notification + ")");
566 service.enqueueNotificationWithTag(pkg, mContext.getOpPackageName(), tag, id,
567 fixNotification(notification), user.getIdentifier());
568 } catch (RemoteException e) {
569 throw e.rethrowFromSystemServer();
570 }
571 }
572
573 private Notification fixNotification(Notification notification) {
574 String pkg = mContext.getPackageName();
Julia Reynoldsda303542015-11-23 14:00:20 -0500575 // Fix the notification as best we can.
576 Notification.addFieldsFromContext(mContext, notification);
Julia Reynoldse0d711f2017-09-01 08:50:47 -0400577
Jeff Sharkey65c4a2b2012-09-25 17:22:27 -0700578 if (notification.sound != null) {
579 notification.sound = notification.sound.getCanonicalUri();
Jeff Sharkeya14acd22013-04-02 18:27:45 -0700580 if (StrictMode.vmFileUriExposureEnabled()) {
Jeff Sharkeyac3be9a2016-02-01 10:39:30 -0700581 notification.sound.checkFileUriExposed("Notification.sound");
Jeff Sharkeya14acd22013-04-02 18:27:45 -0700582 }
Julia Reynoldse0d711f2017-09-01 08:50:47 -0400583
Jeff Sharkey65c4a2b2012-09-25 17:22:27 -0700584 }
Dan Sandlerd63f9322015-05-06 15:18:49 -0400585 fixLegacySmallIcon(notification, pkg);
Julia Reynoldsd9228f12015-10-20 10:37:27 -0400586 if (mContext.getApplicationInfo().targetSdkVersion > Build.VERSION_CODES.LOLLIPOP_MR1) {
587 if (notification.getSmallIcon() == null) {
588 throw new IllegalArgumentException("Invalid notification (no valid small icon): "
589 + notification);
590 }
591 }
Julia Reynoldsa7ba45a2018-08-29 09:07:52 -0400592
Selim Cinekd0426622017-07-11 13:19:59 +0200593 notification.reduceImageSizes(mContext);
Julia Reynoldse0d711f2017-09-01 08:50:47 -0400594
Julia Reynolds8a3b4592017-06-26 17:15:14 -0400595 ActivityManager am = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
596 boolean isLowRam = am.isLowRamDevice();
Julia Reynoldsa7ba45a2018-08-29 09:07:52 -0400597 return Builder.maybeCloneStrippedForDelivery(notification, isLowRam, mContext);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800598 }
599
Dan Sandlerd63f9322015-05-06 15:18:49 -0400600 private void fixLegacySmallIcon(Notification n, String pkg) {
601 if (n.getSmallIcon() == null && n.icon != 0) {
602 n.setSmallIcon(Icon.createWithResource(pkg, n.icon));
603 }
604 }
605
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800606 /**
Julia Reynoldse4a47dd2019-06-07 13:40:59 -0400607 * Cancels a previously posted notification.
608 *
609 * <p>If the notification does not currently represent a
610 * {@link Service#startForeground(int, Notification) foreground service}, it will be
611 * removed from the UI and live
612 * {@link android.service.notification.NotificationListenerService notification listeners}
613 * will be informed so they can remove the notification from their UIs.</p>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800614 */
615 public void cancel(int id)
616 {
Fred Quintana6ecaff12009-09-25 14:23:13 -0700617 cancel(null, id);
618 }
619
620 /**
Julia Reynoldse4a47dd2019-06-07 13:40:59 -0400621 * Cancels a previously posted notification.
622 *
623 * <p>If the notification does not currently represent a
624 * {@link Service#startForeground(int, Notification) foreground service}, it will be
625 * removed from the UI and live
626 * {@link android.service.notification.NotificationListenerService notification listeners}
627 * will be informed so they can remove the notification from their UIs.</p>
Fred Quintana6ecaff12009-09-25 14:23:13 -0700628 */
Julia Reynoldse4a47dd2019-06-07 13:40:59 -0400629 public void cancel(@Nullable String tag, int id)
Fred Quintana6ecaff12009-09-25 14:23:13 -0700630 {
Jeff Sharkeyad357d12018-02-02 13:25:31 -0700631 cancelAsUser(tag, id, mContext.getUser());
Dianne Hackborn41203752012-08-31 14:05:51 -0700632 }
633
634 /**
Julia Reynoldse4a47dd2019-06-07 13:40:59 -0400635 * Cancels a previously posted notification.
636 *
637 * <p>If the notification does not currently represent a
638 * {@link Service#startForeground(int, Notification) foreground service}, it will be
639 * removed from the UI and live
640 * {@link android.service.notification.NotificationListenerService notification listeners}
641 * will be informed so they can remove the notification from their UIs.</p>
642 *
643 * <p>This method may be used by {@link #getNotificationDelegate() a notification delegate} to
644 * cancel notifications that they have posted via {@link #notifyAsPackage(String, String, int,
645 * Notification)}.</p>
646 *
647 * @param targetPackage The package to cancel the notification as. If this package is not your
648 * package, you can only cancel notifications you posted with
649 * {@link #notifyAsPackage(String, String, int, Notification).
650 * @param tag A string identifier for this notification. May be {@code null}.
651 * @param id An identifier for this notification.
652 */
653 public void cancelAsPackage(@NonNull String targetPackage, @Nullable String tag, int id) {
654 INotificationManager service = getService();
655 try {
656 service.cancelNotificationWithTag(targetPackage, mContext.getOpPackageName(),
657 tag, id, mContext.getUser().getIdentifier());
658 } catch (RemoteException e) {
659 throw e.rethrowFromSystemServer();
660 }
661 }
662
663 /**
Dianne Hackborn41203752012-08-31 14:05:51 -0700664 * @hide
665 */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100666 @UnsupportedAppUsage
Dianne Hackborn41203752012-08-31 14:05:51 -0700667 public void cancelAsUser(String tag, int id, UserHandle user)
668 {
669 INotificationManager service = getService();
670 String pkg = mContext.getPackageName();
671 if (localLOGV) Log.v(TAG, pkg + ": cancel(" + id + ")");
672 try {
Julia Reynoldse4a47dd2019-06-07 13:40:59 -0400673 service.cancelNotificationWithTag(
674 pkg, mContext.getOpPackageName(), tag, id, user.getIdentifier());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800675 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -0700676 throw e.rethrowFromSystemServer();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800677 }
678 }
679
680 /**
681 * Cancel all previously shown notifications. See {@link #cancel} for the
682 * detailed behavior.
683 */
684 public void cancelAll()
685 {
686 INotificationManager service = getService();
687 String pkg = mContext.getPackageName();
688 if (localLOGV) Log.v(TAG, pkg + ": cancelAll()");
689 try {
Jeff Sharkeyad357d12018-02-02 13:25:31 -0700690 service.cancelAllNotifications(pkg, mContext.getUserId());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800691 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -0700692 throw e.rethrowFromSystemServer();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800693 }
694 }
695
John Spurlockb4782522014-08-22 14:54:46 -0400696 /**
Julia Reynoldsa7ba45a2018-08-29 09:07:52 -0400697 * Allows a package to post notifications on your behalf using
698 * {@link #notifyAsPackage(String, String, int, Notification)}.
699 *
700 * This can be used to allow persistent processes to post notifications based on messages
701 * received on your behalf from the cloud, without your process having to wake up.
702 *
703 * You can check if you have an allowed delegate with {@link #getNotificationDelegate()} and
Julia Reynoldscbc45e72019-03-07 12:31:52 -0500704 * revoke your delegate by passing null to this method.
Julia Reynoldsa7ba45a2018-08-29 09:07:52 -0400705 *
706 * @param delegate Package name of the app which can send notifications on your behalf.
707 */
Julia Reynoldscbc45e72019-03-07 12:31:52 -0500708 public void setNotificationDelegate(@Nullable String delegate) {
Julia Reynoldsa7ba45a2018-08-29 09:07:52 -0400709 INotificationManager service = getService();
710 String pkg = mContext.getPackageName();
711 if (localLOGV) Log.v(TAG, pkg + ": cancelAll()");
712 try {
713 service.setNotificationDelegate(pkg, delegate);
714 } catch (RemoteException e) {
715 throw e.rethrowFromSystemServer();
716 }
717 }
718
719 /**
Julia Reynoldsa7ba45a2018-08-29 09:07:52 -0400720 * Returns the {@link #setNotificationDelegate(String) delegate} that can post notifications on
721 * your behalf, if there currently is one.
722 */
723 public @Nullable String getNotificationDelegate() {
724 INotificationManager service = getService();
725 String pkg = mContext.getPackageName();
726 try {
727 return service.getNotificationDelegate(pkg);
728 } catch (RemoteException e) {
729 throw e.rethrowFromSystemServer();
730 }
731 }
732
733 /**
734 * Returns whether you are allowed to post notifications on behalf of a given package, with
735 * {@link #notifyAsPackage(String, String, int, Notification)}.
736 *
737 * See {@link #setNotificationDelegate(String)}.
738 */
Fabian Kozynski867550e2019-02-28 12:59:57 -0500739 public boolean canNotifyAsPackage(@NonNull String pkg) {
Julia Reynoldsa7ba45a2018-08-29 09:07:52 -0400740 INotificationManager service = getService();
741 try {
Julia Reynolds7a6d07a2019-03-18 11:31:56 -0400742 return service.canNotifyAsPackage(mContext.getPackageName(), pkg, mContext.getUserId());
Julia Reynoldsa7ba45a2018-08-29 09:07:52 -0400743 } catch (RemoteException e) {
744 throw e.rethrowFromSystemServer();
745 }
746 }
747
748 /**
Julia Reynolds59e152e2017-01-25 17:42:53 -0500749 * Creates a group container for {@link NotificationChannel} objects.
750 *
Julia Reynolds1d97e6a2017-03-13 15:05:40 -0400751 * This can be used to rename an existing group.
Julia Reynolds59e152e2017-01-25 17:42:53 -0500752 * <p>
753 * Group information is only used for presentation, not for behavior. Groups are optional
754 * for channels, and you can have a mix of channels that belong to groups and channels
755 * that do not.
756 * </p>
757 * <p>
758 * For example, if your application supports multiple accounts, and those accounts will
759 * have similar channels, you can create a group for each account with account specific
760 * labels instead of appending account information to each channel's label.
761 * </p>
762 *
763 * @param group The group to create
764 */
765 public void createNotificationChannelGroup(@NonNull NotificationChannelGroup group) {
766 createNotificationChannelGroups(Arrays.asList(group));
767 }
768
769 /**
770 * Creates multiple notification channel groups.
771 *
772 * @param groups The list of groups to create
773 */
774 public void createNotificationChannelGroups(@NonNull List<NotificationChannelGroup> groups) {
775 INotificationManager service = getService();
776 try {
777 service.createNotificationChannelGroups(mContext.getPackageName(),
778 new ParceledListSlice(groups));
779 } catch (RemoteException e) {
780 throw e.rethrowFromSystemServer();
781 }
782 }
783
784 /**
Geoffrey Pitsch03533712017-01-05 10:30:07 -0500785 * Creates a notification channel that notifications can be posted to.
786 *
Julia Reynolds2c891c92017-03-17 14:23:47 -0400787 * This can also be used to restore a deleted channel and to update an existing channel's
Julia Reynolds005c8b92017-08-24 10:35:53 -0400788 * name, description, group, and/or importance.
Julia Reynolds0ffc13b2017-04-27 13:54:36 -0400789 *
790 * <p>The name and description should only be changed if the locale changes
Julia Reynolds2c891c92017-03-17 14:23:47 -0400791 * or in response to the user renaming this channel. For example, if a user has a channel
792 * named 'John Doe' that represents messages from a 'John Doe', and 'John Doe' changes his name
793 * to 'John Smith,' the channel can be renamed to match.
Geoffrey Pitsch07532c32017-07-18 11:44:06 -0400794 *
795 * <p>The importance of an existing channel will only be changed if the new importance is lower
796 * than the current value and the user has not altered any settings on this channel.
797 *
Julia Reynolds005c8b92017-08-24 10:35:53 -0400798 * <p>The group an existing channel will only be changed if the channel does not already
799 * belong to a group.
800 *
Julia Reynolds2c891c92017-03-17 14:23:47 -0400801 * All other fields are ignored for channels that already exist.
Julia Reynolds59e152e2017-01-25 17:42:53 -0500802 *
Geoffrey Pitsch03533712017-01-05 10:30:07 -0500803 * @param channel the channel to create. Note that the created channel may differ from this
Julia Reynoldse8665332017-03-13 13:00:41 -0400804 * value. If the provided channel is malformed, a RemoteException will be
Julia Reynolds1d97e6a2017-03-13 15:05:40 -0400805 * thrown.
Julia Reynoldsb5e44b72016-08-16 15:00:25 -0400806 */
Geoffrey Pitsch03533712017-01-05 10:30:07 -0500807 public void createNotificationChannel(@NonNull NotificationChannel channel) {
808 createNotificationChannels(Arrays.asList(channel));
Geoffrey Pitsche75a66e2016-11-22 11:12:11 -0500809 }
810
811 /**
Julia Reynolds1d97e6a2017-03-13 15:05:40 -0400812 * Creates multiple notification channels that different notifications can be posted to. See
813 * {@link #createNotificationChannel(NotificationChannel)}.
Geoffrey Pitsche75a66e2016-11-22 11:12:11 -0500814 *
Julia Reynolds1d97e6a2017-03-13 15:05:40 -0400815 * @param channels the list of channels to attempt to create.
Geoffrey Pitsche75a66e2016-11-22 11:12:11 -0500816 */
Geoffrey Pitsch03533712017-01-05 10:30:07 -0500817 public void createNotificationChannels(@NonNull List<NotificationChannel> channels) {
Julia Reynoldsb5e44b72016-08-16 15:00:25 -0400818 INotificationManager service = getService();
819 try {
Geoffrey Pitsch03533712017-01-05 10:30:07 -0500820 service.createNotificationChannels(mContext.getPackageName(),
821 new ParceledListSlice(channels));
Julia Reynoldsb5e44b72016-08-16 15:00:25 -0400822 } catch (RemoteException e) {
823 throw e.rethrowFromSystemServer();
824 }
825 }
826
827 /**
828 * Returns the notification channel settings for a given channel id.
Julia Reynolds0ffc13b2017-04-27 13:54:36 -0400829 *
Julia Reynoldsb4a9e9c2019-03-20 15:46:08 -0400830 * <p>The channel must belong to your package, or to a package you are an approved notification
831 * delegate for (see {@link #canNotifyAsPackage(String)}), or it will not be returned. To query
832 * a channel as a notification delegate, call this method from a context created for that
833 * package (see {@link Context#createPackageContext(String, int)}).</p>
Julia Reynoldsb5e44b72016-08-16 15:00:25 -0400834 */
835 public NotificationChannel getNotificationChannel(String channelId) {
836 INotificationManager service = getService();
837 try {
Julia Reynoldsb4a9e9c2019-03-20 15:46:08 -0400838 return service.getNotificationChannel(mContext.getOpPackageName(),
839 mContext.getUserId(), mContext.getPackageName(), channelId);
Julia Reynoldsb5e44b72016-08-16 15:00:25 -0400840 } catch (RemoteException e) {
841 throw e.rethrowFromSystemServer();
842 }
843 }
844
845 /**
Julia Reynolds0ffc13b2017-04-27 13:54:36 -0400846 * Returns all notification channels belonging to the calling package.
Julia Reynoldsb4a9e9c2019-03-20 15:46:08 -0400847 *
848 * <p>Approved notification delegates (see {@link #canNotifyAsPackage(String)}) can query
849 * notification channels belonging to packages they are the delegate for. To do so, call this
850 * method from a context created for that package (see
851 * {@link Context#createPackageContext(String, int)}).</p>
Julia Reynoldsb5e44b72016-08-16 15:00:25 -0400852 */
853 public List<NotificationChannel> getNotificationChannels() {
854 INotificationManager service = getService();
855 try {
Julia Reynoldsb4a9e9c2019-03-20 15:46:08 -0400856 return service.getNotificationChannels(mContext.getOpPackageName(),
857 mContext.getPackageName(), mContext.getUserId()).getList();
Julia Reynoldsb5e44b72016-08-16 15:00:25 -0400858 } catch (RemoteException e) {
859 throw e.rethrowFromSystemServer();
860 }
861 }
862
863 /**
Julia Reynoldsb5e44b72016-08-16 15:00:25 -0400864 * Deletes the given notification channel.
Julia Reynolds0ffc13b2017-04-27 13:54:36 -0400865 *
866 * <p>If you {@link #createNotificationChannel(NotificationChannel) create} a new channel with
867 * this same id, the deleted channel will be un-deleted with all of the same settings it
868 * had before it was deleted.
Julia Reynoldsb5e44b72016-08-16 15:00:25 -0400869 */
870 public void deleteNotificationChannel(String channelId) {
871 INotificationManager service = getService();
872 try {
873 service.deleteNotificationChannel(mContext.getPackageName(), channelId);
874 } catch (RemoteException e) {
875 throw e.rethrowFromSystemServer();
876 }
877 }
878
879 /**
Julia Reynolds3eb3ffd2017-11-16 10:11:32 -0500880 * Returns the notification channel group settings for a given channel group id.
881 *
882 * The channel group must belong to your package, or null will be returned.
883 */
884 public NotificationChannelGroup getNotificationChannelGroup(String channelGroupId) {
885 INotificationManager service = getService();
886 try {
887 return service.getNotificationChannelGroup(mContext.getPackageName(), channelGroupId);
888 } catch (RemoteException e) {
889 throw e.rethrowFromSystemServer();
890 }
891 }
892
893 /**
Julia Reynolds9bfba592017-03-15 14:03:55 -0400894 * Returns all notification channel groups belonging to the calling app.
895 */
896 public List<NotificationChannelGroup> getNotificationChannelGroups() {
897 INotificationManager service = getService();
898 try {
Beverlyc629ee42018-10-02 16:14:07 -0400899 final ParceledListSlice<NotificationChannelGroup> parceledList =
900 service.getNotificationChannelGroups(mContext.getPackageName());
901 if (parceledList != null) {
902 return parceledList.getList();
903 }
Julia Reynolds9bfba592017-03-15 14:03:55 -0400904 } catch (RemoteException e) {
905 throw e.rethrowFromSystemServer();
906 }
Beverlyc629ee42018-10-02 16:14:07 -0400907 return new ArrayList<>();
Julia Reynolds9bfba592017-03-15 14:03:55 -0400908 }
909
910 /**
Julia Reynolds0ffc13b2017-04-27 13:54:36 -0400911 * Deletes the given notification channel group, and all notification channels that
912 * belong to it.
Julia Reynolds9bfba592017-03-15 14:03:55 -0400913 */
914 public void deleteNotificationChannelGroup(String groupId) {
915 INotificationManager service = getService();
916 try {
917 service.deleteNotificationChannelGroup(mContext.getPackageName(), groupId);
918 } catch (RemoteException e) {
919 throw e.rethrowFromSystemServer();
920 }
921 }
922
923 /**
John Spurlockb4782522014-08-22 14:54:46 -0400924 * @hide
925 */
Julia Reynoldsb6c1f992016-11-22 09:26:46 -0500926 @TestApi
John Spurlockb4782522014-08-22 14:54:46 -0400927 public ComponentName getEffectsSuppressor() {
928 INotificationManager service = getService();
929 try {
930 return service.getEffectsSuppressor();
931 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -0700932 throw e.rethrowFromSystemServer();
John Spurlockb4782522014-08-22 14:54:46 -0400933 }
934 }
935
John Spurlock2b122f42014-08-27 16:29:47 -0400936 /**
937 * @hide
938 */
Julia Reynolds87621942019-01-29 16:19:36 -0500939 @TestApi
John Spurlock2b122f42014-08-27 16:29:47 -0400940 public boolean matchesCallFilter(Bundle extras) {
941 INotificationManager service = getService();
942 try {
943 return service.matchesCallFilter(extras);
944 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -0700945 throw e.rethrowFromSystemServer();
John Spurlock2b122f42014-08-27 16:29:47 -0400946 }
947 }
948
John Spurlock530052a2014-11-30 16:26:19 -0500949 /**
950 * @hide
951 */
952 public boolean isSystemConditionProviderEnabled(String path) {
953 INotificationManager service = getService();
954 try {
955 return service.isSystemConditionProviderEnabled(path);
956 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -0700957 throw e.rethrowFromSystemServer();
John Spurlock530052a2014-11-30 16:26:19 -0500958 }
959 }
960
John Spurlockcdb57ae2015-02-11 19:04:11 -0500961 /**
962 * @hide
963 */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100964 @UnsupportedAppUsage
John Spurlockb2278d62015-04-07 12:47:12 -0400965 public void setZenMode(int mode, Uri conditionId, String reason) {
John Spurlockcdb57ae2015-02-11 19:04:11 -0500966 INotificationManager service = getService();
967 try {
John Spurlockb2278d62015-04-07 12:47:12 -0400968 service.setZenMode(mode, conditionId, reason);
John Spurlockcdb57ae2015-02-11 19:04:11 -0500969 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -0700970 throw e.rethrowFromSystemServer();
John Spurlockcdb57ae2015-02-11 19:04:11 -0500971 }
972 }
973
974 /**
975 * @hide
976 */
John Spurlockb2278d62015-04-07 12:47:12 -0400977 public int getZenMode() {
John Spurlockcdb57ae2015-02-11 19:04:11 -0500978 INotificationManager service = getService();
979 try {
John Spurlockb2278d62015-04-07 12:47:12 -0400980 return service.getZenMode();
John Spurlockcdb57ae2015-02-11 19:04:11 -0500981 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -0700982 throw e.rethrowFromSystemServer();
John Spurlockcdb57ae2015-02-11 19:04:11 -0500983 }
984 }
985
986 /**
987 * @hide
988 */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100989 @UnsupportedAppUsage
John Spurlockb2278d62015-04-07 12:47:12 -0400990 public ZenModeConfig getZenModeConfig() {
John Spurlockcdb57ae2015-02-11 19:04:11 -0500991 INotificationManager service = getService();
992 try {
John Spurlockb2278d62015-04-07 12:47:12 -0400993 return service.getZenModeConfig();
John Spurlockcdb57ae2015-02-11 19:04:11 -0500994 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -0700995 throw e.rethrowFromSystemServer();
John Spurlockcdb57ae2015-02-11 19:04:11 -0500996 }
John Spurlockcdb57ae2015-02-11 19:04:11 -0500997 }
998
John Spurlock1fc476d2015-04-14 16:05:20 -0400999 /**
Beverlyd994e2e2019-10-11 14:36:37 -04001000 * <p>
1001 * Gets the currently applied notification policy. If {@link #getCurrentInterruptionFilter}
1002 * is equal to {@link #INTERRUPTION_FILTER_ALL}, then the consolidated notification policy
1003 * will match the default notification policy returned by {@link #getNotificationPolicy}.
1004 * </p>
Julia Reynolds43b70cd2016-01-14 15:05:34 -05001005 */
Beverlyd994e2e2019-10-11 14:36:37 -04001006 @Nullable
Beverlyff2df9b2018-10-10 16:54:10 -04001007 public NotificationManager.Policy getConsolidatedNotificationPolicy() {
1008 INotificationManager service = getService();
1009 try {
1010 return service.getConsolidatedNotificationPolicy();
1011 } catch (RemoteException e) {
1012 throw e.rethrowFromSystemServer();
1013 }
1014 }
1015
1016 /**
1017 * @hide
1018 */
Julia Reynolds43b70cd2016-01-14 15:05:34 -05001019 public int getRuleInstanceCount(ComponentName owner) {
1020 INotificationManager service = getService();
1021 try {
1022 return service.getRuleInstanceCount(owner);
1023 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07001024 throw e.rethrowFromSystemServer();
Julia Reynolds43b70cd2016-01-14 15:05:34 -05001025 }
Julia Reynolds43b70cd2016-01-14 15:05:34 -05001026 }
1027
1028 /**
Julia Reynoldsa47a27f2015-08-24 08:31:47 -04001029 * Returns AutomaticZenRules owned by the caller.
1030 *
1031 * <p>
Jay Aliomer8e3aac52019-10-16 13:48:39 -04001032 * Throws a SecurityException if policy access is not granted to this package.
Julia Reynoldsa47a27f2015-08-24 08:31:47 -04001033 * See {@link #isNotificationPolicyAccessGranted}.
1034 */
Julia Reynolds361e82d32016-02-26 18:19:49 -05001035 public Map<String, AutomaticZenRule> getAutomaticZenRules() {
Julia Reynoldsa47a27f2015-08-24 08:31:47 -04001036 INotificationManager service = getService();
1037 try {
Julia Reynolds361e82d32016-02-26 18:19:49 -05001038 List<ZenModeConfig.ZenRule> rules = service.getZenRules();
1039 Map<String, AutomaticZenRule> ruleMap = new HashMap<>();
1040 for (ZenModeConfig.ZenRule rule : rules) {
Julia Reynolds68062072018-08-06 15:38:21 -04001041 ruleMap.put(rule.id, new AutomaticZenRule(rule.name, rule.component,
1042 rule.configurationActivity, rule.conditionId, rule.zenPolicy,
1043 zenModeToInterruptionFilter(rule.zenMode), rule.enabled,
1044 rule.creationTime));
Julia Reynolds361e82d32016-02-26 18:19:49 -05001045 }
1046 return ruleMap;
Julia Reynoldsa47a27f2015-08-24 08:31:47 -04001047 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07001048 throw e.rethrowFromSystemServer();
Julia Reynoldsa47a27f2015-08-24 08:31:47 -04001049 }
Julia Reynoldsa47a27f2015-08-24 08:31:47 -04001050 }
1051
1052 /**
Julia Reynolds4fe98d62015-10-06 16:23:41 -04001053 * Returns the AutomaticZenRule with the given id, if it exists and the caller has access.
Julia Reynoldsa47a27f2015-08-24 08:31:47 -04001054 *
1055 * <p>
Jay Aliomer8e3aac52019-10-16 13:48:39 -04001056 * Throws a SecurityException if policy access is not granted to this package.
Julia Reynoldsa47a27f2015-08-24 08:31:47 -04001057 * See {@link #isNotificationPolicyAccessGranted}.
1058 *
1059 * <p>
Julia Reynolds4fe98d62015-10-06 16:23:41 -04001060 * 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 -04001061 * doesn't own the matching rule. See {@link AutomaticZenRule#getOwner}.
1062 */
Julia Reynolds4fe98d62015-10-06 16:23:41 -04001063 public AutomaticZenRule getAutomaticZenRule(String id) {
Julia Reynoldsa47a27f2015-08-24 08:31:47 -04001064 INotificationManager service = getService();
1065 try {
Julia Reynolds4fe98d62015-10-06 16:23:41 -04001066 return service.getAutomaticZenRule(id);
Julia Reynoldsa47a27f2015-08-24 08:31:47 -04001067 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07001068 throw e.rethrowFromSystemServer();
Julia Reynoldsa47a27f2015-08-24 08:31:47 -04001069 }
Julia Reynoldsa47a27f2015-08-24 08:31:47 -04001070 }
1071
1072 /**
Julia Reynolds4fe98d62015-10-06 16:23:41 -04001073 * Creates the given zen rule.
Julia Reynoldsa47a27f2015-08-24 08:31:47 -04001074 *
1075 * <p>
Jay Aliomer8e3aac52019-10-16 13:48:39 -04001076 * Throws a SecurityException if policy access is not granted to this package.
Julia Reynoldsa47a27f2015-08-24 08:31:47 -04001077 * See {@link #isNotificationPolicyAccessGranted}.
1078 *
Julia Reynolds4fe98d62015-10-06 16:23:41 -04001079 * @param automaticZenRule the rule to create.
Julia Reynolds361e82d32016-02-26 18:19:49 -05001080 * @return The id of the newly created rule; null if the rule could not be created.
Julia Reynoldsa47a27f2015-08-24 08:31:47 -04001081 */
Julia Reynolds361e82d32016-02-26 18:19:49 -05001082 public String addAutomaticZenRule(AutomaticZenRule automaticZenRule) {
Julia Reynoldsa47a27f2015-08-24 08:31:47 -04001083 INotificationManager service = getService();
1084 try {
Julia Reynolds4fe98d62015-10-06 16:23:41 -04001085 return service.addAutomaticZenRule(automaticZenRule);
Julia Reynoldsa47a27f2015-08-24 08:31:47 -04001086 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07001087 throw e.rethrowFromSystemServer();
Julia Reynoldsa47a27f2015-08-24 08:31:47 -04001088 }
Julia Reynoldsa47a27f2015-08-24 08:31:47 -04001089 }
1090
1091 /**
Julia Reynolds4fe98d62015-10-06 16:23:41 -04001092 * Updates the given zen rule.
Julia Reynoldsa47a27f2015-08-24 08:31:47 -04001093 *
1094 * <p>
Jay Aliomer8e3aac52019-10-16 13:48:39 -04001095 * Throws a SecurityException if policy access is not granted to this package.
Julia Reynoldsa47a27f2015-08-24 08:31:47 -04001096 * See {@link #isNotificationPolicyAccessGranted}.
1097 *
1098 * <p>
1099 * Callers can only update rules that they own. See {@link AutomaticZenRule#getOwner}.
Julia Reynolds361e82d32016-02-26 18:19:49 -05001100 * @param id The id of the rule to update
Geoffrey Pitsche75a66e2016-11-22 11:12:11 -05001101 * @param automaticZenRule the rule to update.
Julia Reynoldsa47a27f2015-08-24 08:31:47 -04001102 * @return Whether the rule was successfully updated.
1103 */
Julia Reynolds361e82d32016-02-26 18:19:49 -05001104 public boolean updateAutomaticZenRule(String id, AutomaticZenRule automaticZenRule) {
Julia Reynoldsa47a27f2015-08-24 08:31:47 -04001105 INotificationManager service = getService();
1106 try {
Julia Reynolds361e82d32016-02-26 18:19:49 -05001107 return service.updateAutomaticZenRule(id, automaticZenRule);
Julia Reynoldsa47a27f2015-08-24 08:31:47 -04001108 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07001109 throw e.rethrowFromSystemServer();
Julia Reynoldsa47a27f2015-08-24 08:31:47 -04001110 }
Julia Reynoldsa47a27f2015-08-24 08:31:47 -04001111 }
1112
1113 /**
Julia Reynolds68062072018-08-06 15:38:21 -04001114 * Informs the notification manager that the state of an {@link AutomaticZenRule} has changed.
1115 * Use this method to put the system into Do Not Disturb mode or request that it exits Do Not
1116 * Disturb mode. The calling app must own the provided {@link android.app.AutomaticZenRule}.
1117 * <p>
1118 * This method can be used in conjunction with or as a replacement to
1119 * {@link android.service.notification.ConditionProviderService#notifyCondition(Condition)}.
1120 * </p>
1121 * @param id The id of the rule whose state should change
1122 * @param condition The new state of this rule
1123 */
Fabian Kozynski867550e2019-02-28 12:59:57 -05001124 public void setAutomaticZenRuleState(@NonNull String id, @NonNull Condition condition) {
Julia Reynolds68062072018-08-06 15:38:21 -04001125 INotificationManager service = getService();
1126 try {
1127 service.setAutomaticZenRuleState(id, condition);
1128 } catch (RemoteException e) {
1129 throw e.rethrowFromSystemServer();
1130 }
1131 }
1132
1133 /**
Julia Reynolds4fe98d62015-10-06 16:23:41 -04001134 * Deletes the automatic zen rule with the given id.
Julia Reynoldsa47a27f2015-08-24 08:31:47 -04001135 *
1136 * <p>
Jay Aliomer8e3aac52019-10-16 13:48:39 -04001137 * Throws a SecurityException if policy access is not granted to this package.
Julia Reynoldsa47a27f2015-08-24 08:31:47 -04001138 * See {@link #isNotificationPolicyAccessGranted}.
1139 *
1140 * <p>
1141 * Callers can only delete rules that they own. See {@link AutomaticZenRule#getOwner}.
Julia Reynolds4fe98d62015-10-06 16:23:41 -04001142 * @param id the id of the rule to delete.
Julia Reynoldsa47a27f2015-08-24 08:31:47 -04001143 * @return Whether the rule was successfully deleted.
1144 */
Julia Reynolds4fe98d62015-10-06 16:23:41 -04001145 public boolean removeAutomaticZenRule(String id) {
Julia Reynoldsa47a27f2015-08-24 08:31:47 -04001146 INotificationManager service = getService();
1147 try {
Julia Reynolds4fe98d62015-10-06 16:23:41 -04001148 return service.removeAutomaticZenRule(id);
Julia Reynoldsa47a27f2015-08-24 08:31:47 -04001149 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07001150 throw e.rethrowFromSystemServer();
Julia Reynoldsa47a27f2015-08-24 08:31:47 -04001151 }
Julia Reynoldsa47a27f2015-08-24 08:31:47 -04001152 }
1153
1154 /**
Julia Reynoldsc8e54e82015-11-30 16:43:05 -05001155 * Deletes all automatic zen rules owned by the given package.
1156 *
1157 * @hide
1158 */
1159 public boolean removeAutomaticZenRules(String packageName) {
1160 INotificationManager service = getService();
1161 try {
1162 return service.removeAutomaticZenRules(packageName);
1163 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07001164 throw e.rethrowFromSystemServer();
Julia Reynoldsc8e54e82015-11-30 16:43:05 -05001165 }
Julia Reynoldsc8e54e82015-11-30 16:43:05 -05001166 }
1167
Julia Reynolds0edb50c2016-02-26 14:08:25 -05001168 /**
Jeff Sharkey6503bd82017-04-19 23:24:18 -06001169 * Returns the user specified importance for notifications from the calling
1170 * package.
Julia Reynolds0edb50c2016-02-26 14:08:25 -05001171 */
Chris Wren5ab5c742016-05-10 15:32:23 -04001172 public @Importance int getImportance() {
Julia Reynolds81afbcd2016-02-09 14:54:08 -05001173 INotificationManager service = getService();
1174 try {
Julia Reynoldsef37f282016-02-12 09:11:27 -05001175 return service.getPackageImportance(mContext.getPackageName());
Julia Reynolds81afbcd2016-02-09 14:54:08 -05001176 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07001177 throw e.rethrowFromSystemServer();
Julia Reynolds81afbcd2016-02-09 14:54:08 -05001178 }
Julia Reynolds81afbcd2016-02-09 14:54:08 -05001179 }
1180
Julia Reynolds0edb50c2016-02-26 14:08:25 -05001181 /**
1182 * Returns whether notifications from the calling package are blocked.
1183 */
Julia Reynolds81afbcd2016-02-09 14:54:08 -05001184 public boolean areNotificationsEnabled() {
1185 INotificationManager service = getService();
1186 try {
1187 return service.areNotificationsEnabled(mContext.getPackageName());
1188 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07001189 throw e.rethrowFromSystemServer();
Julia Reynolds81afbcd2016-02-09 14:54:08 -05001190 }
Julia Reynolds81afbcd2016-02-09 14:54:08 -05001191 }
1192
Julia Reynolds33ab8a02018-12-17 16:19:52 -05001193
1194 /**
1195 * Sets whether notifications posted by this app can appear outside of the
1196 * notification shade, floating over other apps' content.
1197 *
1198 * <p>This value will be ignored for notifications that are posted to channels that do not
Mady Mellorc39b4ae2019-01-09 17:11:37 -08001199 * allow bubbles ({@link NotificationChannel#canBubble()}.
Julia Reynolds33ab8a02018-12-17 16:19:52 -05001200 *
Mady Mellorc39b4ae2019-01-09 17:11:37 -08001201 * @see Notification#getBubbleMetadata()
Julia Reynolds33ab8a02018-12-17 16:19:52 -05001202 */
Mady Mellorc39b4ae2019-01-09 17:11:37 -08001203 public boolean areBubblesAllowed() {
Julia Reynolds33ab8a02018-12-17 16:19:52 -05001204 INotificationManager service = getService();
1205 try {
Mady Mellorc39b4ae2019-01-09 17:11:37 -08001206 return service.areBubblesAllowed(mContext.getPackageName());
Julia Reynolds33ab8a02018-12-17 16:19:52 -05001207 } catch (RemoteException e) {
1208 throw e.rethrowFromSystemServer();
1209 }
1210 }
1211
Julia Reynoldsc8e54e82015-11-30 16:43:05 -05001212 /**
Julia Reynoldsdeb2d0b2019-06-17 15:34:26 -04001213 * Silences the current notification sound, if ones currently playing.
1214 * <p>
1215 * It is intended to handle use-cases such as silencing a ringing call
1216 * when the user presses the volume button during ringing.
1217 * <p>
1218 * If this method is called prior to when the notification begins playing, the sound will not be
1219 * silenced. As such it is not intended as a means to avoid playing of a sound.
1220 * @hide
1221 */
1222 public void silenceNotificationSound() {
1223 INotificationManager service = getService();
1224 try {
1225 service.silenceNotificationSound();
1226 } catch (RemoteException e) {
1227 throw e.rethrowFromSystemServer();
1228 }
1229 }
1230
1231 /**
Julia Reynoldsb40cd092019-01-25 09:35:02 -05001232 * Returns whether notifications from this package are temporarily hidden. This
1233 * could be done because the package was marked as distracting to the user via
1234 * {@code PackageManager#setDistractingPackageRestrictions(String[], int)} or because the
1235 * package is {@code PackageManager#setPackagesSuspended(String[], boolean, PersistableBundle,
1236 * PersistableBundle, SuspendDialogInfo) suspended}.
1237 */
1238 public boolean areNotificationsPaused() {
1239 INotificationManager service = getService();
1240 try {
1241 return service.isPackagePaused(mContext.getPackageName());
1242 } catch (RemoteException e) {
1243 throw e.rethrowFromSystemServer();
1244 }
1245 }
1246
1247 /**
Beverly312ef3e2017-11-15 11:12:51 -05001248 * Checks the ability to modify notification do not disturb policy for the calling package.
John Spurlock1fc476d2015-04-14 16:05:20 -04001249 *
John Spurlock7c74f782015-06-04 13:01:42 -04001250 * <p>
Beverly312ef3e2017-11-15 11:12:51 -05001251 * Returns true if the calling package can modify notification policy.
John Spurlock7c74f782015-06-04 13:01:42 -04001252 *
1253 * <p>
Julia Reynoldsb852e562017-06-06 16:14:18 -04001254 * Apps can request policy access by sending the user to the activity that matches the system
1255 * intent action {@link android.provider.Settings#ACTION_NOTIFICATION_POLICY_ACCESS_SETTINGS}.
John Spurlock7c74f782015-06-04 13:01:42 -04001256 *
1257 * <p>
1258 * Use {@link #ACTION_NOTIFICATION_POLICY_ACCESS_GRANTED_CHANGED} to listen for
1259 * user grant or denial of this access.
John Spurlock1fc476d2015-04-14 16:05:20 -04001260 */
John Spurlock80774932015-05-07 17:38:50 -04001261 public boolean isNotificationPolicyAccessGranted() {
John Spurlock1fc476d2015-04-14 16:05:20 -04001262 INotificationManager service = getService();
1263 try {
John Spurlock80774932015-05-07 17:38:50 -04001264 return service.isNotificationPolicyAccessGranted(mContext.getOpPackageName());
1265 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07001266 throw e.rethrowFromSystemServer();
John Spurlock80774932015-05-07 17:38:50 -04001267 }
John Spurlock80774932015-05-07 17:38:50 -04001268 }
1269
Julia Reynoldsb852e562017-06-06 16:14:18 -04001270 /**
1271 * Checks whether the user has approved a given
1272 * {@link android.service.notification.NotificationListenerService}.
1273 *
1274 * <p>
1275 * The listener service must belong to the calling app.
1276 *
1277 * <p>
1278 * Apps can request notification listener access by sending the user to the activity that
1279 * matches the system intent action
1280 * {@link android.provider.Settings#ACTION_NOTIFICATION_LISTENER_SETTINGS}.
1281 */
1282 public boolean isNotificationListenerAccessGranted(ComponentName listener) {
1283 INotificationManager service = getService();
1284 try {
1285 return service.isNotificationListenerAccessGranted(listener);
1286 } catch (RemoteException e) {
1287 throw e.rethrowFromSystemServer();
1288 }
1289 }
1290
Fabian Kozynskid9425662019-01-29 13:08:30 -05001291 /**
1292 * Checks whether the user has approved a given
1293 * {@link android.service.notification.NotificationAssistantService}.
1294 *
1295 * <p>
1296 * The assistant service must belong to the calling app.
1297 *
1298 * <p>
1299 * Apps can request notification assistant access by sending the user to the activity that
1300 * matches the system intent action
1301 * TODO: STOPSHIP: Add correct intent
1302 * {@link android.provider.Settings#ACTION_MANAGE_DEFAULT_APPS_SETTINGS}.
Julia Reynoldsd0ceefa2019-03-03 16:10:52 -05001303 * @hide
Fabian Kozynskid9425662019-01-29 13:08:30 -05001304 */
Julia Reynoldsd0ceefa2019-03-03 16:10:52 -05001305 @SystemApi
Julia Reynoldsdc6adc62019-04-08 10:35:40 -04001306 @TestApi
Fabian Kozynski867550e2019-02-28 12:59:57 -05001307 public boolean isNotificationAssistantAccessGranted(@NonNull ComponentName assistant) {
Julia Reynoldsb852e562017-06-06 16:14:18 -04001308 INotificationManager service = getService();
1309 try {
1310 return service.isNotificationAssistantAccessGranted(assistant);
1311 } catch (RemoteException e) {
1312 throw e.rethrowFromSystemServer();
1313 }
1314 }
1315
Julia Reynolds12ad7ca2019-01-28 09:29:16 -05001316 /**
1317 * Returns whether the user wants silent notifications (see {@link #IMPORTANCE_LOW} to appear
1318 * in the status bar.
1319 *
1320 * <p>Only available for {@link #isNotificationListenerAccessGranted(ComponentName) notification
1321 * listeners}.
1322 */
1323 public boolean shouldHideSilentStatusBarIcons() {
1324 INotificationManager service = getService();
1325 try {
1326 return service.shouldHideSilentStatusIcons(mContext.getOpPackageName());
1327 } catch (RemoteException e) {
1328 throw e.rethrowFromSystemServer();
1329 }
1330 }
1331
Julia Reynoldsad6dd352019-03-07 16:46:22 -05001332 /**
1333 * Returns the list of {@link android.service.notification.Adjustment adjustment keys} that can
1334 * be modified by the current {@link android.service.notification.NotificationAssistantService}.
1335 *
1336 * <p>Only callable by the current
1337 * {@link android.service.notification.NotificationAssistantService}.
1338 * See {@link #isNotificationAssistantAccessGranted(ComponentName)}</p>
1339 * @hide
1340 */
1341 @SystemApi
Julia Reynoldsdc6adc62019-04-08 10:35:40 -04001342 @TestApi
Julia Reynolds088c4482019-04-10 12:43:27 -04001343 public @NonNull @Adjustment.Keys List<String> getAllowedAssistantAdjustments() {
Julia Reynoldsad6dd352019-03-07 16:46:22 -05001344 INotificationManager service = getService();
1345 try {
Julia Reynolds088c4482019-04-10 12:43:27 -04001346 return service.getAllowedAssistantAdjustments(mContext.getOpPackageName());
Julia Reynoldsad6dd352019-03-07 16:46:22 -05001347 } catch (RemoteException e) {
1348 throw e.rethrowFromSystemServer();
1349 }
1350 }
1351
Julia Reynoldsdc6adc62019-04-08 10:35:40 -04001352 /**
1353 * @hide
1354 */
1355 @TestApi
Julia Reynolds088c4482019-04-10 12:43:27 -04001356 public void allowAssistantAdjustment(String capability) {
Julia Reynoldsdc6adc62019-04-08 10:35:40 -04001357 INotificationManager service = getService();
1358 try {
Julia Reynolds088c4482019-04-10 12:43:27 -04001359 service.allowAssistantAdjustment(capability);
Julia Reynoldsdc6adc62019-04-08 10:35:40 -04001360 } catch (RemoteException e) {
1361 throw e.rethrowFromSystemServer();
1362 }
1363 }
1364
1365 /**
1366 * @hide
1367 */
1368 @TestApi
Julia Reynolds088c4482019-04-10 12:43:27 -04001369 public void disallowAssistantAdjustment(String capability) {
Julia Reynoldsdc6adc62019-04-08 10:35:40 -04001370 INotificationManager service = getService();
1371 try {
Julia Reynolds088c4482019-04-10 12:43:27 -04001372 service.disallowAssistantAdjustment(capability);
Julia Reynoldsdc6adc62019-04-08 10:35:40 -04001373 } catch (RemoteException e) {
1374 throw e.rethrowFromSystemServer();
1375 }
1376 }
1377
John Spurlock80774932015-05-07 17:38:50 -04001378 /** @hide */
1379 public boolean isNotificationPolicyAccessGrantedForPackage(String pkg) {
1380 INotificationManager service = getService();
1381 try {
1382 return service.isNotificationPolicyAccessGrantedForPackage(pkg);
John Spurlock1fc476d2015-04-14 16:05:20 -04001383 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07001384 throw e.rethrowFromSystemServer();
John Spurlock1fc476d2015-04-14 16:05:20 -04001385 }
John Spurlock1fc476d2015-04-14 16:05:20 -04001386 }
1387
1388 /**
Julia Reynoldsb852e562017-06-06 16:14:18 -04001389 * @hide
1390 */
1391 public List<String> getEnabledNotificationListenerPackages() {
1392 INotificationManager service = getService();
1393 try {
1394 return service.getEnabledNotificationListenerPackages();
1395 } catch (RemoteException e) {
1396 throw e.rethrowFromSystemServer();
1397 }
1398 }
1399
1400 /**
Beverlyff2df9b2018-10-10 16:54:10 -04001401 * Gets the current user-specified default notification policy.
John Spurlock1fc476d2015-04-14 16:05:20 -04001402 *
John Spurlock80774932015-05-07 17:38:50 -04001403 * <p>
John Spurlock1fc476d2015-04-14 16:05:20 -04001404 */
John Spurlock80774932015-05-07 17:38:50 -04001405 public Policy getNotificationPolicy() {
John Spurlock1fc476d2015-04-14 16:05:20 -04001406 INotificationManager service = getService();
1407 try {
John Spurlock80774932015-05-07 17:38:50 -04001408 return service.getNotificationPolicy(mContext.getOpPackageName());
John Spurlock1fc476d2015-04-14 16:05:20 -04001409 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07001410 throw e.rethrowFromSystemServer();
John Spurlock1fc476d2015-04-14 16:05:20 -04001411 }
John Spurlock1fc476d2015-04-14 16:05:20 -04001412 }
1413
1414 /**
1415 * Sets the current notification policy.
1416 *
John Spurlock80774932015-05-07 17:38:50 -04001417 * <p>
John Spurlock7c74f782015-06-04 13:01:42 -04001418 * Only available if policy access is granted to this package.
1419 * See {@link #isNotificationPolicyAccessGranted}.
John Spurlock80774932015-05-07 17:38:50 -04001420 *
John Spurlock1fc476d2015-04-14 16:05:20 -04001421 * @param policy The new desired policy.
1422 */
John Spurlock80774932015-05-07 17:38:50 -04001423 public void setNotificationPolicy(@NonNull Policy policy) {
John Spurlock1fc476d2015-04-14 16:05:20 -04001424 checkRequired("policy", policy);
1425 INotificationManager service = getService();
1426 try {
John Spurlock80774932015-05-07 17:38:50 -04001427 service.setNotificationPolicy(mContext.getOpPackageName(), policy);
John Spurlock1fc476d2015-04-14 16:05:20 -04001428 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07001429 throw e.rethrowFromSystemServer();
John Spurlock1fc476d2015-04-14 16:05:20 -04001430 }
1431 }
1432
John Spurlock80774932015-05-07 17:38:50 -04001433 /** @hide */
1434 public void setNotificationPolicyAccessGranted(String pkg, boolean granted) {
1435 INotificationManager service = getService();
1436 try {
1437 service.setNotificationPolicyAccessGranted(pkg, granted);
1438 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07001439 throw e.rethrowFromSystemServer();
John Spurlock80774932015-05-07 17:38:50 -04001440 }
1441 }
1442
1443 /** @hide */
Julia Reynoldsb852e562017-06-06 16:14:18 -04001444 public void setNotificationListenerAccessGranted(ComponentName listener, boolean granted) {
John Spurlock80774932015-05-07 17:38:50 -04001445 INotificationManager service = getService();
1446 try {
Julia Reynoldsb852e562017-06-06 16:14:18 -04001447 service.setNotificationListenerAccessGranted(listener, granted);
John Spurlock80774932015-05-07 17:38:50 -04001448 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07001449 throw e.rethrowFromSystemServer();
John Spurlock80774932015-05-07 17:38:50 -04001450 }
Julia Reynoldsb852e562017-06-06 16:14:18 -04001451 }
1452
1453 /** @hide */
1454 public void setNotificationListenerAccessGrantedForUser(ComponentName listener, int userId,
1455 boolean granted) {
1456 INotificationManager service = getService();
1457 try {
1458 service.setNotificationListenerAccessGrantedForUser(listener, userId, granted);
1459 } catch (RemoteException e) {
1460 throw e.rethrowFromSystemServer();
1461 }
1462 }
1463
Fabian Kozynskid9425662019-01-29 13:08:30 -05001464 /**
1465 * Grants/revokes Notification Assistant access to {@code assistant} for current user.
Fabian Kozynskicbfbb1d2019-03-15 09:51:39 -04001466 * To grant access for a particular user, obtain this service by using the {@link Context}
1467 * provided by {@link Context#createPackageContextAsUser}
Fabian Kozynskid9425662019-01-29 13:08:30 -05001468 *
1469 * @param assistant Name of component to grant/revoke access or {@code null} to revoke access to
1470 * current assistant
1471 * @param granted Grant/revoke access
1472 * @hide
1473 */
1474 @SystemApi
Julia Reynoldsdc6adc62019-04-08 10:35:40 -04001475 @TestApi
Fabian Kozynski5747d632019-03-11 14:23:23 -04001476 public void setNotificationAssistantAccessGranted(@Nullable ComponentName assistant,
1477 boolean granted) {
Fabian Kozynskid9425662019-01-29 13:08:30 -05001478 INotificationManager service = getService();
1479 try {
1480 service.setNotificationAssistantAccessGranted(assistant, granted);
1481 } catch (RemoteException e) {
1482 throw e.rethrowFromSystemServer();
1483 }
1484 }
1485
Julia Reynoldsb852e562017-06-06 16:14:18 -04001486 /** @hide */
1487 public List<ComponentName> getEnabledNotificationListeners(int userId) {
1488 INotificationManager service = getService();
1489 try {
1490 return service.getEnabledNotificationListeners(userId);
1491 } catch (RemoteException e) {
1492 throw e.rethrowFromSystemServer();
1493 }
John Spurlock80774932015-05-07 17:38:50 -04001494 }
1495
Fabian Kozynskid9425662019-01-29 13:08:30 -05001496 /** @hide */
1497 @SystemApi
Julia Reynoldsdc6adc62019-04-08 10:35:40 -04001498 @TestApi
Fabian Kozynskid9425662019-01-29 13:08:30 -05001499 public @Nullable ComponentName getAllowedNotificationAssistant() {
1500 INotificationManager service = getService();
1501 try {
1502 return service.getAllowedNotificationAssistant();
1503 } catch (RemoteException e) {
1504 throw e.rethrowFromSystemServer();
1505 }
1506 }
1507
1508
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001509 private Context mContext;
John Spurlock1fc476d2015-04-14 16:05:20 -04001510
1511 private static void checkRequired(String name, Object value) {
1512 if (value == null) {
1513 throw new IllegalArgumentException(name + " is required");
1514 }
1515 }
1516
1517 /**
1518 * Notification policy configuration. Represents user-preferences for notification
Julia Reynoldscedacef2016-03-04 08:18:47 -05001519 * filtering.
John Spurlock1fc476d2015-04-14 16:05:20 -04001520 */
1521 public static class Policy implements android.os.Parcelable {
1522 /** Reminder notifications are prioritized. */
1523 public static final int PRIORITY_CATEGORY_REMINDERS = 1 << 0;
1524 /** Event notifications are prioritized. */
1525 public static final int PRIORITY_CATEGORY_EVENTS = 1 << 1;
1526 /** Message notifications are prioritized. */
1527 public static final int PRIORITY_CATEGORY_MESSAGES = 1 << 2;
1528 /** Calls are prioritized. */
1529 public static final int PRIORITY_CATEGORY_CALLS = 1 << 3;
1530 /** Calls from repeat callers are prioritized. */
1531 public static final int PRIORITY_CATEGORY_REPEAT_CALLERS = 1 << 4;
Beverly04216872017-09-28 10:55:32 -04001532 /** Alarms are prioritized */
1533 public static final int PRIORITY_CATEGORY_ALARMS = 1 << 5;
Beverlyd6964762018-02-16 14:07:03 -05001534 /** Media, game, voice navigation are prioritized */
1535 public static final int PRIORITY_CATEGORY_MEDIA = 1 << 6;
1536 /**System (catch-all for non-never suppressible sounds) are prioritized */
1537 public static final int PRIORITY_CATEGORY_SYSTEM = 1 << 7;
John Spurlock1fc476d2015-04-14 16:05:20 -04001538
Beverlyd6964762018-02-16 14:07:03 -05001539 /**
1540 * @hide
1541 */
1542 public static final int[] ALL_PRIORITY_CATEGORIES = {
Beverly04216872017-09-28 10:55:32 -04001543 PRIORITY_CATEGORY_ALARMS,
Beverlyd6964762018-02-16 14:07:03 -05001544 PRIORITY_CATEGORY_MEDIA,
1545 PRIORITY_CATEGORY_SYSTEM,
John Spurlock1fc476d2015-04-14 16:05:20 -04001546 PRIORITY_CATEGORY_REMINDERS,
1547 PRIORITY_CATEGORY_EVENTS,
1548 PRIORITY_CATEGORY_MESSAGES,
1549 PRIORITY_CATEGORY_CALLS,
1550 PRIORITY_CATEGORY_REPEAT_CALLERS,
1551 };
1552
1553 /** Any sender is prioritized. */
1554 public static final int PRIORITY_SENDERS_ANY = 0;
1555 /** Saved contacts are prioritized. */
1556 public static final int PRIORITY_SENDERS_CONTACTS = 1;
1557 /** Only starred contacts are prioritized. */
1558 public static final int PRIORITY_SENDERS_STARRED = 2;
1559
1560 /** Notification categories to prioritize. Bitmask of PRIORITY_CATEGORY_* constants. */
1561 public final int priorityCategories;
1562
John Spurlock80774932015-05-07 17:38:50 -04001563 /** Notification senders to prioritize for calls. One of:
John Spurlock1fc476d2015-04-14 16:05:20 -04001564 * PRIORITY_SENDERS_ANY, PRIORITY_SENDERS_CONTACTS, PRIORITY_SENDERS_STARRED */
John Spurlock80774932015-05-07 17:38:50 -04001565 public final int priorityCallSenders;
John Spurlock1fc476d2015-04-14 16:05:20 -04001566
John Spurlock80774932015-05-07 17:38:50 -04001567 /** Notification senders to prioritize for messages. One of:
1568 * PRIORITY_SENDERS_ANY, PRIORITY_SENDERS_CONTACTS, PRIORITY_SENDERS_STARRED */
1569 public final int priorityMessageSenders;
1570
Julia Reynoldsd5607292016-02-05 15:25:58 -05001571 /**
1572 * @hide
1573 */
Julia Reynoldsf612869ae2015-11-05 16:48:55 -05001574 public static final int SUPPRESSED_EFFECTS_UNSET = -1;
Julia Reynoldsccc6ae62018-03-01 16:24:49 -05001575
Julia Reynoldsd5607292016-02-05 15:25:58 -05001576 /**
Julia Reynoldscedacef2016-03-04 08:18:47 -05001577 * Whether notifications suppressed by DND should not interrupt visually (e.g. with
1578 * notification lights or by turning the screen on) when the screen is off.
Julia Reynoldsccc6ae62018-03-01 16:24:49 -05001579 *
1580 * @deprecated use {@link #SUPPRESSED_EFFECT_FULL_SCREEN_INTENT} and
1581 * {@link #SUPPRESSED_EFFECT_AMBIENT} and {@link #SUPPRESSED_EFFECT_LIGHTS} individually.
Julia Reynoldsd5607292016-02-05 15:25:58 -05001582 */
Julia Reynoldsccc6ae62018-03-01 16:24:49 -05001583 @Deprecated
Julia Reynoldsd5607292016-02-05 15:25:58 -05001584 public static final int SUPPRESSED_EFFECT_SCREEN_OFF = 1 << 0;
1585 /**
Julia Reynoldscedacef2016-03-04 08:18:47 -05001586 * Whether notifications suppressed by DND should not interrupt visually when the screen
1587 * is on (e.g. by peeking onto the screen).
Julia Reynoldsccc6ae62018-03-01 16:24:49 -05001588 *
1589 * @deprecated use {@link #SUPPRESSED_EFFECT_PEEK}.
Julia Reynoldsd5607292016-02-05 15:25:58 -05001590 */
Julia Reynoldsccc6ae62018-03-01 16:24:49 -05001591 @Deprecated
Julia Reynoldsd5607292016-02-05 15:25:58 -05001592 public static final int SUPPRESSED_EFFECT_SCREEN_ON = 1 << 1;
Julia Reynoldsf612869ae2015-11-05 16:48:55 -05001593
Julia Reynoldsccc6ae62018-03-01 16:24:49 -05001594 /**
1595 * Whether {@link Notification#fullScreenIntent full screen intents} from
1596 * notifications intercepted by DND are blocked.
1597 */
1598 public static final int SUPPRESSED_EFFECT_FULL_SCREEN_INTENT = 1 << 2;
1599
1600 /**
1601 * Whether {@link NotificationChannel#shouldShowLights() notification lights} from
1602 * notifications intercepted by DND are blocked.
1603 */
1604 public static final int SUPPRESSED_EFFECT_LIGHTS = 1 << 3;
1605
1606 /**
1607 * Whether notifications intercepted by DND are prevented from peeking.
1608 */
1609 public static final int SUPPRESSED_EFFECT_PEEK = 1 << 4;
1610
1611 /**
1612 * Whether notifications intercepted by DND are prevented from appearing in the status bar,
1613 * on devices that support status bars.
1614 */
1615 public static final int SUPPRESSED_EFFECT_STATUS_BAR = 1 << 5;
1616
1617 /**
1618 * Whether {@link NotificationChannel#canShowBadge() badges} from
1619 * notifications intercepted by DND are blocked on devices that support badging.
1620 */
1621 public static final int SUPPRESSED_EFFECT_BADGE = 1 << 6;
1622
1623 /**
1624 * Whether notification intercepted by DND are prevented from appearing on ambient displays
1625 * on devices that support ambient display.
1626 */
1627 public static final int SUPPRESSED_EFFECT_AMBIENT = 1 << 7;
1628
1629 /**
1630 * Whether notification intercepted by DND are prevented from appearing in notification
1631 * list views like the notification shade or lockscreen on devices that support those
1632 * views.
1633 */
1634 public static final int SUPPRESSED_EFFECT_NOTIFICATION_LIST = 1 << 8;
1635
Julia Reynoldsf612869ae2015-11-05 16:48:55 -05001636 private static final int[] ALL_SUPPRESSED_EFFECTS = {
Julia Reynoldsd5607292016-02-05 15:25:58 -05001637 SUPPRESSED_EFFECT_SCREEN_OFF,
Julia Reynolds61721582016-01-05 08:35:25 -05001638 SUPPRESSED_EFFECT_SCREEN_ON,
Julia Reynoldsccc6ae62018-03-01 16:24:49 -05001639 SUPPRESSED_EFFECT_FULL_SCREEN_INTENT,
1640 SUPPRESSED_EFFECT_LIGHTS,
1641 SUPPRESSED_EFFECT_PEEK,
1642 SUPPRESSED_EFFECT_STATUS_BAR,
1643 SUPPRESSED_EFFECT_BADGE,
1644 SUPPRESSED_EFFECT_AMBIENT,
1645 SUPPRESSED_EFFECT_NOTIFICATION_LIST
Julia Reynoldsf612869ae2015-11-05 16:48:55 -05001646 };
1647
Julia Reynolds47f42802018-04-09 08:47:39 -04001648 private static final int[] SCREEN_OFF_SUPPRESSED_EFFECTS = {
1649 SUPPRESSED_EFFECT_SCREEN_OFF,
1650 SUPPRESSED_EFFECT_FULL_SCREEN_INTENT,
1651 SUPPRESSED_EFFECT_LIGHTS,
1652 SUPPRESSED_EFFECT_AMBIENT,
1653 };
1654
1655 private static final int[] SCREEN_ON_SUPPRESSED_EFFECTS = {
1656 SUPPRESSED_EFFECT_SCREEN_ON,
1657 SUPPRESSED_EFFECT_PEEK,
1658 SUPPRESSED_EFFECT_STATUS_BAR,
1659 SUPPRESSED_EFFECT_BADGE,
1660 SUPPRESSED_EFFECT_NOTIFICATION_LIST
1661 };
1662
Julia Reynoldsf612869ae2015-11-05 16:48:55 -05001663 /**
1664 * Visual effects to suppress for a notification that is filtered by Do Not Disturb mode.
1665 * Bitmask of SUPPRESSED_EFFECT_* constants.
1666 */
1667 public final int suppressedVisualEffects;
1668
Julia Reynoldscedacef2016-03-04 08:18:47 -05001669 /**
Beverly86d076f2018-04-17 14:44:52 -04001670 * @hide
1671 */
1672 public static final int STATE_CHANNELS_BYPASSING_DND = 1 << 0;
1673
1674 /**
1675 * @hide
1676 */
1677 public static final int STATE_UNSET = -1;
1678
1679 /**
1680 * Notification state information that is necessary to determine Do Not Disturb behavior.
1681 * Bitmask of STATE_* constants.
1682 * @hide
1683 */
1684 public final int state;
1685
1686 /**
Julia Reynoldscedacef2016-03-04 08:18:47 -05001687 * Constructs a policy for Do Not Disturb priority mode behavior.
1688 *
Julia Reynoldsccc6ae62018-03-01 16:24:49 -05001689 * <p>
1690 * Apps that target API levels below {@link Build.VERSION_CODES#P} cannot
1691 * change user-designated values to allow or disallow
1692 * {@link Policy#PRIORITY_CATEGORY_ALARMS}, {@link Policy#PRIORITY_CATEGORY_SYSTEM}, and
1693 * {@link Policy#PRIORITY_CATEGORY_MEDIA} from bypassing dnd.
1694 *
Julia Reynoldscedacef2016-03-04 08:18:47 -05001695 * @param priorityCategories bitmask of categories of notifications that can bypass DND.
1696 * @param priorityCallSenders which callers can bypass DND.
1697 * @param priorityMessageSenders which message senders can bypass DND.
1698 */
John Spurlock80774932015-05-07 17:38:50 -04001699 public Policy(int priorityCategories, int priorityCallSenders, int priorityMessageSenders) {
Julia Reynoldsf612869ae2015-11-05 16:48:55 -05001700 this(priorityCategories, priorityCallSenders, priorityMessageSenders,
Beverly86d076f2018-04-17 14:44:52 -04001701 SUPPRESSED_EFFECTS_UNSET, STATE_UNSET);
Julia Reynoldsf612869ae2015-11-05 16:48:55 -05001702 }
1703
Julia Reynoldscedacef2016-03-04 08:18:47 -05001704 /**
1705 * Constructs a policy for Do Not Disturb priority mode behavior.
1706 *
Julia Reynoldsccc6ae62018-03-01 16:24:49 -05001707 * <p>
1708 * Apps that target API levels below {@link Build.VERSION_CODES#P} cannot
1709 * change user-designated values to allow or disallow
1710 * {@link Policy#PRIORITY_CATEGORY_ALARMS}, {@link Policy#PRIORITY_CATEGORY_SYSTEM}, and
1711 * {@link Policy#PRIORITY_CATEGORY_MEDIA} from bypassing dnd.
1712 * <p>
1713 * Additionally, apps that target API levels below {@link Build.VERSION_CODES#P} can
1714 * only modify the {@link #SUPPRESSED_EFFECT_SCREEN_ON} and
1715 * {@link #SUPPRESSED_EFFECT_SCREEN_OFF} bits of the suppressed visual effects field.
1716 * All other suppressed effects will be ignored and reconstituted from the screen on
1717 * and screen off values.
1718 * <p>
1719 * Apps that target {@link Build.VERSION_CODES#P} or above can set any
1720 * suppressed visual effects. However, if any suppressed effects >
1721 * {@link #SUPPRESSED_EFFECT_SCREEN_ON} are set, {@link #SUPPRESSED_EFFECT_SCREEN_ON}
1722 * and {@link #SUPPRESSED_EFFECT_SCREEN_OFF} will be ignored and reconstituted from
1723 * the more specific suppressed visual effect bits. Apps should migrate to targeting
1724 * specific effects instead of the deprecated {@link #SUPPRESSED_EFFECT_SCREEN_ON} and
1725 * {@link #SUPPRESSED_EFFECT_SCREEN_OFF} effects.
1726 *
Julia Reynoldscedacef2016-03-04 08:18:47 -05001727 * @param priorityCategories bitmask of categories of notifications that can bypass DND.
1728 * @param priorityCallSenders which callers can bypass DND.
1729 * @param priorityMessageSenders which message senders can bypass DND.
1730 * @param suppressedVisualEffects which visual interruptions should be suppressed from
1731 * notifications that are filtered by DND.
1732 */
Julia Reynoldsf612869ae2015-11-05 16:48:55 -05001733 public Policy(int priorityCategories, int priorityCallSenders, int priorityMessageSenders,
1734 int suppressedVisualEffects) {
John Spurlock1fc476d2015-04-14 16:05:20 -04001735 this.priorityCategories = priorityCategories;
John Spurlock80774932015-05-07 17:38:50 -04001736 this.priorityCallSenders = priorityCallSenders;
1737 this.priorityMessageSenders = priorityMessageSenders;
Julia Reynoldsf612869ae2015-11-05 16:48:55 -05001738 this.suppressedVisualEffects = suppressedVisualEffects;
Beverly86d076f2018-04-17 14:44:52 -04001739 this.state = STATE_UNSET;
1740 }
1741
1742 /** @hide */
1743 public Policy(int priorityCategories, int priorityCallSenders, int priorityMessageSenders,
1744 int suppressedVisualEffects, int state) {
1745 this.priorityCategories = priorityCategories;
1746 this.priorityCallSenders = priorityCallSenders;
1747 this.priorityMessageSenders = priorityMessageSenders;
1748 this.suppressedVisualEffects = suppressedVisualEffects;
1749 this.state = state;
John Spurlock1fc476d2015-04-14 16:05:20 -04001750 }
1751
1752 /** @hide */
1753 public Policy(Parcel source) {
Beverly86d076f2018-04-17 14:44:52 -04001754 this(source.readInt(), source.readInt(), source.readInt(), source.readInt(),
1755 source.readInt());
John Spurlock1fc476d2015-04-14 16:05:20 -04001756 }
1757
1758 @Override
1759 public void writeToParcel(Parcel dest, int flags) {
1760 dest.writeInt(priorityCategories);
John Spurlock80774932015-05-07 17:38:50 -04001761 dest.writeInt(priorityCallSenders);
1762 dest.writeInt(priorityMessageSenders);
Julia Reynoldsf612869ae2015-11-05 16:48:55 -05001763 dest.writeInt(suppressedVisualEffects);
Beverly86d076f2018-04-17 14:44:52 -04001764 dest.writeInt(state);
John Spurlock1fc476d2015-04-14 16:05:20 -04001765 }
1766
1767 @Override
1768 public int describeContents() {
1769 return 0;
1770 }
1771
1772 @Override
1773 public int hashCode() {
Julia Reynoldsf612869ae2015-11-05 16:48:55 -05001774 return Objects.hash(priorityCategories, priorityCallSenders, priorityMessageSenders,
Beverly4f8b0222019-10-24 13:35:03 -04001775 suppressedVisualEffects, state);
John Spurlock1fc476d2015-04-14 16:05:20 -04001776 }
1777
1778 @Override
1779 public boolean equals(Object o) {
1780 if (!(o instanceof Policy)) return false;
1781 if (o == this) return true;
1782 final Policy other = (Policy) o;
1783 return other.priorityCategories == priorityCategories
John Spurlock80774932015-05-07 17:38:50 -04001784 && other.priorityCallSenders == priorityCallSenders
Julia Reynoldsf612869ae2015-11-05 16:48:55 -05001785 && other.priorityMessageSenders == priorityMessageSenders
Beverly9cb05c92018-11-28 10:03:23 -05001786 && suppressedVisualEffectsEqual(suppressedVisualEffects,
Beverly4f8b0222019-10-24 13:35:03 -04001787 other.suppressedVisualEffects)
1788 && other.state == this.state;
Beverly9cb05c92018-11-28 10:03:23 -05001789 }
1790
Beverly9cb05c92018-11-28 10:03:23 -05001791 private boolean suppressedVisualEffectsEqual(int suppressedEffects,
1792 int otherSuppressedVisualEffects) {
1793 if (suppressedEffects == otherSuppressedVisualEffects) {
1794 return true;
1795 }
1796
1797 if ((suppressedEffects & SUPPRESSED_EFFECT_SCREEN_ON) != 0) {
1798 suppressedEffects |= SUPPRESSED_EFFECT_PEEK;
1799 }
1800 if ((suppressedEffects & SUPPRESSED_EFFECT_SCREEN_OFF) != 0) {
1801 suppressedEffects |= SUPPRESSED_EFFECT_FULL_SCREEN_INTENT;
1802 suppressedEffects |= SUPPRESSED_EFFECT_LIGHTS;
1803 suppressedEffects |= SUPPRESSED_EFFECT_AMBIENT;
1804 }
1805
1806 if ((otherSuppressedVisualEffects & SUPPRESSED_EFFECT_SCREEN_ON) != 0) {
1807 otherSuppressedVisualEffects |= SUPPRESSED_EFFECT_PEEK;
1808 }
1809 if ((otherSuppressedVisualEffects & SUPPRESSED_EFFECT_SCREEN_OFF) != 0) {
1810 otherSuppressedVisualEffects |= SUPPRESSED_EFFECT_FULL_SCREEN_INTENT;
1811 otherSuppressedVisualEffects |= SUPPRESSED_EFFECT_LIGHTS;
1812 otherSuppressedVisualEffects |= SUPPRESSED_EFFECT_AMBIENT;
1813 }
1814
1815 if ((suppressedEffects & SUPPRESSED_EFFECT_SCREEN_ON)
1816 != (otherSuppressedVisualEffects & SUPPRESSED_EFFECT_SCREEN_ON)) {
1817 int currSuppressedEffects = (suppressedEffects & SUPPRESSED_EFFECT_SCREEN_ON) != 0
1818 ? otherSuppressedVisualEffects : suppressedEffects;
1819 if ((currSuppressedEffects & SUPPRESSED_EFFECT_PEEK) == 0) {
1820 return false;
1821 }
1822 }
1823
1824 if ((suppressedEffects & SUPPRESSED_EFFECT_SCREEN_OFF)
1825 != (otherSuppressedVisualEffects & SUPPRESSED_EFFECT_SCREEN_OFF)) {
1826 int currSuppressedEffects = (suppressedEffects & SUPPRESSED_EFFECT_SCREEN_OFF) != 0
1827 ? otherSuppressedVisualEffects : suppressedEffects;
1828 if ((currSuppressedEffects & SUPPRESSED_EFFECT_FULL_SCREEN_INTENT) == 0
1829 || (currSuppressedEffects & SUPPRESSED_EFFECT_LIGHTS) == 0
1830 || (currSuppressedEffects & SUPPRESSED_EFFECT_AMBIENT) == 0) {
1831 return false;
1832 }
1833 }
1834
1835 int thisWithoutOldEffects = suppressedEffects
1836 & ~SUPPRESSED_EFFECT_SCREEN_ON
1837 & ~SUPPRESSED_EFFECT_SCREEN_OFF;
1838 int otherWithoutOldEffects = otherSuppressedVisualEffects
1839 & ~SUPPRESSED_EFFECT_SCREEN_ON
1840 & ~SUPPRESSED_EFFECT_SCREEN_OFF;
1841 return thisWithoutOldEffects == otherWithoutOldEffects;
John Spurlock1fc476d2015-04-14 16:05:20 -04001842 }
1843
1844 @Override
1845 public String toString() {
1846 return "NotificationManager.Policy["
1847 + "priorityCategories=" + priorityCategoriesToString(priorityCategories)
John Spurlock80774932015-05-07 17:38:50 -04001848 + ",priorityCallSenders=" + prioritySendersToString(priorityCallSenders)
1849 + ",priorityMessageSenders=" + prioritySendersToString(priorityMessageSenders)
Julia Reynoldsf612869ae2015-11-05 16:48:55 -05001850 + ",suppressedVisualEffects="
1851 + suppressedEffectsToString(suppressedVisualEffects)
Beverly86d076f2018-04-17 14:44:52 -04001852 + ",areChannelsBypassingDnd=" + (((state & STATE_CHANNELS_BYPASSING_DND) != 0)
1853 ? "true" : "false")
John Spurlock1fc476d2015-04-14 16:05:20 -04001854 + "]";
1855 }
1856
Kweku Adams5ec78cd2017-09-25 16:29:54 -07001857 /** @hide */
Jeffrey Huangcb782852019-12-05 11:28:11 -08001858 public void dumpDebug(ProtoOutputStream proto, long fieldId) {
Kweku Adams5ec78cd2017-09-25 16:29:54 -07001859 final long pToken = proto.start(fieldId);
1860
1861 bitwiseToProtoEnum(proto, PolicyProto.PRIORITY_CATEGORIES, priorityCategories);
1862 proto.write(PolicyProto.PRIORITY_CALL_SENDER, priorityCallSenders);
1863 proto.write(PolicyProto.PRIORITY_MESSAGE_SENDER, priorityMessageSenders);
1864 bitwiseToProtoEnum(
1865 proto, PolicyProto.SUPPRESSED_VISUAL_EFFECTS, suppressedVisualEffects);
1866
1867 proto.end(pToken);
1868 }
1869
1870 private static void bitwiseToProtoEnum(ProtoOutputStream proto, long fieldId, int data) {
1871 for (int i = 1; data > 0; ++i, data >>>= 1) {
1872 if ((data & 1) == 1) {
1873 proto.write(fieldId, i);
1874 }
1875 }
1876 }
1877
Julia Reynoldsccc6ae62018-03-01 16:24:49 -05001878 /**
1879 * @hide
1880 */
1881 public static int getAllSuppressedVisualEffects() {
1882 int effects = 0;
1883 for (int i = 0; i < ALL_SUPPRESSED_EFFECTS.length; i++) {
1884 effects |= ALL_SUPPRESSED_EFFECTS[i];
1885 }
1886 return effects;
1887 }
1888
1889 /**
1890 * @hide
1891 */
1892 public static boolean areAllVisualEffectsSuppressed(int effects) {
1893 for (int i = 0; i < ALL_SUPPRESSED_EFFECTS.length; i++) {
1894 final int effect = ALL_SUPPRESSED_EFFECTS[i];
1895 if ((effects & effect) == 0) {
1896 return false;
1897 }
1898 }
1899 return true;
1900 }
1901
Julia Reynolds9aa1c9e2018-04-09 11:31:15 -04001902 private static int toggleEffects(int currentEffects, int[] effects, boolean suppress) {
1903 for (int i = 0; i < effects.length; i++) {
1904 final int effect = effects[i];
1905 if (suppress) {
1906 currentEffects |= effect;
1907 } else {
1908 currentEffects &= ~effect;
1909 }
1910 }
1911 return currentEffects;
1912 }
1913
Julia Reynoldsf612869ae2015-11-05 16:48:55 -05001914 public static String suppressedEffectsToString(int effects) {
1915 if (effects <= 0) return "";
1916 final StringBuilder sb = new StringBuilder();
1917 for (int i = 0; i < ALL_SUPPRESSED_EFFECTS.length; i++) {
1918 final int effect = ALL_SUPPRESSED_EFFECTS[i];
1919 if ((effects & effect) != 0) {
1920 if (sb.length() > 0) sb.append(',');
1921 sb.append(effectToString(effect));
1922 }
1923 effects &= ~effect;
1924 }
1925 if (effects != 0) {
1926 if (sb.length() > 0) sb.append(',');
1927 sb.append("UNKNOWN_").append(effects);
1928 }
1929 return sb.toString();
1930 }
1931
John Spurlock1fc476d2015-04-14 16:05:20 -04001932 public static String priorityCategoriesToString(int priorityCategories) {
1933 if (priorityCategories == 0) return "";
1934 final StringBuilder sb = new StringBuilder();
1935 for (int i = 0; i < ALL_PRIORITY_CATEGORIES.length; i++) {
1936 final int priorityCategory = ALL_PRIORITY_CATEGORIES[i];
1937 if ((priorityCategories & priorityCategory) != 0) {
1938 if (sb.length() > 0) sb.append(',');
1939 sb.append(priorityCategoryToString(priorityCategory));
1940 }
1941 priorityCategories &= ~priorityCategory;
1942 }
1943 if (priorityCategories != 0) {
1944 if (sb.length() > 0) sb.append(',');
1945 sb.append("PRIORITY_CATEGORY_UNKNOWN_").append(priorityCategories);
1946 }
1947 return sb.toString();
1948 }
1949
Julia Reynoldsf612869ae2015-11-05 16:48:55 -05001950 private static String effectToString(int effect) {
1951 switch (effect) {
Julia Reynoldsccc6ae62018-03-01 16:24:49 -05001952 case SUPPRESSED_EFFECT_FULL_SCREEN_INTENT:
1953 return "SUPPRESSED_EFFECT_FULL_SCREEN_INTENT";
1954 case SUPPRESSED_EFFECT_LIGHTS:
1955 return "SUPPRESSED_EFFECT_LIGHTS";
1956 case SUPPRESSED_EFFECT_PEEK:
1957 return "SUPPRESSED_EFFECT_PEEK";
1958 case SUPPRESSED_EFFECT_STATUS_BAR:
1959 return "SUPPRESSED_EFFECT_STATUS_BAR";
1960 case SUPPRESSED_EFFECT_BADGE:
1961 return "SUPPRESSED_EFFECT_BADGE";
1962 case SUPPRESSED_EFFECT_AMBIENT:
1963 return "SUPPRESSED_EFFECT_AMBIENT";
1964 case SUPPRESSED_EFFECT_NOTIFICATION_LIST:
1965 return "SUPPRESSED_EFFECT_NOTIFICATION_LIST";
1966 case SUPPRESSED_EFFECT_SCREEN_OFF:
1967 return "SUPPRESSED_EFFECT_SCREEN_OFF";
1968 case SUPPRESSED_EFFECT_SCREEN_ON:
1969 return "SUPPRESSED_EFFECT_SCREEN_ON";
1970 case SUPPRESSED_EFFECTS_UNSET:
1971 return "SUPPRESSED_EFFECTS_UNSET";
Julia Reynoldsf612869ae2015-11-05 16:48:55 -05001972 default: return "UNKNOWN_" + effect;
1973 }
1974 }
1975
John Spurlock1fc476d2015-04-14 16:05:20 -04001976 private static String priorityCategoryToString(int priorityCategory) {
1977 switch (priorityCategory) {
1978 case PRIORITY_CATEGORY_REMINDERS: return "PRIORITY_CATEGORY_REMINDERS";
1979 case PRIORITY_CATEGORY_EVENTS: return "PRIORITY_CATEGORY_EVENTS";
1980 case PRIORITY_CATEGORY_MESSAGES: return "PRIORITY_CATEGORY_MESSAGES";
1981 case PRIORITY_CATEGORY_CALLS: return "PRIORITY_CATEGORY_CALLS";
1982 case PRIORITY_CATEGORY_REPEAT_CALLERS: return "PRIORITY_CATEGORY_REPEAT_CALLERS";
Beverly04216872017-09-28 10:55:32 -04001983 case PRIORITY_CATEGORY_ALARMS: return "PRIORITY_CATEGORY_ALARMS";
Beverlyd6964762018-02-16 14:07:03 -05001984 case PRIORITY_CATEGORY_MEDIA: return "PRIORITY_CATEGORY_MEDIA";
1985 case PRIORITY_CATEGORY_SYSTEM: return "PRIORITY_CATEGORY_SYSTEM";
John Spurlock1fc476d2015-04-14 16:05:20 -04001986 default: return "PRIORITY_CATEGORY_UNKNOWN_" + priorityCategory;
1987 }
1988 }
1989
1990 public static String prioritySendersToString(int prioritySenders) {
1991 switch (prioritySenders) {
1992 case PRIORITY_SENDERS_ANY: return "PRIORITY_SENDERS_ANY";
1993 case PRIORITY_SENDERS_CONTACTS: return "PRIORITY_SENDERS_CONTACTS";
1994 case PRIORITY_SENDERS_STARRED: return "PRIORITY_SENDERS_STARRED";
1995 default: return "PRIORITY_SENDERS_UNKNOWN_" + prioritySenders;
1996 }
1997 }
1998
Jeff Sharkey9e8f83d2019-02-28 12:06:45 -07001999 public static final @android.annotation.NonNull Parcelable.Creator<Policy> CREATOR = new Parcelable.Creator<Policy>() {
John Spurlock1fc476d2015-04-14 16:05:20 -04002000 @Override
2001 public Policy createFromParcel(Parcel in) {
2002 return new Policy(in);
2003 }
2004
2005 @Override
2006 public Policy[] newArray(int size) {
2007 return new Policy[size];
2008 }
2009 };
Beverlyff2df9b2018-10-10 16:54:10 -04002010
2011 /** @hide **/
2012 public boolean allowAlarms() {
2013 return (priorityCategories & PRIORITY_CATEGORY_ALARMS) != 0;
2014 }
2015
2016 /** @hide **/
2017 public boolean allowMedia() {
2018 return (priorityCategories & PRIORITY_CATEGORY_MEDIA) != 0;
2019 }
2020
2021 /** @hide **/
2022 public boolean allowSystem() {
2023 return (priorityCategories & PRIORITY_CATEGORY_SYSTEM) != 0;
2024 }
2025
2026 /** @hide **/
2027 public boolean allowRepeatCallers() {
2028 return (priorityCategories & PRIORITY_CATEGORY_REPEAT_CALLERS) != 0;
2029 }
2030
2031 /** @hide **/
2032 public boolean allowCalls() {
2033 return (priorityCategories & PRIORITY_CATEGORY_CALLS) != 0;
2034 }
2035
2036 /** @hide **/
2037 public boolean allowMessages() {
2038 return (priorityCategories & PRIORITY_CATEGORY_MESSAGES) != 0;
2039 }
2040
2041 /** @hide **/
2042 public boolean allowEvents() {
2043 return (priorityCategories & PRIORITY_CATEGORY_EVENTS) != 0;
2044 }
2045
2046 /** @hide **/
2047 public boolean allowReminders() {
2048 return (priorityCategories & PRIORITY_CATEGORY_REMINDERS) != 0;
2049 }
2050
2051 /** @hide **/
2052 public int allowCallsFrom() {
2053 return priorityCallSenders;
2054 }
2055
2056 /** @hide **/
2057 public int allowMessagesFrom() {
2058 return priorityMessageSenders;
2059 }
2060
Beverly12196702018-12-12 15:05:51 -05002061 /** @hide **/
2062 public boolean showFullScreenIntents() {
2063 return (suppressedVisualEffects & SUPPRESSED_EFFECT_FULL_SCREEN_INTENT) == 0;
2064 }
2065
2066 /** @hide **/
2067 public boolean showLights() {
2068 return (suppressedVisualEffects & SUPPRESSED_EFFECT_LIGHTS) == 0;
2069 }
2070
2071 /** @hide **/
2072 public boolean showPeeking() {
2073 return (suppressedVisualEffects & SUPPRESSED_EFFECT_PEEK) == 0;
2074 }
2075
2076 /** @hide **/
2077 public boolean showStatusBarIcons() {
2078 return (suppressedVisualEffects & SUPPRESSED_EFFECT_STATUS_BAR) == 0;
2079 }
2080
2081 /** @hide **/
2082 public boolean showAmbient() {
2083 return (suppressedVisualEffects & SUPPRESSED_EFFECT_AMBIENT) == 0;
2084 }
2085
2086 /** @hide **/
2087 public boolean showBadges() {
2088 return (suppressedVisualEffects & SUPPRESSED_EFFECT_BADGE) == 0;
2089 }
2090
2091 /** @hide **/
2092 public boolean showInNotificationList() {
2093 return (suppressedVisualEffects & SUPPRESSED_EFFECT_NOTIFICATION_LIST) == 0;
2094 }
2095
Beverlyff2df9b2018-10-10 16:54:10 -04002096 /**
2097 * returns a deep copy of this policy
2098 * @hide
2099 */
2100 public Policy copy() {
2101 final Parcel parcel = Parcel.obtain();
2102 try {
2103 writeToParcel(parcel, 0);
2104 parcel.setDataPosition(0);
2105 return new Policy(parcel);
2106 } finally {
2107 parcel.recycle();
2108 }
2109 }
John Spurlock1fc476d2015-04-14 16:05:20 -04002110 }
2111
Dan Sandler994349c2015-04-15 11:02:54 -04002112 /**
2113 * Recover a list of active notifications: ones that have been posted by the calling app that
2114 * have not yet been dismissed by the user or {@link #cancel(String, int)}ed by the app.
2115 *
Julia Reynoldsd12392c2018-12-17 14:06:04 -05002116 * <p><Each notification is embedded in a {@link StatusBarNotification} object, including the
Dan Sandler994349c2015-04-15 11:02:54 -04002117 * original <code>tag</code> and <code>id</code> supplied to
2118 * {@link #notify(String, int, Notification) notify()}
2119 * (via {@link StatusBarNotification#getTag() getTag()} and
2120 * {@link StatusBarNotification#getId() getId()}) as well as a copy of the original
2121 * {@link Notification} object (via {@link StatusBarNotification#getNotification()}).
Julia Reynoldsd12392c2018-12-17 14:06:04 -05002122 * </p>
2123 * <p>From {@link Build.VERSION_CODES#Q}, will also return notifications you've posted as an
2124 * app's notification delegate via
2125 * {@link NotificationManager#notifyAsPackage(String, String, int, Notification)}.
2126 * </p>
Dan Sandler994349c2015-04-15 11:02:54 -04002127 *
2128 * @return An array of {@link StatusBarNotification}.
2129 */
2130 public StatusBarNotification[] getActiveNotifications() {
2131 final INotificationManager service = getService();
2132 final String pkg = mContext.getPackageName();
2133 try {
2134 final ParceledListSlice<StatusBarNotification> parceledList
Jeff Sharkeyad357d12018-02-02 13:25:31 -07002135 = service.getAppActiveNotifications(pkg, mContext.getUserId());
Julia Reynolds34a80842018-09-21 13:01:00 -04002136 if (parceledList != null) {
2137 final List<StatusBarNotification> list = parceledList.getList();
2138 return list.toArray(new StatusBarNotification[list.size()]);
2139 }
Dan Sandler994349c2015-04-15 11:02:54 -04002140 } catch (RemoteException e) {
Jeff Sharkeyc53962d2016-03-01 19:27:23 -07002141 throw e.rethrowFromSystemServer();
Dan Sandler994349c2015-04-15 11:02:54 -04002142 }
Julia Reynolds34a80842018-09-21 13:01:00 -04002143 return new StatusBarNotification[0];
Dan Sandler994349c2015-04-15 11:02:54 -04002144 }
John Spurlock80774932015-05-07 17:38:50 -04002145
2146 /**
2147 * Gets the current notification interruption filter.
John Spurlock80774932015-05-07 17:38:50 -04002148 * <p>
Jeff Sharkey6503bd82017-04-19 23:24:18 -06002149 * The interruption filter defines which notifications are allowed to
2150 * interrupt the user (e.g. via sound &amp; vibration) and is applied
2151 * globally.
John Spurlock80774932015-05-07 17:38:50 -04002152 */
Julia Reynolds0edb50c2016-02-26 14:08:25 -05002153 public final @InterruptionFilter int getCurrentInterruptionFilter() {
John Spurlock80774932015-05-07 17:38:50 -04002154 final INotificationManager service = getService();
2155 try {
2156 return zenModeToInterruptionFilter(service.getZenMode());
2157 } catch (RemoteException e) {
Jeff Sharkeyc53962d2016-03-01 19:27:23 -07002158 throw e.rethrowFromSystemServer();
John Spurlock80774932015-05-07 17:38:50 -04002159 }
John Spurlock80774932015-05-07 17:38:50 -04002160 }
2161
2162 /**
2163 * Sets the current notification interruption filter.
John Spurlock80774932015-05-07 17:38:50 -04002164 * <p>
Jeff Sharkey6503bd82017-04-19 23:24:18 -06002165 * The interruption filter defines which notifications are allowed to
2166 * interrupt the user (e.g. via sound &amp; vibration) and is applied
2167 * globally.
John Spurlock80774932015-05-07 17:38:50 -04002168 * <p>
Jeff Sharkey6503bd82017-04-19 23:24:18 -06002169 * Only available if policy access is granted to this package. See
2170 * {@link #isNotificationPolicyAccessGranted}.
John Spurlock80774932015-05-07 17:38:50 -04002171 */
Jeff Sharkey6503bd82017-04-19 23:24:18 -06002172 public final void setInterruptionFilter(@InterruptionFilter int interruptionFilter) {
John Spurlock80774932015-05-07 17:38:50 -04002173 final INotificationManager service = getService();
2174 try {
2175 service.setInterruptionFilter(mContext.getOpPackageName(), interruptionFilter);
2176 } catch (RemoteException e) {
Jeff Sharkeyc53962d2016-03-01 19:27:23 -07002177 throw e.rethrowFromSystemServer();
John Spurlock80774932015-05-07 17:38:50 -04002178 }
2179 }
2180
2181 /** @hide */
2182 public static int zenModeToInterruptionFilter(int zen) {
2183 switch (zen) {
2184 case Global.ZEN_MODE_OFF: return INTERRUPTION_FILTER_ALL;
2185 case Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS: return INTERRUPTION_FILTER_PRIORITY;
2186 case Global.ZEN_MODE_ALARMS: return INTERRUPTION_FILTER_ALARMS;
2187 case Global.ZEN_MODE_NO_INTERRUPTIONS: return INTERRUPTION_FILTER_NONE;
2188 default: return INTERRUPTION_FILTER_UNKNOWN;
2189 }
2190 }
2191
2192 /** @hide */
2193 public static int zenModeFromInterruptionFilter(int interruptionFilter, int defValue) {
2194 switch (interruptionFilter) {
2195 case INTERRUPTION_FILTER_ALL: return Global.ZEN_MODE_OFF;
2196 case INTERRUPTION_FILTER_PRIORITY: return Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS;
2197 case INTERRUPTION_FILTER_ALARMS: return Global.ZEN_MODE_ALARMS;
2198 case INTERRUPTION_FILTER_NONE: return Global.ZEN_MODE_NO_INTERRUPTIONS;
2199 default: return defValue;
2200 }
2201 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002202}