blob: b13a34faab6be11b1bd03a28dbc4043cf6b4b697 [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 /**
John Spurlockb4782522014-08-22 14:54:46 -0400174 * Intent that is broadcast when the state of {@link #getEffectsSuppressor()} changes.
175 * This broadcast is only sent to registered receivers.
176 *
177 * @hide
178 */
179 @SdkConstant(SdkConstant.SdkConstantType.BROADCAST_INTENT_ACTION)
180 public static final String ACTION_EFFECTS_SUPPRESSOR_CHANGED
181 = "android.os.action.ACTION_EFFECTS_SUPPRESSOR_CHANGED";
182
John Spurlock1fc476d2015-04-14 16:05:20 -0400183 /**
John Spurlock7c74f782015-06-04 13:01:42 -0400184 * Intent that is broadcast when the state of {@link #isNotificationPolicyAccessGranted()}
185 * changes.
186 *
187 * This broadcast is only sent to registered receivers, and only to the apps that have changed.
188 */
189 @SdkConstant(SdkConstant.SdkConstantType.BROADCAST_INTENT_ACTION)
190 public static final String ACTION_NOTIFICATION_POLICY_ACCESS_GRANTED_CHANGED
191 = "android.app.action.NOTIFICATION_POLICY_ACCESS_GRANTED_CHANGED";
192
193 /**
John Spurlock1fc476d2015-04-14 16:05:20 -0400194 * Intent that is broadcast when the state of getNotificationPolicy() changes.
195 * This broadcast is only sent to registered receivers.
196 */
197 @SdkConstant(SdkConstant.SdkConstantType.BROADCAST_INTENT_ACTION)
198 public static final String ACTION_NOTIFICATION_POLICY_CHANGED
199 = "android.app.action.NOTIFICATION_POLICY_CHANGED";
200
John Spurlock80774932015-05-07 17:38:50 -0400201 /**
202 * Intent that is broadcast when the state of getCurrentInterruptionFilter() changes.
203 * This broadcast is only sent to registered receivers.
204 */
205 @SdkConstant(SdkConstant.SdkConstantType.BROADCAST_INTENT_ACTION)
206 public static final String ACTION_INTERRUPTION_FILTER_CHANGED
207 = "android.app.action.INTERRUPTION_FILTER_CHANGED";
208
209 /**
Jason Monka9927322015-12-13 16:22:37 -0500210 * Intent that is broadcast when the state of getCurrentInterruptionFilter() changes.
211 * @hide
212 */
213 @SdkConstant(SdkConstant.SdkConstantType.BROADCAST_INTENT_ACTION)
214 public static final String ACTION_INTERRUPTION_FILTER_CHANGED_INTERNAL
215 = "android.app.action.INTERRUPTION_FILTER_CHANGED_INTERNAL";
216
Julia Reynolds0edb50c2016-02-26 14:08:25 -0500217 /** @hide */
Jeff Sharkey6503bd82017-04-19 23:24:18 -0600218 @IntDef(prefix = { "INTERRUPTION_FILTER_" }, value = {
219 INTERRUPTION_FILTER_NONE, INTERRUPTION_FILTER_PRIORITY, INTERRUPTION_FILTER_ALARMS,
220 INTERRUPTION_FILTER_ALL, INTERRUPTION_FILTER_UNKNOWN
221 })
Julia Reynolds0edb50c2016-02-26 14:08:25 -0500222 @Retention(RetentionPolicy.SOURCE)
223 public @interface InterruptionFilter {}
224
Jason Monka9927322015-12-13 16:22:37 -0500225 /**
John Spurlock80774932015-05-07 17:38:50 -0400226 * {@link #getCurrentInterruptionFilter() Interruption filter} constant -
Julia Reynoldsdd0605b2016-04-06 10:26:54 -0400227 * Normal interruption filter - no notifications are suppressed.
John Spurlock80774932015-05-07 17:38:50 -0400228 */
229 public static final int INTERRUPTION_FILTER_ALL = 1;
230
231 /**
232 * {@link #getCurrentInterruptionFilter() Interruption filter} constant -
Julia Reynoldsdd0605b2016-04-06 10:26:54 -0400233 * Priority interruption filter - all notifications are suppressed except those that match
234 * the priority criteria. Some audio streams are muted. See
235 * {@link Policy#priorityCallSenders}, {@link Policy#priorityCategories},
236 * {@link Policy#priorityMessageSenders} to define or query this criteria. Users can
237 * additionally specify packages that can bypass this interruption filter.
John Spurlock80774932015-05-07 17:38:50 -0400238 */
239 public static final int INTERRUPTION_FILTER_PRIORITY = 2;
240
241 /**
242 * {@link #getCurrentInterruptionFilter() Interruption filter} constant -
Julia Reynoldsdd0605b2016-04-06 10:26:54 -0400243 * No interruptions filter - all notifications are suppressed and all audio streams (except
244 * those used for phone calls) and vibrations are muted.
John Spurlock80774932015-05-07 17:38:50 -0400245 */
246 public static final int INTERRUPTION_FILTER_NONE = 3;
247
248 /**
249 * {@link #getCurrentInterruptionFilter() Interruption filter} constant -
Julia Reynoldsdd0605b2016-04-06 10:26:54 -0400250 * Alarms only interruption filter - all notifications except those of category
251 * {@link Notification#CATEGORY_ALARM} are suppressed. Some audio streams are muted.
John Spurlock80774932015-05-07 17:38:50 -0400252 */
253 public static final int INTERRUPTION_FILTER_ALARMS = 4;
254
255 /** {@link #getCurrentInterruptionFilter() Interruption filter} constant - returned when
256 * the value is unavailable for any reason.
257 */
258 public static final int INTERRUPTION_FILTER_UNKNOWN = 0;
259
Chris Wren5ab5c742016-05-10 15:32:23 -0400260 /** @hide */
Jeff Sharkey6503bd82017-04-19 23:24:18 -0600261 @IntDef(prefix = { "IMPORTANCE_" }, value = {
262 IMPORTANCE_UNSPECIFIED, IMPORTANCE_NONE,
263 IMPORTANCE_MIN, IMPORTANCE_LOW, IMPORTANCE_DEFAULT, IMPORTANCE_HIGH
264 })
Chris Wren5ab5c742016-05-10 15:32:23 -0400265 @Retention(RetentionPolicy.SOURCE)
266 public @interface Importance {}
267
Julia Reynolds68062072018-08-06 15:38:21 -0400268 /**
269 * Activity Action: Launch an Automatic Zen Rule configuration screen
270 * <p>
271 * Input: Optionally, {@link #EXTRA_AUTOMATIC_RULE_ID}, if the configuration screen for an
272 * existing rule should be displayed. If the rule id is missing or null, apps should display
273 * a configuration screen where users can create a new instance of the rule.
274 * <p>
275 * Output: Nothing
276 * <p>
277 * You can have multiple activities handling this intent, if you support multiple
278 * {@link AutomaticZenRule rules}. In order for the system to properly display all of your
279 * rule types so that users can create new instances or configure existing ones, you need
280 * to add some extra metadata ({@link #META_DATA_AUTOMATIC_RULE_TYPE})
281 * to your activity tag in your manifest. If you'd like to limit the number of rules a user
282 * can create from this flow, you can additionally optionally include
283 * {@link #META_DATA_RULE_INSTANCE_LIMIT}.
284 *
285 * For example,
286 * &lt;meta-data
287 * android:name="android.app.zen.automatic.ruleType"
288 * android:value="@string/my_condition_rule">
289 * &lt;/meta-data>
290 * &lt;meta-data
291 * android:name="android.app.zen.automatic.ruleInstanceLimit"
292 * android:value="1">
293 * &lt;/meta-data>
294 * </p>
295 * </p>
296 *
297 * @see {@link #addAutomaticZenRule(AutomaticZenRule)}
298 */
299 @SdkConstant(SdkConstant.SdkConstantType.ACTIVITY_INTENT_ACTION)
300 public static final String ACTION_AUTOMATIC_ZEN_RULE =
301 "android.app.action.AUTOMATIC_ZEN_RULE";
302
303 /**
304 * Used as an optional string extra on {@link #ACTION_AUTOMATIC_ZEN_RULE} intents. If
305 * provided, contains the id of the {@link AutomaticZenRule} (as returned from
306 * {@link NotificationManager#addAutomaticZenRule(AutomaticZenRule)}) for which configuration
307 * settings should be displayed.
308 */
309 public static final String EXTRA_AUTOMATIC_RULE_ID = "android.app.extra.AUTOMATIC_RULE_ID";
310
311 /**
312 * A required {@code meta-data} tag for activities that handle
313 * {@link #ACTION_AUTOMATIC_ZEN_RULE}.
314 *
315 * This tag should contain a localized name of the type of the zen rule provided by the
316 * activity.
317 */
Julia Reynolds395bf7052019-03-21 11:41:17 -0400318 public static final String META_DATA_AUTOMATIC_RULE_TYPE =
319 "android.service.zen.automatic.ruleType";
Julia Reynolds68062072018-08-06 15:38:21 -0400320
321 /**
322 * An optional {@code meta-data} tag for activities that handle
323 * {@link #ACTION_AUTOMATIC_ZEN_RULE}.
324 *
325 * This tag should contain the maximum number of rule instances that
326 * can be created for this rule type. Omit or enter a value <= 0 to allow unlimited instances.
327 */
328 public static final String META_DATA_RULE_INSTANCE_LIMIT =
Julia Reynolds395bf7052019-03-21 11:41:17 -0400329 "android.service.zen.automatic.ruleInstanceLimit";
Julia Reynolds68062072018-08-06 15:38:21 -0400330
Chris Wren5ab5c742016-05-10 15:32:23 -0400331 /** Value signifying that the user has not expressed a per-app visibility override value.
332 * @hide */
333 public static final int VISIBILITY_NO_OVERRIDE = -1000;
Julia Reynolds85769912016-10-25 09:08:57 -0400334
Chris Wren5ab5c742016-05-10 15:32:23 -0400335 /**
336 * Value signifying that the user has not expressed an importance.
337 *
338 * This value is for persisting preferences, and should never be associated with
339 * an actual notification.
340 */
341 public static final int IMPORTANCE_UNSPECIFIED = -1000;
342
343 /**
Julia Reynoldsbaff4002016-12-15 11:34:26 -0500344 * A notification with no importance: does not show in the shade.
Chris Wren5ab5c742016-05-10 15:32:23 -0400345 */
346 public static final int IMPORTANCE_NONE = 0;
347
348 /**
Dianne Hackborn6e5bd3f2017-07-31 14:22:04 -0700349 * Min notification importance: only shows in the shade, below the fold. This should
350 * not be used with {@link Service#startForeground(int, Notification) Service.startForeground}
351 * since a foreground service is supposed to be something the user cares about so it does
352 * not make semantic sense to mark its notification as minimum importance. If you do this
353 * as of Android version {@link android.os.Build.VERSION_CODES#O}, the system will show
354 * a higher-priority notification about your app running in the background.
Chris Wren5ab5c742016-05-10 15:32:23 -0400355 */
356 public static final int IMPORTANCE_MIN = 1;
357
358 /**
Julia Reynolds12ad7ca2019-01-28 09:29:16 -0500359 * Low notification importance: Shows in the shade, and potentially in the status bar
360 * (see {@link #shouldHideSilentStatusBarIcons()}), but is not audibly intrusive.
Chris Wren5ab5c742016-05-10 15:32:23 -0400361 */
362 public static final int IMPORTANCE_LOW = 2;
363
364 /**
Julia Reynolds85769912016-10-25 09:08:57 -0400365 * Default notification importance: shows everywhere, makes noise, but does not visually
366 * intrude.
Chris Wren5ab5c742016-05-10 15:32:23 -0400367 */
368 public static final int IMPORTANCE_DEFAULT = 3;
369
370 /**
Julia Reynolds85769912016-10-25 09:08:57 -0400371 * Higher notification importance: shows everywhere, makes noise and peeks. May use full screen
372 * intents.
Chris Wren5ab5c742016-05-10 15:32:23 -0400373 */
374 public static final int IMPORTANCE_HIGH = 4;
375
376 /**
Julia Reynolds85769912016-10-25 09:08:57 -0400377 * Unused.
Chris Wren5ab5c742016-05-10 15:32:23 -0400378 */
379 public static final int IMPORTANCE_MAX = 5;
380
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100381 @UnsupportedAppUsage
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800382 private static INotificationManager sService;
383
Dianne Hackbornd8a43f62009-08-17 23:33:56 -0700384 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100385 @UnsupportedAppUsage
Dianne Hackbornd8a43f62009-08-17 23:33:56 -0700386 static public INotificationManager getService()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800387 {
388 if (sService != null) {
389 return sService;
390 }
391 IBinder b = ServiceManager.getService("notification");
392 sService = INotificationManager.Stub.asInterface(b);
393 return sService;
394 }
395
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100396 @UnsupportedAppUsage
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800397 /*package*/ NotificationManager(Context context, Handler handler)
398 {
399 mContext = context;
400 }
401
Jeff Sharkey69ddab42012-08-25 00:05:46 -0700402 /** {@hide} */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100403 @UnsupportedAppUsage
Jeff Sharkey69ddab42012-08-25 00:05:46 -0700404 public static NotificationManager from(Context context) {
405 return (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
406 }
407
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800408 /**
Daniel Sandlere97a3bc2011-02-07 16:47:07 -0500409 * Post a notification to be shown in the status bar. If a notification with
410 * the same id has already been posted by your application and has not yet been canceled, it
411 * will be replaced by the updated information.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800412 *
413 * @param id An identifier for this notification unique within your
414 * application.
Daniel Sandlere97a3bc2011-02-07 16:47:07 -0500415 * @param notification A {@link Notification} object describing what to show the user. Must not
416 * be null.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800417 */
418 public void notify(int id, Notification notification)
419 {
Fred Quintana6ecaff12009-09-25 14:23:13 -0700420 notify(null, id, notification);
421 }
422
423 /**
Julia Reynoldsa7ba45a2018-08-29 09:07:52 -0400424 * Posts a notification to be shown in the status bar. If a notification with
Daniel Sandlere97a3bc2011-02-07 16:47:07 -0500425 * the same tag and id has already been posted by your application and has not yet been
426 * canceled, it will be replaced by the updated information.
Fred Quintana6ecaff12009-09-25 14:23:13 -0700427 *
Julia Reynoldse0d711f2017-09-01 08:50:47 -0400428 * All {@link android.service.notification.NotificationListenerService listener services} will
429 * be granted {@link Intent#FLAG_GRANT_READ_URI_PERMISSION} access to any {@link Uri uris}
430 * provided on this notification or the
431 * {@link NotificationChannel} this notification is posted to using
432 * {@link Context#grantUriPermission(String, Uri, int)}. Permission will be revoked when the
433 * notification is canceled, or you can revoke permissions with
434 * {@link Context#revokeUriPermission(Uri, int)}.
435 *
Peter Collingbourneb97c3492010-10-13 20:04:52 +0100436 * @param tag A string identifier for this notification. May be {@code null}.
437 * @param id An identifier for this notification. The pair (tag, id) must be unique
438 * within your application.
Daniel Sandlere97a3bc2011-02-07 16:47:07 -0500439 * @param notification A {@link Notification} object describing what to
440 * show the user. Must not be null.
Fred Quintana6ecaff12009-09-25 14:23:13 -0700441 */
442 public void notify(String tag, int id, Notification notification)
443 {
Jeff Sharkeyad357d12018-02-02 13:25:31 -0700444 notifyAsUser(tag, id, notification, mContext.getUser());
Dianne Hackborn41203752012-08-31 14:05:51 -0700445 }
446
447 /**
Julia Reynoldsa7ba45a2018-08-29 09:07:52 -0400448 * Posts a notification as a specified package to be shown in the status bar. If a notification
449 * with the same tag and id has already been posted for that package and has not yet been
450 * canceled, it will be replaced by the updated information.
451 *
452 * All {@link android.service.notification.NotificationListenerService listener services} will
453 * be granted {@link Intent#FLAG_GRANT_READ_URI_PERMISSION} access to any {@link Uri uris}
454 * provided on this notification or the
455 * {@link NotificationChannel} this notification is posted to using
456 * {@link Context#grantUriPermission(String, Uri, int)}. Permission will be revoked when the
457 * notification is canceled, or you can revoke permissions with
458 * {@link Context#revokeUriPermission(Uri, int)}.
459 *
460 * @param targetPackage The package to post the notification as. The package must have granted
461 * you access to post notifications on their behalf with
462 * {@link #setNotificationDelegate(String)}.
463 * @param tag A string identifier for this notification. May be {@code null}.
464 * @param id An identifier for this notification. The pair (tag, id) must be unique
465 * within your application.
466 * @param notification A {@link Notification} object describing what to
467 * show the user. Must not be null.
468 */
469 public void notifyAsPackage(@NonNull String targetPackage, @NonNull String tag, int id,
Fabian Kozynski867550e2019-02-28 12:59:57 -0500470 @NonNull Notification notification) {
Julia Reynoldsa7ba45a2018-08-29 09:07:52 -0400471 INotificationManager service = getService();
472 String sender = mContext.getPackageName();
473
474 try {
475 if (localLOGV) Log.v(TAG, sender + ": notify(" + id + ", " + notification + ")");
476 service.enqueueNotificationWithTag(targetPackage, sender, tag, id,
477 fixNotification(notification), mContext.getUser().getIdentifier());
478 } catch (RemoteException e) {
479 throw e.rethrowFromSystemServer();
480 }
481 }
482
483 /**
Dianne Hackborn41203752012-08-31 14:05:51 -0700484 * @hide
485 */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100486 @UnsupportedAppUsage
Dianne Hackborn41203752012-08-31 14:05:51 -0700487 public void notifyAsUser(String tag, int id, Notification notification, UserHandle user)
488 {
Dianne Hackborn41203752012-08-31 14:05:51 -0700489 INotificationManager service = getService();
490 String pkg = mContext.getPackageName();
Julia Reynoldsa7ba45a2018-08-29 09:07:52 -0400491
492 try {
493 if (localLOGV) Log.v(TAG, pkg + ": notify(" + id + ", " + notification + ")");
494 service.enqueueNotificationWithTag(pkg, mContext.getOpPackageName(), tag, id,
495 fixNotification(notification), user.getIdentifier());
496 } catch (RemoteException e) {
497 throw e.rethrowFromSystemServer();
498 }
499 }
500
501 private Notification fixNotification(Notification notification) {
502 String pkg = mContext.getPackageName();
Julia Reynoldsda303542015-11-23 14:00:20 -0500503 // Fix the notification as best we can.
504 Notification.addFieldsFromContext(mContext, notification);
Julia Reynoldse0d711f2017-09-01 08:50:47 -0400505
Jeff Sharkey65c4a2b2012-09-25 17:22:27 -0700506 if (notification.sound != null) {
507 notification.sound = notification.sound.getCanonicalUri();
Jeff Sharkeya14acd22013-04-02 18:27:45 -0700508 if (StrictMode.vmFileUriExposureEnabled()) {
Jeff Sharkeyac3be9a2016-02-01 10:39:30 -0700509 notification.sound.checkFileUriExposed("Notification.sound");
Jeff Sharkeya14acd22013-04-02 18:27:45 -0700510 }
Julia Reynoldse0d711f2017-09-01 08:50:47 -0400511
Jeff Sharkey65c4a2b2012-09-25 17:22:27 -0700512 }
Dan Sandlerd63f9322015-05-06 15:18:49 -0400513 fixLegacySmallIcon(notification, pkg);
Julia Reynoldsd9228f12015-10-20 10:37:27 -0400514 if (mContext.getApplicationInfo().targetSdkVersion > Build.VERSION_CODES.LOLLIPOP_MR1) {
515 if (notification.getSmallIcon() == null) {
516 throw new IllegalArgumentException("Invalid notification (no valid small icon): "
517 + notification);
518 }
519 }
Julia Reynoldsa7ba45a2018-08-29 09:07:52 -0400520
Selim Cinekd0426622017-07-11 13:19:59 +0200521 notification.reduceImageSizes(mContext);
Julia Reynoldse0d711f2017-09-01 08:50:47 -0400522
Julia Reynolds8a3b4592017-06-26 17:15:14 -0400523 ActivityManager am = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
524 boolean isLowRam = am.isLowRamDevice();
Julia Reynoldsa7ba45a2018-08-29 09:07:52 -0400525 return Builder.maybeCloneStrippedForDelivery(notification, isLowRam, mContext);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800526 }
527
Dan Sandlerd63f9322015-05-06 15:18:49 -0400528 private void fixLegacySmallIcon(Notification n, String pkg) {
529 if (n.getSmallIcon() == null && n.icon != 0) {
530 n.setSmallIcon(Icon.createWithResource(pkg, n.icon));
531 }
532 }
533
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800534 /**
535 * Cancel a previously shown notification. If it's transient, the view
536 * will be hidden. If it's persistent, it will be removed from the status
537 * bar.
538 */
539 public void cancel(int id)
540 {
Fred Quintana6ecaff12009-09-25 14:23:13 -0700541 cancel(null, id);
542 }
543
544 /**
545 * Cancel a previously shown notification. If it's transient, the view
546 * will be hidden. If it's persistent, it will be removed from the status
547 * bar.
548 */
549 public void cancel(String tag, int id)
550 {
Jeff Sharkeyad357d12018-02-02 13:25:31 -0700551 cancelAsUser(tag, id, mContext.getUser());
Dianne Hackborn41203752012-08-31 14:05:51 -0700552 }
553
554 /**
555 * @hide
556 */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100557 @UnsupportedAppUsage
Dianne Hackborn41203752012-08-31 14:05:51 -0700558 public void cancelAsUser(String tag, int id, UserHandle user)
559 {
560 INotificationManager service = getService();
561 String pkg = mContext.getPackageName();
562 if (localLOGV) Log.v(TAG, pkg + ": cancel(" + id + ")");
563 try {
564 service.cancelNotificationWithTag(pkg, tag, id, user.getIdentifier());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800565 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -0700566 throw e.rethrowFromSystemServer();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800567 }
568 }
569
570 /**
571 * Cancel all previously shown notifications. See {@link #cancel} for the
572 * detailed behavior.
573 */
574 public void cancelAll()
575 {
576 INotificationManager service = getService();
577 String pkg = mContext.getPackageName();
578 if (localLOGV) Log.v(TAG, pkg + ": cancelAll()");
579 try {
Jeff Sharkeyad357d12018-02-02 13:25:31 -0700580 service.cancelAllNotifications(pkg, mContext.getUserId());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800581 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -0700582 throw e.rethrowFromSystemServer();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800583 }
584 }
585
John Spurlockb4782522014-08-22 14:54:46 -0400586 /**
Julia Reynoldsa7ba45a2018-08-29 09:07:52 -0400587 * Allows a package to post notifications on your behalf using
588 * {@link #notifyAsPackage(String, String, int, Notification)}.
589 *
590 * This can be used to allow persistent processes to post notifications based on messages
591 * received on your behalf from the cloud, without your process having to wake up.
592 *
593 * You can check if you have an allowed delegate with {@link #getNotificationDelegate()} and
Julia Reynoldscbc45e72019-03-07 12:31:52 -0500594 * revoke your delegate by passing null to this method.
Julia Reynoldsa7ba45a2018-08-29 09:07:52 -0400595 *
596 * @param delegate Package name of the app which can send notifications on your behalf.
597 */
Julia Reynoldscbc45e72019-03-07 12:31:52 -0500598 public void setNotificationDelegate(@Nullable String delegate) {
Julia Reynoldsa7ba45a2018-08-29 09:07:52 -0400599 INotificationManager service = getService();
600 String pkg = mContext.getPackageName();
601 if (localLOGV) Log.v(TAG, pkg + ": cancelAll()");
602 try {
603 service.setNotificationDelegate(pkg, delegate);
604 } catch (RemoteException e) {
605 throw e.rethrowFromSystemServer();
606 }
607 }
608
609 /**
Julia Reynoldsa7ba45a2018-08-29 09:07:52 -0400610 * Returns the {@link #setNotificationDelegate(String) delegate} that can post notifications on
611 * your behalf, if there currently is one.
612 */
613 public @Nullable String getNotificationDelegate() {
614 INotificationManager service = getService();
615 String pkg = mContext.getPackageName();
616 try {
617 return service.getNotificationDelegate(pkg);
618 } catch (RemoteException e) {
619 throw e.rethrowFromSystemServer();
620 }
621 }
622
623 /**
624 * Returns whether you are allowed to post notifications on behalf of a given package, with
625 * {@link #notifyAsPackage(String, String, int, Notification)}.
626 *
627 * See {@link #setNotificationDelegate(String)}.
628 */
Fabian Kozynski867550e2019-02-28 12:59:57 -0500629 public boolean canNotifyAsPackage(@NonNull String pkg) {
Julia Reynoldsa7ba45a2018-08-29 09:07:52 -0400630 INotificationManager service = getService();
631 try {
Julia Reynolds7a6d07a2019-03-18 11:31:56 -0400632 return service.canNotifyAsPackage(mContext.getPackageName(), pkg, mContext.getUserId());
Julia Reynoldsa7ba45a2018-08-29 09:07:52 -0400633 } catch (RemoteException e) {
634 throw e.rethrowFromSystemServer();
635 }
636 }
637
638 /**
Julia Reynolds59e152e2017-01-25 17:42:53 -0500639 * Creates a group container for {@link NotificationChannel} objects.
640 *
Julia Reynolds1d97e6a2017-03-13 15:05:40 -0400641 * This can be used to rename an existing group.
Julia Reynolds59e152e2017-01-25 17:42:53 -0500642 * <p>
643 * Group information is only used for presentation, not for behavior. Groups are optional
644 * for channels, and you can have a mix of channels that belong to groups and channels
645 * that do not.
646 * </p>
647 * <p>
648 * For example, if your application supports multiple accounts, and those accounts will
649 * have similar channels, you can create a group for each account with account specific
650 * labels instead of appending account information to each channel's label.
651 * </p>
652 *
653 * @param group The group to create
654 */
655 public void createNotificationChannelGroup(@NonNull NotificationChannelGroup group) {
656 createNotificationChannelGroups(Arrays.asList(group));
657 }
658
659 /**
660 * Creates multiple notification channel groups.
661 *
662 * @param groups The list of groups to create
663 */
664 public void createNotificationChannelGroups(@NonNull List<NotificationChannelGroup> groups) {
665 INotificationManager service = getService();
666 try {
667 service.createNotificationChannelGroups(mContext.getPackageName(),
668 new ParceledListSlice(groups));
669 } catch (RemoteException e) {
670 throw e.rethrowFromSystemServer();
671 }
672 }
673
674 /**
Geoffrey Pitsch03533712017-01-05 10:30:07 -0500675 * Creates a notification channel that notifications can be posted to.
676 *
Julia Reynolds2c891c92017-03-17 14:23:47 -0400677 * This can also be used to restore a deleted channel and to update an existing channel's
Julia Reynolds005c8b92017-08-24 10:35:53 -0400678 * name, description, group, and/or importance.
Julia Reynolds0ffc13b2017-04-27 13:54:36 -0400679 *
680 * <p>The name and description should only be changed if the locale changes
Julia Reynolds2c891c92017-03-17 14:23:47 -0400681 * or in response to the user renaming this channel. For example, if a user has a channel
682 * named 'John Doe' that represents messages from a 'John Doe', and 'John Doe' changes his name
683 * to 'John Smith,' the channel can be renamed to match.
Geoffrey Pitsch07532c32017-07-18 11:44:06 -0400684 *
685 * <p>The importance of an existing channel will only be changed if the new importance is lower
686 * than the current value and the user has not altered any settings on this channel.
687 *
Julia Reynolds005c8b92017-08-24 10:35:53 -0400688 * <p>The group an existing channel will only be changed if the channel does not already
689 * belong to a group.
690 *
Julia Reynolds2c891c92017-03-17 14:23:47 -0400691 * All other fields are ignored for channels that already exist.
Julia Reynolds59e152e2017-01-25 17:42:53 -0500692 *
Geoffrey Pitsch03533712017-01-05 10:30:07 -0500693 * @param channel the channel to create. Note that the created channel may differ from this
Julia Reynoldse8665332017-03-13 13:00:41 -0400694 * value. If the provided channel is malformed, a RemoteException will be
Julia Reynolds1d97e6a2017-03-13 15:05:40 -0400695 * thrown.
Julia Reynoldsb5e44b72016-08-16 15:00:25 -0400696 */
Geoffrey Pitsch03533712017-01-05 10:30:07 -0500697 public void createNotificationChannel(@NonNull NotificationChannel channel) {
698 createNotificationChannels(Arrays.asList(channel));
Geoffrey Pitsche75a66e2016-11-22 11:12:11 -0500699 }
700
701 /**
Julia Reynolds1d97e6a2017-03-13 15:05:40 -0400702 * Creates multiple notification channels that different notifications can be posted to. See
703 * {@link #createNotificationChannel(NotificationChannel)}.
Geoffrey Pitsche75a66e2016-11-22 11:12:11 -0500704 *
Julia Reynolds1d97e6a2017-03-13 15:05:40 -0400705 * @param channels the list of channels to attempt to create.
Geoffrey Pitsche75a66e2016-11-22 11:12:11 -0500706 */
Geoffrey Pitsch03533712017-01-05 10:30:07 -0500707 public void createNotificationChannels(@NonNull List<NotificationChannel> channels) {
Julia Reynoldsb5e44b72016-08-16 15:00:25 -0400708 INotificationManager service = getService();
709 try {
Geoffrey Pitsch03533712017-01-05 10:30:07 -0500710 service.createNotificationChannels(mContext.getPackageName(),
711 new ParceledListSlice(channels));
Julia Reynoldsb5e44b72016-08-16 15:00:25 -0400712 } catch (RemoteException e) {
713 throw e.rethrowFromSystemServer();
714 }
715 }
716
717 /**
718 * Returns the notification channel settings for a given channel id.
Julia Reynolds0ffc13b2017-04-27 13:54:36 -0400719 *
Julia Reynoldsb4a9e9c2019-03-20 15:46:08 -0400720 * <p>The channel must belong to your package, or to a package you are an approved notification
721 * delegate for (see {@link #canNotifyAsPackage(String)}), or it will not be returned. To query
722 * a channel as a notification delegate, call this method from a context created for that
723 * package (see {@link Context#createPackageContext(String, int)}).</p>
Julia Reynoldsb5e44b72016-08-16 15:00:25 -0400724 */
725 public NotificationChannel getNotificationChannel(String channelId) {
726 INotificationManager service = getService();
727 try {
Julia Reynoldsb4a9e9c2019-03-20 15:46:08 -0400728 return service.getNotificationChannel(mContext.getOpPackageName(),
729 mContext.getUserId(), mContext.getPackageName(), channelId);
Julia Reynoldsb5e44b72016-08-16 15:00:25 -0400730 } catch (RemoteException e) {
731 throw e.rethrowFromSystemServer();
732 }
733 }
734
735 /**
Julia Reynolds0ffc13b2017-04-27 13:54:36 -0400736 * Returns all notification channels belonging to the calling package.
Julia Reynoldsb4a9e9c2019-03-20 15:46:08 -0400737 *
738 * <p>Approved notification delegates (see {@link #canNotifyAsPackage(String)}) can query
739 * notification channels belonging to packages they are the delegate for. To do so, call this
740 * method from a context created for that package (see
741 * {@link Context#createPackageContext(String, int)}).</p>
Julia Reynoldsb5e44b72016-08-16 15:00:25 -0400742 */
743 public List<NotificationChannel> getNotificationChannels() {
744 INotificationManager service = getService();
745 try {
Julia Reynoldsb4a9e9c2019-03-20 15:46:08 -0400746 return service.getNotificationChannels(mContext.getOpPackageName(),
747 mContext.getPackageName(), mContext.getUserId()).getList();
Julia Reynoldsb5e44b72016-08-16 15:00:25 -0400748 } catch (RemoteException e) {
749 throw e.rethrowFromSystemServer();
750 }
751 }
752
753 /**
Julia Reynoldsb5e44b72016-08-16 15:00:25 -0400754 * Deletes the given notification channel.
Julia Reynolds0ffc13b2017-04-27 13:54:36 -0400755 *
756 * <p>If you {@link #createNotificationChannel(NotificationChannel) create} a new channel with
757 * this same id, the deleted channel will be un-deleted with all of the same settings it
758 * had before it was deleted.
Julia Reynoldsb5e44b72016-08-16 15:00:25 -0400759 */
760 public void deleteNotificationChannel(String channelId) {
761 INotificationManager service = getService();
762 try {
763 service.deleteNotificationChannel(mContext.getPackageName(), channelId);
764 } catch (RemoteException e) {
765 throw e.rethrowFromSystemServer();
766 }
767 }
768
769 /**
Julia Reynolds3eb3ffd2017-11-16 10:11:32 -0500770 * Returns the notification channel group settings for a given channel group id.
771 *
772 * The channel group must belong to your package, or null will be returned.
773 */
774 public NotificationChannelGroup getNotificationChannelGroup(String channelGroupId) {
775 INotificationManager service = getService();
776 try {
777 return service.getNotificationChannelGroup(mContext.getPackageName(), channelGroupId);
778 } catch (RemoteException e) {
779 throw e.rethrowFromSystemServer();
780 }
781 }
782
783 /**
Julia Reynolds9bfba592017-03-15 14:03:55 -0400784 * Returns all notification channel groups belonging to the calling app.
785 */
786 public List<NotificationChannelGroup> getNotificationChannelGroups() {
787 INotificationManager service = getService();
788 try {
Beverlyc629ee42018-10-02 16:14:07 -0400789 final ParceledListSlice<NotificationChannelGroup> parceledList =
790 service.getNotificationChannelGroups(mContext.getPackageName());
791 if (parceledList != null) {
792 return parceledList.getList();
793 }
Julia Reynolds9bfba592017-03-15 14:03:55 -0400794 } catch (RemoteException e) {
795 throw e.rethrowFromSystemServer();
796 }
Beverlyc629ee42018-10-02 16:14:07 -0400797 return new ArrayList<>();
Julia Reynolds9bfba592017-03-15 14:03:55 -0400798 }
799
800 /**
Julia Reynolds0ffc13b2017-04-27 13:54:36 -0400801 * Deletes the given notification channel group, and all notification channels that
802 * belong to it.
Julia Reynolds9bfba592017-03-15 14:03:55 -0400803 */
804 public void deleteNotificationChannelGroup(String groupId) {
805 INotificationManager service = getService();
806 try {
807 service.deleteNotificationChannelGroup(mContext.getPackageName(), groupId);
808 } catch (RemoteException e) {
809 throw e.rethrowFromSystemServer();
810 }
811 }
812
813 /**
John Spurlockb4782522014-08-22 14:54:46 -0400814 * @hide
815 */
Julia Reynoldsb6c1f992016-11-22 09:26:46 -0500816 @TestApi
John Spurlockb4782522014-08-22 14:54:46 -0400817 public ComponentName getEffectsSuppressor() {
818 INotificationManager service = getService();
819 try {
820 return service.getEffectsSuppressor();
821 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -0700822 throw e.rethrowFromSystemServer();
John Spurlockb4782522014-08-22 14:54:46 -0400823 }
824 }
825
John Spurlock2b122f42014-08-27 16:29:47 -0400826 /**
827 * @hide
828 */
Julia Reynolds87621942019-01-29 16:19:36 -0500829 @TestApi
John Spurlock2b122f42014-08-27 16:29:47 -0400830 public boolean matchesCallFilter(Bundle extras) {
831 INotificationManager service = getService();
832 try {
833 return service.matchesCallFilter(extras);
834 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -0700835 throw e.rethrowFromSystemServer();
John Spurlock2b122f42014-08-27 16:29:47 -0400836 }
837 }
838
John Spurlock530052a2014-11-30 16:26:19 -0500839 /**
840 * @hide
841 */
842 public boolean isSystemConditionProviderEnabled(String path) {
843 INotificationManager service = getService();
844 try {
845 return service.isSystemConditionProviderEnabled(path);
846 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -0700847 throw e.rethrowFromSystemServer();
John Spurlock530052a2014-11-30 16:26:19 -0500848 }
849 }
850
John Spurlockcdb57ae2015-02-11 19:04:11 -0500851 /**
852 * @hide
853 */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100854 @UnsupportedAppUsage
John Spurlockb2278d62015-04-07 12:47:12 -0400855 public void setZenMode(int mode, Uri conditionId, String reason) {
John Spurlockcdb57ae2015-02-11 19:04:11 -0500856 INotificationManager service = getService();
857 try {
John Spurlockb2278d62015-04-07 12:47:12 -0400858 service.setZenMode(mode, conditionId, reason);
John Spurlockcdb57ae2015-02-11 19:04:11 -0500859 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -0700860 throw e.rethrowFromSystemServer();
John Spurlockcdb57ae2015-02-11 19:04:11 -0500861 }
862 }
863
864 /**
865 * @hide
866 */
John Spurlockb2278d62015-04-07 12:47:12 -0400867 public int getZenMode() {
John Spurlockcdb57ae2015-02-11 19:04:11 -0500868 INotificationManager service = getService();
869 try {
John Spurlockb2278d62015-04-07 12:47:12 -0400870 return service.getZenMode();
John Spurlockcdb57ae2015-02-11 19:04:11 -0500871 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -0700872 throw e.rethrowFromSystemServer();
John Spurlockcdb57ae2015-02-11 19:04:11 -0500873 }
874 }
875
876 /**
877 * @hide
878 */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100879 @UnsupportedAppUsage
John Spurlockb2278d62015-04-07 12:47:12 -0400880 public ZenModeConfig getZenModeConfig() {
John Spurlockcdb57ae2015-02-11 19:04:11 -0500881 INotificationManager service = getService();
882 try {
John Spurlockb2278d62015-04-07 12:47:12 -0400883 return service.getZenModeConfig();
John Spurlockcdb57ae2015-02-11 19:04:11 -0500884 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -0700885 throw e.rethrowFromSystemServer();
John Spurlockcdb57ae2015-02-11 19:04:11 -0500886 }
John Spurlockcdb57ae2015-02-11 19:04:11 -0500887 }
888
John Spurlock1fc476d2015-04-14 16:05:20 -0400889 /**
Julia Reynolds43b70cd2016-01-14 15:05:34 -0500890 * @hide
891 */
Beverlyff2df9b2018-10-10 16:54:10 -0400892 public NotificationManager.Policy getConsolidatedNotificationPolicy() {
893 INotificationManager service = getService();
894 try {
895 return service.getConsolidatedNotificationPolicy();
896 } catch (RemoteException e) {
897 throw e.rethrowFromSystemServer();
898 }
899 }
900
901 /**
902 * @hide
903 */
Julia Reynolds43b70cd2016-01-14 15:05:34 -0500904 public int getRuleInstanceCount(ComponentName owner) {
905 INotificationManager service = getService();
906 try {
907 return service.getRuleInstanceCount(owner);
908 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -0700909 throw e.rethrowFromSystemServer();
Julia Reynolds43b70cd2016-01-14 15:05:34 -0500910 }
Julia Reynolds43b70cd2016-01-14 15:05:34 -0500911 }
912
913 /**
Julia Reynoldsa47a27f2015-08-24 08:31:47 -0400914 * Returns AutomaticZenRules owned by the caller.
915 *
916 * <p>
Julia Reynolds361e82d32016-02-26 18:19:49 -0500917 * Throws a SecurityException if policy access is granted to this package.
Julia Reynoldsa47a27f2015-08-24 08:31:47 -0400918 * See {@link #isNotificationPolicyAccessGranted}.
919 */
Julia Reynolds361e82d32016-02-26 18:19:49 -0500920 public Map<String, AutomaticZenRule> getAutomaticZenRules() {
Julia Reynoldsa47a27f2015-08-24 08:31:47 -0400921 INotificationManager service = getService();
922 try {
Julia Reynolds361e82d32016-02-26 18:19:49 -0500923 List<ZenModeConfig.ZenRule> rules = service.getZenRules();
924 Map<String, AutomaticZenRule> ruleMap = new HashMap<>();
925 for (ZenModeConfig.ZenRule rule : rules) {
Julia Reynolds68062072018-08-06 15:38:21 -0400926 ruleMap.put(rule.id, new AutomaticZenRule(rule.name, rule.component,
927 rule.configurationActivity, rule.conditionId, rule.zenPolicy,
928 zenModeToInterruptionFilter(rule.zenMode), rule.enabled,
929 rule.creationTime));
Julia Reynolds361e82d32016-02-26 18:19:49 -0500930 }
931 return ruleMap;
Julia Reynoldsa47a27f2015-08-24 08:31:47 -0400932 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -0700933 throw e.rethrowFromSystemServer();
Julia Reynoldsa47a27f2015-08-24 08:31:47 -0400934 }
Julia Reynoldsa47a27f2015-08-24 08:31:47 -0400935 }
936
937 /**
Julia Reynolds4fe98d62015-10-06 16:23:41 -0400938 * Returns the AutomaticZenRule with the given id, if it exists and the caller has access.
Julia Reynoldsa47a27f2015-08-24 08:31:47 -0400939 *
940 * <p>
Julia Reynolds361e82d32016-02-26 18:19:49 -0500941 * Throws a SecurityException if policy access is granted to this package.
Julia Reynoldsa47a27f2015-08-24 08:31:47 -0400942 * See {@link #isNotificationPolicyAccessGranted}.
943 *
944 * <p>
Julia Reynolds4fe98d62015-10-06 16:23:41 -0400945 * 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 -0400946 * doesn't own the matching rule. See {@link AutomaticZenRule#getOwner}.
947 */
Julia Reynolds4fe98d62015-10-06 16:23:41 -0400948 public AutomaticZenRule getAutomaticZenRule(String id) {
Julia Reynoldsa47a27f2015-08-24 08:31:47 -0400949 INotificationManager service = getService();
950 try {
Julia Reynolds4fe98d62015-10-06 16:23:41 -0400951 return service.getAutomaticZenRule(id);
Julia Reynoldsa47a27f2015-08-24 08:31:47 -0400952 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -0700953 throw e.rethrowFromSystemServer();
Julia Reynoldsa47a27f2015-08-24 08:31:47 -0400954 }
Julia Reynoldsa47a27f2015-08-24 08:31:47 -0400955 }
956
957 /**
Julia Reynolds4fe98d62015-10-06 16:23:41 -0400958 * Creates the given zen rule.
Julia Reynoldsa47a27f2015-08-24 08:31:47 -0400959 *
960 * <p>
Julia Reynolds361e82d32016-02-26 18:19:49 -0500961 * Throws a SecurityException if policy access is granted to this package.
Julia Reynoldsa47a27f2015-08-24 08:31:47 -0400962 * See {@link #isNotificationPolicyAccessGranted}.
963 *
Julia Reynolds4fe98d62015-10-06 16:23:41 -0400964 * @param automaticZenRule the rule to create.
Julia Reynolds361e82d32016-02-26 18:19:49 -0500965 * @return The id of the newly created rule; null if the rule could not be created.
Julia Reynoldsa47a27f2015-08-24 08:31:47 -0400966 */
Julia Reynolds361e82d32016-02-26 18:19:49 -0500967 public String addAutomaticZenRule(AutomaticZenRule automaticZenRule) {
Julia Reynoldsa47a27f2015-08-24 08:31:47 -0400968 INotificationManager service = getService();
969 try {
Julia Reynolds4fe98d62015-10-06 16:23:41 -0400970 return service.addAutomaticZenRule(automaticZenRule);
Julia Reynoldsa47a27f2015-08-24 08:31:47 -0400971 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -0700972 throw e.rethrowFromSystemServer();
Julia Reynoldsa47a27f2015-08-24 08:31:47 -0400973 }
Julia Reynoldsa47a27f2015-08-24 08:31:47 -0400974 }
975
976 /**
Julia Reynolds4fe98d62015-10-06 16:23:41 -0400977 * Updates the given zen rule.
Julia Reynoldsa47a27f2015-08-24 08:31:47 -0400978 *
979 * <p>
Julia Reynolds361e82d32016-02-26 18:19:49 -0500980 * Throws a SecurityException if policy access is granted to this package.
Julia Reynoldsa47a27f2015-08-24 08:31:47 -0400981 * See {@link #isNotificationPolicyAccessGranted}.
982 *
983 * <p>
984 * Callers can only update rules that they own. See {@link AutomaticZenRule#getOwner}.
Julia Reynolds361e82d32016-02-26 18:19:49 -0500985 * @param id The id of the rule to update
Geoffrey Pitsche75a66e2016-11-22 11:12:11 -0500986 * @param automaticZenRule the rule to update.
Julia Reynoldsa47a27f2015-08-24 08:31:47 -0400987 * @return Whether the rule was successfully updated.
988 */
Julia Reynolds361e82d32016-02-26 18:19:49 -0500989 public boolean updateAutomaticZenRule(String id, AutomaticZenRule automaticZenRule) {
Julia Reynoldsa47a27f2015-08-24 08:31:47 -0400990 INotificationManager service = getService();
991 try {
Julia Reynolds361e82d32016-02-26 18:19:49 -0500992 return service.updateAutomaticZenRule(id, automaticZenRule);
Julia Reynoldsa47a27f2015-08-24 08:31:47 -0400993 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -0700994 throw e.rethrowFromSystemServer();
Julia Reynoldsa47a27f2015-08-24 08:31:47 -0400995 }
Julia Reynoldsa47a27f2015-08-24 08:31:47 -0400996 }
997
998 /**
Julia Reynolds68062072018-08-06 15:38:21 -0400999 * Informs the notification manager that the state of an {@link AutomaticZenRule} has changed.
1000 * Use this method to put the system into Do Not Disturb mode or request that it exits Do Not
1001 * Disturb mode. The calling app must own the provided {@link android.app.AutomaticZenRule}.
1002 * <p>
1003 * This method can be used in conjunction with or as a replacement to
1004 * {@link android.service.notification.ConditionProviderService#notifyCondition(Condition)}.
1005 * </p>
1006 * @param id The id of the rule whose state should change
1007 * @param condition The new state of this rule
1008 */
Fabian Kozynski867550e2019-02-28 12:59:57 -05001009 public void setAutomaticZenRuleState(@NonNull String id, @NonNull Condition condition) {
Julia Reynolds68062072018-08-06 15:38:21 -04001010 INotificationManager service = getService();
1011 try {
1012 service.setAutomaticZenRuleState(id, condition);
1013 } catch (RemoteException e) {
1014 throw e.rethrowFromSystemServer();
1015 }
1016 }
1017
1018 /**
Julia Reynolds4fe98d62015-10-06 16:23:41 -04001019 * Deletes the automatic zen rule with the given id.
Julia Reynoldsa47a27f2015-08-24 08:31:47 -04001020 *
1021 * <p>
Julia Reynolds361e82d32016-02-26 18:19:49 -05001022 * Throws a SecurityException if policy access is granted to this package.
Julia Reynoldsa47a27f2015-08-24 08:31:47 -04001023 * See {@link #isNotificationPolicyAccessGranted}.
1024 *
1025 * <p>
1026 * Callers can only delete rules that they own. See {@link AutomaticZenRule#getOwner}.
Julia Reynolds4fe98d62015-10-06 16:23:41 -04001027 * @param id the id of the rule to delete.
Julia Reynoldsa47a27f2015-08-24 08:31:47 -04001028 * @return Whether the rule was successfully deleted.
1029 */
Julia Reynolds4fe98d62015-10-06 16:23:41 -04001030 public boolean removeAutomaticZenRule(String id) {
Julia Reynoldsa47a27f2015-08-24 08:31:47 -04001031 INotificationManager service = getService();
1032 try {
Julia Reynolds4fe98d62015-10-06 16:23:41 -04001033 return service.removeAutomaticZenRule(id);
Julia Reynoldsa47a27f2015-08-24 08:31:47 -04001034 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07001035 throw e.rethrowFromSystemServer();
Julia Reynoldsa47a27f2015-08-24 08:31:47 -04001036 }
Julia Reynoldsa47a27f2015-08-24 08:31:47 -04001037 }
1038
1039 /**
Julia Reynoldsc8e54e82015-11-30 16:43:05 -05001040 * Deletes all automatic zen rules owned by the given package.
1041 *
1042 * @hide
1043 */
1044 public boolean removeAutomaticZenRules(String packageName) {
1045 INotificationManager service = getService();
1046 try {
1047 return service.removeAutomaticZenRules(packageName);
1048 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07001049 throw e.rethrowFromSystemServer();
Julia Reynoldsc8e54e82015-11-30 16:43:05 -05001050 }
Julia Reynoldsc8e54e82015-11-30 16:43:05 -05001051 }
1052
Julia Reynolds0edb50c2016-02-26 14:08:25 -05001053 /**
Jeff Sharkey6503bd82017-04-19 23:24:18 -06001054 * Returns the user specified importance for notifications from the calling
1055 * package.
Julia Reynolds0edb50c2016-02-26 14:08:25 -05001056 */
Chris Wren5ab5c742016-05-10 15:32:23 -04001057 public @Importance int getImportance() {
Julia Reynolds81afbcd2016-02-09 14:54:08 -05001058 INotificationManager service = getService();
1059 try {
Julia Reynoldsef37f282016-02-12 09:11:27 -05001060 return service.getPackageImportance(mContext.getPackageName());
Julia Reynolds81afbcd2016-02-09 14:54:08 -05001061 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07001062 throw e.rethrowFromSystemServer();
Julia Reynolds81afbcd2016-02-09 14:54:08 -05001063 }
Julia Reynolds81afbcd2016-02-09 14:54:08 -05001064 }
1065
Julia Reynolds0edb50c2016-02-26 14:08:25 -05001066 /**
1067 * Returns whether notifications from the calling package are blocked.
1068 */
Julia Reynolds81afbcd2016-02-09 14:54:08 -05001069 public boolean areNotificationsEnabled() {
1070 INotificationManager service = getService();
1071 try {
1072 return service.areNotificationsEnabled(mContext.getPackageName());
1073 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07001074 throw e.rethrowFromSystemServer();
Julia Reynolds81afbcd2016-02-09 14:54:08 -05001075 }
Julia Reynolds81afbcd2016-02-09 14:54:08 -05001076 }
1077
Julia Reynolds33ab8a02018-12-17 16:19:52 -05001078
1079 /**
1080 * Sets whether notifications posted by this app can appear outside of the
1081 * notification shade, floating over other apps' content.
1082 *
1083 * <p>This value will be ignored for notifications that are posted to channels that do not
Mady Mellorc39b4ae2019-01-09 17:11:37 -08001084 * allow bubbles ({@link NotificationChannel#canBubble()}.
Julia Reynolds33ab8a02018-12-17 16:19:52 -05001085 *
Mady Mellorc39b4ae2019-01-09 17:11:37 -08001086 * @see Notification#getBubbleMetadata()
Julia Reynolds33ab8a02018-12-17 16:19:52 -05001087 */
Mady Mellorc39b4ae2019-01-09 17:11:37 -08001088 public boolean areBubblesAllowed() {
Julia Reynolds33ab8a02018-12-17 16:19:52 -05001089 INotificationManager service = getService();
1090 try {
Mady Mellorc39b4ae2019-01-09 17:11:37 -08001091 return service.areBubblesAllowed(mContext.getPackageName());
Julia Reynolds33ab8a02018-12-17 16:19:52 -05001092 } catch (RemoteException e) {
1093 throw e.rethrowFromSystemServer();
1094 }
1095 }
1096
Julia Reynoldsc8e54e82015-11-30 16:43:05 -05001097 /**
Julia Reynolds1ceddc42019-06-17 15:34:26 -04001098 * Silences the current notification sound, if ones currently playing.
1099 * <p>
1100 * It is intended to handle use-cases such as silencing a ringing call
1101 * when the user presses the volume button during ringing.
1102 * <p>
1103 * If this method is called prior to when the notification begins playing, the sound will not be
1104 * silenced. As such it is not intended as a means to avoid playing of a sound.
1105 * @hide
1106 */
1107 public void silenceNotificationSound() {
1108 INotificationManager service = getService();
1109 try {
1110 service.silenceNotificationSound();
1111 } catch (RemoteException e) {
1112 throw e.rethrowFromSystemServer();
1113 }
1114 }
1115
1116 /**
Julia Reynoldsb40cd092019-01-25 09:35:02 -05001117 * Returns whether notifications from this package are temporarily hidden. This
1118 * could be done because the package was marked as distracting to the user via
1119 * {@code PackageManager#setDistractingPackageRestrictions(String[], int)} or because the
1120 * package is {@code PackageManager#setPackagesSuspended(String[], boolean, PersistableBundle,
1121 * PersistableBundle, SuspendDialogInfo) suspended}.
1122 */
1123 public boolean areNotificationsPaused() {
1124 INotificationManager service = getService();
1125 try {
1126 return service.isPackagePaused(mContext.getPackageName());
1127 } catch (RemoteException e) {
1128 throw e.rethrowFromSystemServer();
1129 }
1130 }
1131
1132 /**
Beverly312ef3e2017-11-15 11:12:51 -05001133 * Checks the ability to modify notification do not disturb policy for the calling package.
John Spurlock1fc476d2015-04-14 16:05:20 -04001134 *
John Spurlock7c74f782015-06-04 13:01:42 -04001135 * <p>
Beverly312ef3e2017-11-15 11:12:51 -05001136 * Returns true if the calling package can modify notification policy.
John Spurlock7c74f782015-06-04 13:01:42 -04001137 *
1138 * <p>
Julia Reynoldsb852e562017-06-06 16:14:18 -04001139 * Apps can request policy access by sending the user to the activity that matches the system
1140 * intent action {@link android.provider.Settings#ACTION_NOTIFICATION_POLICY_ACCESS_SETTINGS}.
John Spurlock7c74f782015-06-04 13:01:42 -04001141 *
1142 * <p>
1143 * Use {@link #ACTION_NOTIFICATION_POLICY_ACCESS_GRANTED_CHANGED} to listen for
1144 * user grant or denial of this access.
John Spurlock1fc476d2015-04-14 16:05:20 -04001145 */
John Spurlock80774932015-05-07 17:38:50 -04001146 public boolean isNotificationPolicyAccessGranted() {
John Spurlock1fc476d2015-04-14 16:05:20 -04001147 INotificationManager service = getService();
1148 try {
John Spurlock80774932015-05-07 17:38:50 -04001149 return service.isNotificationPolicyAccessGranted(mContext.getOpPackageName());
1150 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07001151 throw e.rethrowFromSystemServer();
John Spurlock80774932015-05-07 17:38:50 -04001152 }
John Spurlock80774932015-05-07 17:38:50 -04001153 }
1154
Julia Reynoldsb852e562017-06-06 16:14:18 -04001155 /**
1156 * Checks whether the user has approved a given
1157 * {@link android.service.notification.NotificationListenerService}.
1158 *
1159 * <p>
1160 * The listener service must belong to the calling app.
1161 *
1162 * <p>
1163 * Apps can request notification listener access by sending the user to the activity that
1164 * matches the system intent action
1165 * {@link android.provider.Settings#ACTION_NOTIFICATION_LISTENER_SETTINGS}.
1166 */
1167 public boolean isNotificationListenerAccessGranted(ComponentName listener) {
1168 INotificationManager service = getService();
1169 try {
1170 return service.isNotificationListenerAccessGranted(listener);
1171 } catch (RemoteException e) {
1172 throw e.rethrowFromSystemServer();
1173 }
1174 }
1175
Fabian Kozynskid9425662019-01-29 13:08:30 -05001176 /**
1177 * Checks whether the user has approved a given
1178 * {@link android.service.notification.NotificationAssistantService}.
1179 *
1180 * <p>
1181 * The assistant service must belong to the calling app.
1182 *
1183 * <p>
1184 * Apps can request notification assistant access by sending the user to the activity that
1185 * matches the system intent action
1186 * TODO: STOPSHIP: Add correct intent
1187 * {@link android.provider.Settings#ACTION_MANAGE_DEFAULT_APPS_SETTINGS}.
Julia Reynoldsd0ceefa2019-03-03 16:10:52 -05001188 * @hide
Fabian Kozynskid9425662019-01-29 13:08:30 -05001189 */
Julia Reynoldsd0ceefa2019-03-03 16:10:52 -05001190 @SystemApi
Julia Reynoldsdc6adc62019-04-08 10:35:40 -04001191 @TestApi
Fabian Kozynski867550e2019-02-28 12:59:57 -05001192 public boolean isNotificationAssistantAccessGranted(@NonNull ComponentName assistant) {
Julia Reynoldsb852e562017-06-06 16:14:18 -04001193 INotificationManager service = getService();
1194 try {
1195 return service.isNotificationAssistantAccessGranted(assistant);
1196 } catch (RemoteException e) {
1197 throw e.rethrowFromSystemServer();
1198 }
1199 }
1200
Julia Reynolds12ad7ca2019-01-28 09:29:16 -05001201 /**
1202 * Returns whether the user wants silent notifications (see {@link #IMPORTANCE_LOW} to appear
1203 * in the status bar.
1204 *
1205 * <p>Only available for {@link #isNotificationListenerAccessGranted(ComponentName) notification
1206 * listeners}.
1207 */
1208 public boolean shouldHideSilentStatusBarIcons() {
1209 INotificationManager service = getService();
1210 try {
1211 return service.shouldHideSilentStatusIcons(mContext.getOpPackageName());
1212 } catch (RemoteException e) {
1213 throw e.rethrowFromSystemServer();
1214 }
1215 }
1216
Julia Reynoldsad6dd352019-03-07 16:46:22 -05001217 /**
1218 * Returns the list of {@link android.service.notification.Adjustment adjustment keys} that can
1219 * be modified by the current {@link android.service.notification.NotificationAssistantService}.
1220 *
1221 * <p>Only callable by the current
1222 * {@link android.service.notification.NotificationAssistantService}.
1223 * See {@link #isNotificationAssistantAccessGranted(ComponentName)}</p>
1224 * @hide
1225 */
1226 @SystemApi
Julia Reynoldsdc6adc62019-04-08 10:35:40 -04001227 @TestApi
Julia Reynolds088c4482019-04-10 12:43:27 -04001228 public @NonNull @Adjustment.Keys List<String> getAllowedAssistantAdjustments() {
Julia Reynoldsad6dd352019-03-07 16:46:22 -05001229 INotificationManager service = getService();
1230 try {
Julia Reynolds088c4482019-04-10 12:43:27 -04001231 return service.getAllowedAssistantAdjustments(mContext.getOpPackageName());
Julia Reynoldsad6dd352019-03-07 16:46:22 -05001232 } catch (RemoteException e) {
1233 throw e.rethrowFromSystemServer();
1234 }
1235 }
1236
Julia Reynoldsdc6adc62019-04-08 10:35:40 -04001237 /**
1238 * @hide
1239 */
1240 @TestApi
Julia Reynolds088c4482019-04-10 12:43:27 -04001241 public void allowAssistantAdjustment(String capability) {
Julia Reynoldsdc6adc62019-04-08 10:35:40 -04001242 INotificationManager service = getService();
1243 try {
Julia Reynolds088c4482019-04-10 12:43:27 -04001244 service.allowAssistantAdjustment(capability);
Julia Reynoldsdc6adc62019-04-08 10:35:40 -04001245 } catch (RemoteException e) {
1246 throw e.rethrowFromSystemServer();
1247 }
1248 }
1249
1250 /**
1251 * @hide
1252 */
1253 @TestApi
Julia Reynolds088c4482019-04-10 12:43:27 -04001254 public void disallowAssistantAdjustment(String capability) {
Julia Reynoldsdc6adc62019-04-08 10:35:40 -04001255 INotificationManager service = getService();
1256 try {
Julia Reynolds088c4482019-04-10 12:43:27 -04001257 service.disallowAssistantAdjustment(capability);
Julia Reynoldsdc6adc62019-04-08 10:35:40 -04001258 } catch (RemoteException e) {
1259 throw e.rethrowFromSystemServer();
1260 }
1261 }
1262
John Spurlock80774932015-05-07 17:38:50 -04001263 /** @hide */
1264 public boolean isNotificationPolicyAccessGrantedForPackage(String pkg) {
1265 INotificationManager service = getService();
1266 try {
1267 return service.isNotificationPolicyAccessGrantedForPackage(pkg);
John Spurlock1fc476d2015-04-14 16:05:20 -04001268 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07001269 throw e.rethrowFromSystemServer();
John Spurlock1fc476d2015-04-14 16:05:20 -04001270 }
John Spurlock1fc476d2015-04-14 16:05:20 -04001271 }
1272
1273 /**
Julia Reynoldsb852e562017-06-06 16:14:18 -04001274 * @hide
1275 */
1276 public List<String> getEnabledNotificationListenerPackages() {
1277 INotificationManager service = getService();
1278 try {
1279 return service.getEnabledNotificationListenerPackages();
1280 } catch (RemoteException e) {
1281 throw e.rethrowFromSystemServer();
1282 }
1283 }
1284
1285 /**
Beverlyff2df9b2018-10-10 16:54:10 -04001286 * Gets the current user-specified default notification policy.
John Spurlock1fc476d2015-04-14 16:05:20 -04001287 *
John Spurlock80774932015-05-07 17:38:50 -04001288 * <p>
John Spurlock1fc476d2015-04-14 16:05:20 -04001289 */
John Spurlock80774932015-05-07 17:38:50 -04001290 public Policy getNotificationPolicy() {
John Spurlock1fc476d2015-04-14 16:05:20 -04001291 INotificationManager service = getService();
1292 try {
John Spurlock80774932015-05-07 17:38:50 -04001293 return service.getNotificationPolicy(mContext.getOpPackageName());
John Spurlock1fc476d2015-04-14 16:05:20 -04001294 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07001295 throw e.rethrowFromSystemServer();
John Spurlock1fc476d2015-04-14 16:05:20 -04001296 }
John Spurlock1fc476d2015-04-14 16:05:20 -04001297 }
1298
1299 /**
1300 * Sets the current notification policy.
1301 *
John Spurlock80774932015-05-07 17:38:50 -04001302 * <p>
John Spurlock7c74f782015-06-04 13:01:42 -04001303 * Only available if policy access is granted to this package.
1304 * See {@link #isNotificationPolicyAccessGranted}.
John Spurlock80774932015-05-07 17:38:50 -04001305 *
John Spurlock1fc476d2015-04-14 16:05:20 -04001306 * @param policy The new desired policy.
1307 */
John Spurlock80774932015-05-07 17:38:50 -04001308 public void setNotificationPolicy(@NonNull Policy policy) {
John Spurlock1fc476d2015-04-14 16:05:20 -04001309 checkRequired("policy", policy);
1310 INotificationManager service = getService();
1311 try {
John Spurlock80774932015-05-07 17:38:50 -04001312 service.setNotificationPolicy(mContext.getOpPackageName(), policy);
John Spurlock1fc476d2015-04-14 16:05:20 -04001313 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07001314 throw e.rethrowFromSystemServer();
John Spurlock1fc476d2015-04-14 16:05:20 -04001315 }
1316 }
1317
John Spurlock80774932015-05-07 17:38:50 -04001318 /** @hide */
1319 public void setNotificationPolicyAccessGranted(String pkg, boolean granted) {
1320 INotificationManager service = getService();
1321 try {
1322 service.setNotificationPolicyAccessGranted(pkg, granted);
1323 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07001324 throw e.rethrowFromSystemServer();
John Spurlock80774932015-05-07 17:38:50 -04001325 }
1326 }
1327
1328 /** @hide */
Julia Reynoldsb852e562017-06-06 16:14:18 -04001329 public void setNotificationListenerAccessGranted(ComponentName listener, boolean granted) {
John Spurlock80774932015-05-07 17:38:50 -04001330 INotificationManager service = getService();
1331 try {
Julia Reynoldsb852e562017-06-06 16:14:18 -04001332 service.setNotificationListenerAccessGranted(listener, granted);
John Spurlock80774932015-05-07 17:38:50 -04001333 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07001334 throw e.rethrowFromSystemServer();
John Spurlock80774932015-05-07 17:38:50 -04001335 }
Julia Reynoldsb852e562017-06-06 16:14:18 -04001336 }
1337
1338 /** @hide */
1339 public void setNotificationListenerAccessGrantedForUser(ComponentName listener, int userId,
1340 boolean granted) {
1341 INotificationManager service = getService();
1342 try {
1343 service.setNotificationListenerAccessGrantedForUser(listener, userId, granted);
1344 } catch (RemoteException e) {
1345 throw e.rethrowFromSystemServer();
1346 }
1347 }
1348
Fabian Kozynskid9425662019-01-29 13:08:30 -05001349 /**
1350 * Grants/revokes Notification Assistant access to {@code assistant} for current user.
Fabian Kozynskicbfbb1d2019-03-15 09:51:39 -04001351 * To grant access for a particular user, obtain this service by using the {@link Context}
1352 * provided by {@link Context#createPackageContextAsUser}
Fabian Kozynskid9425662019-01-29 13:08:30 -05001353 *
1354 * @param assistant Name of component to grant/revoke access or {@code null} to revoke access to
1355 * current assistant
1356 * @param granted Grant/revoke access
1357 * @hide
1358 */
1359 @SystemApi
Julia Reynoldsdc6adc62019-04-08 10:35:40 -04001360 @TestApi
Fabian Kozynski5747d632019-03-11 14:23:23 -04001361 public void setNotificationAssistantAccessGranted(@Nullable ComponentName assistant,
1362 boolean granted) {
Fabian Kozynskid9425662019-01-29 13:08:30 -05001363 INotificationManager service = getService();
1364 try {
1365 service.setNotificationAssistantAccessGranted(assistant, granted);
1366 } catch (RemoteException e) {
1367 throw e.rethrowFromSystemServer();
1368 }
1369 }
1370
Julia Reynoldsb852e562017-06-06 16:14:18 -04001371 /** @hide */
1372 public List<ComponentName> getEnabledNotificationListeners(int userId) {
1373 INotificationManager service = getService();
1374 try {
1375 return service.getEnabledNotificationListeners(userId);
1376 } catch (RemoteException e) {
1377 throw e.rethrowFromSystemServer();
1378 }
John Spurlock80774932015-05-07 17:38:50 -04001379 }
1380
Fabian Kozynskid9425662019-01-29 13:08:30 -05001381 /** @hide */
1382 @SystemApi
Julia Reynoldsdc6adc62019-04-08 10:35:40 -04001383 @TestApi
Fabian Kozynskid9425662019-01-29 13:08:30 -05001384 public @Nullable ComponentName getAllowedNotificationAssistant() {
1385 INotificationManager service = getService();
1386 try {
1387 return service.getAllowedNotificationAssistant();
1388 } catch (RemoteException e) {
1389 throw e.rethrowFromSystemServer();
1390 }
1391 }
1392
1393
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001394 private Context mContext;
John Spurlock1fc476d2015-04-14 16:05:20 -04001395
1396 private static void checkRequired(String name, Object value) {
1397 if (value == null) {
1398 throw new IllegalArgumentException(name + " is required");
1399 }
1400 }
1401
1402 /**
1403 * Notification policy configuration. Represents user-preferences for notification
Julia Reynoldscedacef2016-03-04 08:18:47 -05001404 * filtering.
John Spurlock1fc476d2015-04-14 16:05:20 -04001405 */
1406 public static class Policy implements android.os.Parcelable {
1407 /** Reminder notifications are prioritized. */
1408 public static final int PRIORITY_CATEGORY_REMINDERS = 1 << 0;
1409 /** Event notifications are prioritized. */
1410 public static final int PRIORITY_CATEGORY_EVENTS = 1 << 1;
1411 /** Message notifications are prioritized. */
1412 public static final int PRIORITY_CATEGORY_MESSAGES = 1 << 2;
1413 /** Calls are prioritized. */
1414 public static final int PRIORITY_CATEGORY_CALLS = 1 << 3;
1415 /** Calls from repeat callers are prioritized. */
1416 public static final int PRIORITY_CATEGORY_REPEAT_CALLERS = 1 << 4;
Beverly04216872017-09-28 10:55:32 -04001417 /** Alarms are prioritized */
1418 public static final int PRIORITY_CATEGORY_ALARMS = 1 << 5;
Beverlyd6964762018-02-16 14:07:03 -05001419 /** Media, game, voice navigation are prioritized */
1420 public static final int PRIORITY_CATEGORY_MEDIA = 1 << 6;
1421 /**System (catch-all for non-never suppressible sounds) are prioritized */
1422 public static final int PRIORITY_CATEGORY_SYSTEM = 1 << 7;
John Spurlock1fc476d2015-04-14 16:05:20 -04001423
Beverlyd6964762018-02-16 14:07:03 -05001424 /**
1425 * @hide
1426 */
1427 public static final int[] ALL_PRIORITY_CATEGORIES = {
Beverly04216872017-09-28 10:55:32 -04001428 PRIORITY_CATEGORY_ALARMS,
Beverlyd6964762018-02-16 14:07:03 -05001429 PRIORITY_CATEGORY_MEDIA,
1430 PRIORITY_CATEGORY_SYSTEM,
John Spurlock1fc476d2015-04-14 16:05:20 -04001431 PRIORITY_CATEGORY_REMINDERS,
1432 PRIORITY_CATEGORY_EVENTS,
1433 PRIORITY_CATEGORY_MESSAGES,
1434 PRIORITY_CATEGORY_CALLS,
1435 PRIORITY_CATEGORY_REPEAT_CALLERS,
1436 };
1437
1438 /** Any sender is prioritized. */
1439 public static final int PRIORITY_SENDERS_ANY = 0;
1440 /** Saved contacts are prioritized. */
1441 public static final int PRIORITY_SENDERS_CONTACTS = 1;
1442 /** Only starred contacts are prioritized. */
1443 public static final int PRIORITY_SENDERS_STARRED = 2;
1444
1445 /** Notification categories to prioritize. Bitmask of PRIORITY_CATEGORY_* constants. */
1446 public final int priorityCategories;
1447
John Spurlock80774932015-05-07 17:38:50 -04001448 /** Notification senders to prioritize for calls. One of:
John Spurlock1fc476d2015-04-14 16:05:20 -04001449 * PRIORITY_SENDERS_ANY, PRIORITY_SENDERS_CONTACTS, PRIORITY_SENDERS_STARRED */
John Spurlock80774932015-05-07 17:38:50 -04001450 public final int priorityCallSenders;
John Spurlock1fc476d2015-04-14 16:05:20 -04001451
John Spurlock80774932015-05-07 17:38:50 -04001452 /** Notification senders to prioritize for messages. One of:
1453 * PRIORITY_SENDERS_ANY, PRIORITY_SENDERS_CONTACTS, PRIORITY_SENDERS_STARRED */
1454 public final int priorityMessageSenders;
1455
Julia Reynoldsd5607292016-02-05 15:25:58 -05001456 /**
1457 * @hide
1458 */
Julia Reynoldsf612869ae2015-11-05 16:48:55 -05001459 public static final int SUPPRESSED_EFFECTS_UNSET = -1;
Julia Reynoldsccc6ae62018-03-01 16:24:49 -05001460
Julia Reynoldsd5607292016-02-05 15:25:58 -05001461 /**
Julia Reynoldscedacef2016-03-04 08:18:47 -05001462 * Whether notifications suppressed by DND should not interrupt visually (e.g. with
1463 * notification lights or by turning the screen on) when the screen is off.
Julia Reynoldsccc6ae62018-03-01 16:24:49 -05001464 *
1465 * @deprecated use {@link #SUPPRESSED_EFFECT_FULL_SCREEN_INTENT} and
1466 * {@link #SUPPRESSED_EFFECT_AMBIENT} and {@link #SUPPRESSED_EFFECT_LIGHTS} individually.
Julia Reynoldsd5607292016-02-05 15:25:58 -05001467 */
Julia Reynoldsccc6ae62018-03-01 16:24:49 -05001468 @Deprecated
Julia Reynoldsd5607292016-02-05 15:25:58 -05001469 public static final int SUPPRESSED_EFFECT_SCREEN_OFF = 1 << 0;
1470 /**
Julia Reynoldscedacef2016-03-04 08:18:47 -05001471 * Whether notifications suppressed by DND should not interrupt visually when the screen
1472 * is on (e.g. by peeking onto the screen).
Julia Reynoldsccc6ae62018-03-01 16:24:49 -05001473 *
1474 * @deprecated use {@link #SUPPRESSED_EFFECT_PEEK}.
Julia Reynoldsd5607292016-02-05 15:25:58 -05001475 */
Julia Reynoldsccc6ae62018-03-01 16:24:49 -05001476 @Deprecated
Julia Reynoldsd5607292016-02-05 15:25:58 -05001477 public static final int SUPPRESSED_EFFECT_SCREEN_ON = 1 << 1;
Julia Reynoldsf612869ae2015-11-05 16:48:55 -05001478
Julia Reynoldsccc6ae62018-03-01 16:24:49 -05001479 /**
1480 * Whether {@link Notification#fullScreenIntent full screen intents} from
1481 * notifications intercepted by DND are blocked.
1482 */
1483 public static final int SUPPRESSED_EFFECT_FULL_SCREEN_INTENT = 1 << 2;
1484
1485 /**
1486 * Whether {@link NotificationChannel#shouldShowLights() notification lights} from
1487 * notifications intercepted by DND are blocked.
1488 */
1489 public static final int SUPPRESSED_EFFECT_LIGHTS = 1 << 3;
1490
1491 /**
1492 * Whether notifications intercepted by DND are prevented from peeking.
1493 */
1494 public static final int SUPPRESSED_EFFECT_PEEK = 1 << 4;
1495
1496 /**
1497 * Whether notifications intercepted by DND are prevented from appearing in the status bar,
1498 * on devices that support status bars.
1499 */
1500 public static final int SUPPRESSED_EFFECT_STATUS_BAR = 1 << 5;
1501
1502 /**
1503 * Whether {@link NotificationChannel#canShowBadge() badges} from
1504 * notifications intercepted by DND are blocked on devices that support badging.
1505 */
1506 public static final int SUPPRESSED_EFFECT_BADGE = 1 << 6;
1507
1508 /**
1509 * Whether notification intercepted by DND are prevented from appearing on ambient displays
1510 * on devices that support ambient display.
1511 */
1512 public static final int SUPPRESSED_EFFECT_AMBIENT = 1 << 7;
1513
1514 /**
1515 * Whether notification intercepted by DND are prevented from appearing in notification
1516 * list views like the notification shade or lockscreen on devices that support those
1517 * views.
1518 */
1519 public static final int SUPPRESSED_EFFECT_NOTIFICATION_LIST = 1 << 8;
1520
Julia Reynoldsf612869ae2015-11-05 16:48:55 -05001521 private static final int[] ALL_SUPPRESSED_EFFECTS = {
Julia Reynoldsd5607292016-02-05 15:25:58 -05001522 SUPPRESSED_EFFECT_SCREEN_OFF,
Julia Reynolds61721582016-01-05 08:35:25 -05001523 SUPPRESSED_EFFECT_SCREEN_ON,
Julia Reynoldsccc6ae62018-03-01 16:24:49 -05001524 SUPPRESSED_EFFECT_FULL_SCREEN_INTENT,
1525 SUPPRESSED_EFFECT_LIGHTS,
1526 SUPPRESSED_EFFECT_PEEK,
1527 SUPPRESSED_EFFECT_STATUS_BAR,
1528 SUPPRESSED_EFFECT_BADGE,
1529 SUPPRESSED_EFFECT_AMBIENT,
1530 SUPPRESSED_EFFECT_NOTIFICATION_LIST
Julia Reynoldsf612869ae2015-11-05 16:48:55 -05001531 };
1532
Julia Reynolds47f42802018-04-09 08:47:39 -04001533 private static final int[] SCREEN_OFF_SUPPRESSED_EFFECTS = {
1534 SUPPRESSED_EFFECT_SCREEN_OFF,
1535 SUPPRESSED_EFFECT_FULL_SCREEN_INTENT,
1536 SUPPRESSED_EFFECT_LIGHTS,
1537 SUPPRESSED_EFFECT_AMBIENT,
1538 };
1539
1540 private static final int[] SCREEN_ON_SUPPRESSED_EFFECTS = {
1541 SUPPRESSED_EFFECT_SCREEN_ON,
1542 SUPPRESSED_EFFECT_PEEK,
1543 SUPPRESSED_EFFECT_STATUS_BAR,
1544 SUPPRESSED_EFFECT_BADGE,
1545 SUPPRESSED_EFFECT_NOTIFICATION_LIST
1546 };
1547
Julia Reynoldsf612869ae2015-11-05 16:48:55 -05001548 /**
1549 * Visual effects to suppress for a notification that is filtered by Do Not Disturb mode.
1550 * Bitmask of SUPPRESSED_EFFECT_* constants.
1551 */
1552 public final int suppressedVisualEffects;
1553
Julia Reynoldscedacef2016-03-04 08:18:47 -05001554 /**
Beverly86d076f2018-04-17 14:44:52 -04001555 * @hide
1556 */
1557 public static final int STATE_CHANNELS_BYPASSING_DND = 1 << 0;
1558
1559 /**
1560 * @hide
1561 */
1562 public static final int STATE_UNSET = -1;
1563
1564 /**
1565 * Notification state information that is necessary to determine Do Not Disturb behavior.
1566 * Bitmask of STATE_* constants.
1567 * @hide
1568 */
1569 public final int state;
1570
1571 /**
Julia Reynoldscedacef2016-03-04 08:18:47 -05001572 * Constructs a policy for Do Not Disturb priority mode behavior.
1573 *
Julia Reynoldsccc6ae62018-03-01 16:24:49 -05001574 * <p>
1575 * Apps that target API levels below {@link Build.VERSION_CODES#P} cannot
1576 * change user-designated values to allow or disallow
1577 * {@link Policy#PRIORITY_CATEGORY_ALARMS}, {@link Policy#PRIORITY_CATEGORY_SYSTEM}, and
1578 * {@link Policy#PRIORITY_CATEGORY_MEDIA} from bypassing dnd.
1579 *
Julia Reynoldscedacef2016-03-04 08:18:47 -05001580 * @param priorityCategories bitmask of categories of notifications that can bypass DND.
1581 * @param priorityCallSenders which callers can bypass DND.
1582 * @param priorityMessageSenders which message senders can bypass DND.
1583 */
John Spurlock80774932015-05-07 17:38:50 -04001584 public Policy(int priorityCategories, int priorityCallSenders, int priorityMessageSenders) {
Julia Reynoldsf612869ae2015-11-05 16:48:55 -05001585 this(priorityCategories, priorityCallSenders, priorityMessageSenders,
Beverly86d076f2018-04-17 14:44:52 -04001586 SUPPRESSED_EFFECTS_UNSET, STATE_UNSET);
Julia Reynoldsf612869ae2015-11-05 16:48:55 -05001587 }
1588
Julia Reynoldscedacef2016-03-04 08:18:47 -05001589 /**
1590 * Constructs a policy for Do Not Disturb priority mode behavior.
1591 *
Julia Reynoldsccc6ae62018-03-01 16:24:49 -05001592 * <p>
1593 * Apps that target API levels below {@link Build.VERSION_CODES#P} cannot
1594 * change user-designated values to allow or disallow
1595 * {@link Policy#PRIORITY_CATEGORY_ALARMS}, {@link Policy#PRIORITY_CATEGORY_SYSTEM}, and
1596 * {@link Policy#PRIORITY_CATEGORY_MEDIA} from bypassing dnd.
1597 * <p>
1598 * Additionally, apps that target API levels below {@link Build.VERSION_CODES#P} can
1599 * only modify the {@link #SUPPRESSED_EFFECT_SCREEN_ON} and
1600 * {@link #SUPPRESSED_EFFECT_SCREEN_OFF} bits of the suppressed visual effects field.
1601 * All other suppressed effects will be ignored and reconstituted from the screen on
1602 * and screen off values.
1603 * <p>
1604 * Apps that target {@link Build.VERSION_CODES#P} or above can set any
1605 * suppressed visual effects. However, if any suppressed effects >
1606 * {@link #SUPPRESSED_EFFECT_SCREEN_ON} are set, {@link #SUPPRESSED_EFFECT_SCREEN_ON}
1607 * and {@link #SUPPRESSED_EFFECT_SCREEN_OFF} will be ignored and reconstituted from
1608 * the more specific suppressed visual effect bits. Apps should migrate to targeting
1609 * specific effects instead of the deprecated {@link #SUPPRESSED_EFFECT_SCREEN_ON} and
1610 * {@link #SUPPRESSED_EFFECT_SCREEN_OFF} effects.
1611 *
Julia Reynoldscedacef2016-03-04 08:18:47 -05001612 * @param priorityCategories bitmask of categories of notifications that can bypass DND.
1613 * @param priorityCallSenders which callers can bypass DND.
1614 * @param priorityMessageSenders which message senders can bypass DND.
1615 * @param suppressedVisualEffects which visual interruptions should be suppressed from
1616 * notifications that are filtered by DND.
1617 */
Julia Reynoldsf612869ae2015-11-05 16:48:55 -05001618 public Policy(int priorityCategories, int priorityCallSenders, int priorityMessageSenders,
1619 int suppressedVisualEffects) {
John Spurlock1fc476d2015-04-14 16:05:20 -04001620 this.priorityCategories = priorityCategories;
John Spurlock80774932015-05-07 17:38:50 -04001621 this.priorityCallSenders = priorityCallSenders;
1622 this.priorityMessageSenders = priorityMessageSenders;
Julia Reynoldsf612869ae2015-11-05 16:48:55 -05001623 this.suppressedVisualEffects = suppressedVisualEffects;
Beverly86d076f2018-04-17 14:44:52 -04001624 this.state = STATE_UNSET;
1625 }
1626
1627 /** @hide */
1628 public Policy(int priorityCategories, int priorityCallSenders, int priorityMessageSenders,
1629 int suppressedVisualEffects, int state) {
1630 this.priorityCategories = priorityCategories;
1631 this.priorityCallSenders = priorityCallSenders;
1632 this.priorityMessageSenders = priorityMessageSenders;
1633 this.suppressedVisualEffects = suppressedVisualEffects;
1634 this.state = state;
John Spurlock1fc476d2015-04-14 16:05:20 -04001635 }
1636
1637 /** @hide */
1638 public Policy(Parcel source) {
Beverly86d076f2018-04-17 14:44:52 -04001639 this(source.readInt(), source.readInt(), source.readInt(), source.readInt(),
1640 source.readInt());
John Spurlock1fc476d2015-04-14 16:05:20 -04001641 }
1642
1643 @Override
1644 public void writeToParcel(Parcel dest, int flags) {
1645 dest.writeInt(priorityCategories);
John Spurlock80774932015-05-07 17:38:50 -04001646 dest.writeInt(priorityCallSenders);
1647 dest.writeInt(priorityMessageSenders);
Julia Reynoldsf612869ae2015-11-05 16:48:55 -05001648 dest.writeInt(suppressedVisualEffects);
Beverly86d076f2018-04-17 14:44:52 -04001649 dest.writeInt(state);
John Spurlock1fc476d2015-04-14 16:05:20 -04001650 }
1651
1652 @Override
1653 public int describeContents() {
1654 return 0;
1655 }
1656
1657 @Override
1658 public int hashCode() {
Julia Reynoldsf612869ae2015-11-05 16:48:55 -05001659 return Objects.hash(priorityCategories, priorityCallSenders, priorityMessageSenders,
1660 suppressedVisualEffects);
John Spurlock1fc476d2015-04-14 16:05:20 -04001661 }
1662
1663 @Override
1664 public boolean equals(Object o) {
1665 if (!(o instanceof Policy)) return false;
1666 if (o == this) return true;
1667 final Policy other = (Policy) o;
1668 return other.priorityCategories == priorityCategories
John Spurlock80774932015-05-07 17:38:50 -04001669 && other.priorityCallSenders == priorityCallSenders
Julia Reynoldsf612869ae2015-11-05 16:48:55 -05001670 && other.priorityMessageSenders == priorityMessageSenders
Beverly9cb05c92018-11-28 10:03:23 -05001671 && suppressedVisualEffectsEqual(suppressedVisualEffects,
1672 other.suppressedVisualEffects);
1673 }
1674
1675
1676 private boolean suppressedVisualEffectsEqual(int suppressedEffects,
1677 int otherSuppressedVisualEffects) {
1678 if (suppressedEffects == otherSuppressedVisualEffects) {
1679 return true;
1680 }
1681
1682 if ((suppressedEffects & SUPPRESSED_EFFECT_SCREEN_ON) != 0) {
1683 suppressedEffects |= SUPPRESSED_EFFECT_PEEK;
1684 }
1685 if ((suppressedEffects & SUPPRESSED_EFFECT_SCREEN_OFF) != 0) {
1686 suppressedEffects |= SUPPRESSED_EFFECT_FULL_SCREEN_INTENT;
1687 suppressedEffects |= SUPPRESSED_EFFECT_LIGHTS;
1688 suppressedEffects |= SUPPRESSED_EFFECT_AMBIENT;
1689 }
1690
1691 if ((otherSuppressedVisualEffects & SUPPRESSED_EFFECT_SCREEN_ON) != 0) {
1692 otherSuppressedVisualEffects |= SUPPRESSED_EFFECT_PEEK;
1693 }
1694 if ((otherSuppressedVisualEffects & SUPPRESSED_EFFECT_SCREEN_OFF) != 0) {
1695 otherSuppressedVisualEffects |= SUPPRESSED_EFFECT_FULL_SCREEN_INTENT;
1696 otherSuppressedVisualEffects |= SUPPRESSED_EFFECT_LIGHTS;
1697 otherSuppressedVisualEffects |= SUPPRESSED_EFFECT_AMBIENT;
1698 }
1699
1700 if ((suppressedEffects & SUPPRESSED_EFFECT_SCREEN_ON)
1701 != (otherSuppressedVisualEffects & SUPPRESSED_EFFECT_SCREEN_ON)) {
1702 int currSuppressedEffects = (suppressedEffects & SUPPRESSED_EFFECT_SCREEN_ON) != 0
1703 ? otherSuppressedVisualEffects : suppressedEffects;
1704 if ((currSuppressedEffects & SUPPRESSED_EFFECT_PEEK) == 0) {
1705 return false;
1706 }
1707 }
1708
1709 if ((suppressedEffects & SUPPRESSED_EFFECT_SCREEN_OFF)
1710 != (otherSuppressedVisualEffects & SUPPRESSED_EFFECT_SCREEN_OFF)) {
1711 int currSuppressedEffects = (suppressedEffects & SUPPRESSED_EFFECT_SCREEN_OFF) != 0
1712 ? otherSuppressedVisualEffects : suppressedEffects;
1713 if ((currSuppressedEffects & SUPPRESSED_EFFECT_FULL_SCREEN_INTENT) == 0
1714 || (currSuppressedEffects & SUPPRESSED_EFFECT_LIGHTS) == 0
1715 || (currSuppressedEffects & SUPPRESSED_EFFECT_AMBIENT) == 0) {
1716 return false;
1717 }
1718 }
1719
1720 int thisWithoutOldEffects = suppressedEffects
1721 & ~SUPPRESSED_EFFECT_SCREEN_ON
1722 & ~SUPPRESSED_EFFECT_SCREEN_OFF;
1723 int otherWithoutOldEffects = otherSuppressedVisualEffects
1724 & ~SUPPRESSED_EFFECT_SCREEN_ON
1725 & ~SUPPRESSED_EFFECT_SCREEN_OFF;
1726 return thisWithoutOldEffects == otherWithoutOldEffects;
John Spurlock1fc476d2015-04-14 16:05:20 -04001727 }
1728
1729 @Override
1730 public String toString() {
1731 return "NotificationManager.Policy["
1732 + "priorityCategories=" + priorityCategoriesToString(priorityCategories)
John Spurlock80774932015-05-07 17:38:50 -04001733 + ",priorityCallSenders=" + prioritySendersToString(priorityCallSenders)
1734 + ",priorityMessageSenders=" + prioritySendersToString(priorityMessageSenders)
Julia Reynoldsf612869ae2015-11-05 16:48:55 -05001735 + ",suppressedVisualEffects="
1736 + suppressedEffectsToString(suppressedVisualEffects)
Beverly86d076f2018-04-17 14:44:52 -04001737 + ",areChannelsBypassingDnd=" + (((state & STATE_CHANNELS_BYPASSING_DND) != 0)
1738 ? "true" : "false")
John Spurlock1fc476d2015-04-14 16:05:20 -04001739 + "]";
1740 }
1741
Kweku Adams5ec78cd2017-09-25 16:29:54 -07001742 /** @hide */
Kweku Adamsbc84aec2018-01-23 13:33:12 -08001743 public void writeToProto(ProtoOutputStream proto, long fieldId) {
Kweku Adams5ec78cd2017-09-25 16:29:54 -07001744 final long pToken = proto.start(fieldId);
1745
1746 bitwiseToProtoEnum(proto, PolicyProto.PRIORITY_CATEGORIES, priorityCategories);
1747 proto.write(PolicyProto.PRIORITY_CALL_SENDER, priorityCallSenders);
1748 proto.write(PolicyProto.PRIORITY_MESSAGE_SENDER, priorityMessageSenders);
1749 bitwiseToProtoEnum(
1750 proto, PolicyProto.SUPPRESSED_VISUAL_EFFECTS, suppressedVisualEffects);
1751
1752 proto.end(pToken);
1753 }
1754
1755 private static void bitwiseToProtoEnum(ProtoOutputStream proto, long fieldId, int data) {
1756 for (int i = 1; data > 0; ++i, data >>>= 1) {
1757 if ((data & 1) == 1) {
1758 proto.write(fieldId, i);
1759 }
1760 }
1761 }
1762
Julia Reynoldsccc6ae62018-03-01 16:24:49 -05001763 /**
1764 * @hide
1765 */
1766 public static int getAllSuppressedVisualEffects() {
1767 int effects = 0;
1768 for (int i = 0; i < ALL_SUPPRESSED_EFFECTS.length; i++) {
1769 effects |= ALL_SUPPRESSED_EFFECTS[i];
1770 }
1771 return effects;
1772 }
1773
1774 /**
1775 * @hide
1776 */
1777 public static boolean areAllVisualEffectsSuppressed(int effects) {
1778 for (int i = 0; i < ALL_SUPPRESSED_EFFECTS.length; i++) {
1779 final int effect = ALL_SUPPRESSED_EFFECTS[i];
1780 if ((effects & effect) == 0) {
1781 return false;
1782 }
1783 }
1784 return true;
1785 }
1786
Julia Reynolds9aa1c9e2018-04-09 11:31:15 -04001787 private static int toggleEffects(int currentEffects, int[] effects, boolean suppress) {
1788 for (int i = 0; i < effects.length; i++) {
1789 final int effect = effects[i];
1790 if (suppress) {
1791 currentEffects |= effect;
1792 } else {
1793 currentEffects &= ~effect;
1794 }
1795 }
1796 return currentEffects;
1797 }
1798
Julia Reynoldsf612869ae2015-11-05 16:48:55 -05001799 public static String suppressedEffectsToString(int effects) {
1800 if (effects <= 0) return "";
1801 final StringBuilder sb = new StringBuilder();
1802 for (int i = 0; i < ALL_SUPPRESSED_EFFECTS.length; i++) {
1803 final int effect = ALL_SUPPRESSED_EFFECTS[i];
1804 if ((effects & effect) != 0) {
1805 if (sb.length() > 0) sb.append(',');
1806 sb.append(effectToString(effect));
1807 }
1808 effects &= ~effect;
1809 }
1810 if (effects != 0) {
1811 if (sb.length() > 0) sb.append(',');
1812 sb.append("UNKNOWN_").append(effects);
1813 }
1814 return sb.toString();
1815 }
1816
John Spurlock1fc476d2015-04-14 16:05:20 -04001817 public static String priorityCategoriesToString(int priorityCategories) {
1818 if (priorityCategories == 0) return "";
1819 final StringBuilder sb = new StringBuilder();
1820 for (int i = 0; i < ALL_PRIORITY_CATEGORIES.length; i++) {
1821 final int priorityCategory = ALL_PRIORITY_CATEGORIES[i];
1822 if ((priorityCategories & priorityCategory) != 0) {
1823 if (sb.length() > 0) sb.append(',');
1824 sb.append(priorityCategoryToString(priorityCategory));
1825 }
1826 priorityCategories &= ~priorityCategory;
1827 }
1828 if (priorityCategories != 0) {
1829 if (sb.length() > 0) sb.append(',');
1830 sb.append("PRIORITY_CATEGORY_UNKNOWN_").append(priorityCategories);
1831 }
1832 return sb.toString();
1833 }
1834
Julia Reynoldsf612869ae2015-11-05 16:48:55 -05001835 private static String effectToString(int effect) {
1836 switch (effect) {
Julia Reynoldsccc6ae62018-03-01 16:24:49 -05001837 case SUPPRESSED_EFFECT_FULL_SCREEN_INTENT:
1838 return "SUPPRESSED_EFFECT_FULL_SCREEN_INTENT";
1839 case SUPPRESSED_EFFECT_LIGHTS:
1840 return "SUPPRESSED_EFFECT_LIGHTS";
1841 case SUPPRESSED_EFFECT_PEEK:
1842 return "SUPPRESSED_EFFECT_PEEK";
1843 case SUPPRESSED_EFFECT_STATUS_BAR:
1844 return "SUPPRESSED_EFFECT_STATUS_BAR";
1845 case SUPPRESSED_EFFECT_BADGE:
1846 return "SUPPRESSED_EFFECT_BADGE";
1847 case SUPPRESSED_EFFECT_AMBIENT:
1848 return "SUPPRESSED_EFFECT_AMBIENT";
1849 case SUPPRESSED_EFFECT_NOTIFICATION_LIST:
1850 return "SUPPRESSED_EFFECT_NOTIFICATION_LIST";
1851 case SUPPRESSED_EFFECT_SCREEN_OFF:
1852 return "SUPPRESSED_EFFECT_SCREEN_OFF";
1853 case SUPPRESSED_EFFECT_SCREEN_ON:
1854 return "SUPPRESSED_EFFECT_SCREEN_ON";
1855 case SUPPRESSED_EFFECTS_UNSET:
1856 return "SUPPRESSED_EFFECTS_UNSET";
Julia Reynoldsf612869ae2015-11-05 16:48:55 -05001857 default: return "UNKNOWN_" + effect;
1858 }
1859 }
1860
John Spurlock1fc476d2015-04-14 16:05:20 -04001861 private static String priorityCategoryToString(int priorityCategory) {
1862 switch (priorityCategory) {
1863 case PRIORITY_CATEGORY_REMINDERS: return "PRIORITY_CATEGORY_REMINDERS";
1864 case PRIORITY_CATEGORY_EVENTS: return "PRIORITY_CATEGORY_EVENTS";
1865 case PRIORITY_CATEGORY_MESSAGES: return "PRIORITY_CATEGORY_MESSAGES";
1866 case PRIORITY_CATEGORY_CALLS: return "PRIORITY_CATEGORY_CALLS";
1867 case PRIORITY_CATEGORY_REPEAT_CALLERS: return "PRIORITY_CATEGORY_REPEAT_CALLERS";
Beverly04216872017-09-28 10:55:32 -04001868 case PRIORITY_CATEGORY_ALARMS: return "PRIORITY_CATEGORY_ALARMS";
Beverlyd6964762018-02-16 14:07:03 -05001869 case PRIORITY_CATEGORY_MEDIA: return "PRIORITY_CATEGORY_MEDIA";
1870 case PRIORITY_CATEGORY_SYSTEM: return "PRIORITY_CATEGORY_SYSTEM";
John Spurlock1fc476d2015-04-14 16:05:20 -04001871 default: return "PRIORITY_CATEGORY_UNKNOWN_" + priorityCategory;
1872 }
1873 }
1874
1875 public static String prioritySendersToString(int prioritySenders) {
1876 switch (prioritySenders) {
1877 case PRIORITY_SENDERS_ANY: return "PRIORITY_SENDERS_ANY";
1878 case PRIORITY_SENDERS_CONTACTS: return "PRIORITY_SENDERS_CONTACTS";
1879 case PRIORITY_SENDERS_STARRED: return "PRIORITY_SENDERS_STARRED";
1880 default: return "PRIORITY_SENDERS_UNKNOWN_" + prioritySenders;
1881 }
1882 }
1883
Jeff Sharkey9e8f83d2019-02-28 12:06:45 -07001884 public static final @android.annotation.NonNull Parcelable.Creator<Policy> CREATOR = new Parcelable.Creator<Policy>() {
John Spurlock1fc476d2015-04-14 16:05:20 -04001885 @Override
1886 public Policy createFromParcel(Parcel in) {
1887 return new Policy(in);
1888 }
1889
1890 @Override
1891 public Policy[] newArray(int size) {
1892 return new Policy[size];
1893 }
1894 };
Beverlyff2df9b2018-10-10 16:54:10 -04001895
1896 /** @hide **/
1897 public boolean allowAlarms() {
1898 return (priorityCategories & PRIORITY_CATEGORY_ALARMS) != 0;
1899 }
1900
1901 /** @hide **/
1902 public boolean allowMedia() {
1903 return (priorityCategories & PRIORITY_CATEGORY_MEDIA) != 0;
1904 }
1905
1906 /** @hide **/
1907 public boolean allowSystem() {
1908 return (priorityCategories & PRIORITY_CATEGORY_SYSTEM) != 0;
1909 }
1910
1911 /** @hide **/
1912 public boolean allowRepeatCallers() {
1913 return (priorityCategories & PRIORITY_CATEGORY_REPEAT_CALLERS) != 0;
1914 }
1915
1916 /** @hide **/
1917 public boolean allowCalls() {
1918 return (priorityCategories & PRIORITY_CATEGORY_CALLS) != 0;
1919 }
1920
1921 /** @hide **/
1922 public boolean allowMessages() {
1923 return (priorityCategories & PRIORITY_CATEGORY_MESSAGES) != 0;
1924 }
1925
1926 /** @hide **/
1927 public boolean allowEvents() {
1928 return (priorityCategories & PRIORITY_CATEGORY_EVENTS) != 0;
1929 }
1930
1931 /** @hide **/
1932 public boolean allowReminders() {
1933 return (priorityCategories & PRIORITY_CATEGORY_REMINDERS) != 0;
1934 }
1935
1936 /** @hide **/
1937 public int allowCallsFrom() {
1938 return priorityCallSenders;
1939 }
1940
1941 /** @hide **/
1942 public int allowMessagesFrom() {
1943 return priorityMessageSenders;
1944 }
1945
Beverly12196702018-12-12 15:05:51 -05001946 /** @hide **/
1947 public boolean showFullScreenIntents() {
1948 return (suppressedVisualEffects & SUPPRESSED_EFFECT_FULL_SCREEN_INTENT) == 0;
1949 }
1950
1951 /** @hide **/
1952 public boolean showLights() {
1953 return (suppressedVisualEffects & SUPPRESSED_EFFECT_LIGHTS) == 0;
1954 }
1955
1956 /** @hide **/
1957 public boolean showPeeking() {
1958 return (suppressedVisualEffects & SUPPRESSED_EFFECT_PEEK) == 0;
1959 }
1960
1961 /** @hide **/
1962 public boolean showStatusBarIcons() {
1963 return (suppressedVisualEffects & SUPPRESSED_EFFECT_STATUS_BAR) == 0;
1964 }
1965
1966 /** @hide **/
1967 public boolean showAmbient() {
1968 return (suppressedVisualEffects & SUPPRESSED_EFFECT_AMBIENT) == 0;
1969 }
1970
1971 /** @hide **/
1972 public boolean showBadges() {
1973 return (suppressedVisualEffects & SUPPRESSED_EFFECT_BADGE) == 0;
1974 }
1975
1976 /** @hide **/
1977 public boolean showInNotificationList() {
1978 return (suppressedVisualEffects & SUPPRESSED_EFFECT_NOTIFICATION_LIST) == 0;
1979 }
1980
Beverlyff2df9b2018-10-10 16:54:10 -04001981 /**
1982 * returns a deep copy of this policy
1983 * @hide
1984 */
1985 public Policy copy() {
1986 final Parcel parcel = Parcel.obtain();
1987 try {
1988 writeToParcel(parcel, 0);
1989 parcel.setDataPosition(0);
1990 return new Policy(parcel);
1991 } finally {
1992 parcel.recycle();
1993 }
1994 }
John Spurlock1fc476d2015-04-14 16:05:20 -04001995 }
1996
Dan Sandler994349c2015-04-15 11:02:54 -04001997 /**
1998 * Recover a list of active notifications: ones that have been posted by the calling app that
1999 * have not yet been dismissed by the user or {@link #cancel(String, int)}ed by the app.
2000 *
Julia Reynoldsd12392c2018-12-17 14:06:04 -05002001 * <p><Each notification is embedded in a {@link StatusBarNotification} object, including the
Dan Sandler994349c2015-04-15 11:02:54 -04002002 * original <code>tag</code> and <code>id</code> supplied to
2003 * {@link #notify(String, int, Notification) notify()}
2004 * (via {@link StatusBarNotification#getTag() getTag()} and
2005 * {@link StatusBarNotification#getId() getId()}) as well as a copy of the original
2006 * {@link Notification} object (via {@link StatusBarNotification#getNotification()}).
Julia Reynoldsd12392c2018-12-17 14:06:04 -05002007 * </p>
2008 * <p>From {@link Build.VERSION_CODES#Q}, will also return notifications you've posted as an
2009 * app's notification delegate via
2010 * {@link NotificationManager#notifyAsPackage(String, String, int, Notification)}.
2011 * </p>
Dan Sandler994349c2015-04-15 11:02:54 -04002012 *
2013 * @return An array of {@link StatusBarNotification}.
2014 */
2015 public StatusBarNotification[] getActiveNotifications() {
2016 final INotificationManager service = getService();
2017 final String pkg = mContext.getPackageName();
2018 try {
2019 final ParceledListSlice<StatusBarNotification> parceledList
Jeff Sharkeyad357d12018-02-02 13:25:31 -07002020 = service.getAppActiveNotifications(pkg, mContext.getUserId());
Julia Reynolds34a80842018-09-21 13:01:00 -04002021 if (parceledList != null) {
2022 final List<StatusBarNotification> list = parceledList.getList();
2023 return list.toArray(new StatusBarNotification[list.size()]);
2024 }
Dan Sandler994349c2015-04-15 11:02:54 -04002025 } catch (RemoteException e) {
Jeff Sharkeyc53962d2016-03-01 19:27:23 -07002026 throw e.rethrowFromSystemServer();
Dan Sandler994349c2015-04-15 11:02:54 -04002027 }
Julia Reynolds34a80842018-09-21 13:01:00 -04002028 return new StatusBarNotification[0];
Dan Sandler994349c2015-04-15 11:02:54 -04002029 }
John Spurlock80774932015-05-07 17:38:50 -04002030
2031 /**
2032 * Gets the current notification interruption filter.
John Spurlock80774932015-05-07 17:38:50 -04002033 * <p>
Jeff Sharkey6503bd82017-04-19 23:24:18 -06002034 * The interruption filter defines which notifications are allowed to
2035 * interrupt the user (e.g. via sound &amp; vibration) and is applied
2036 * globally.
John Spurlock80774932015-05-07 17:38:50 -04002037 */
Julia Reynolds0edb50c2016-02-26 14:08:25 -05002038 public final @InterruptionFilter int getCurrentInterruptionFilter() {
John Spurlock80774932015-05-07 17:38:50 -04002039 final INotificationManager service = getService();
2040 try {
2041 return zenModeToInterruptionFilter(service.getZenMode());
2042 } catch (RemoteException e) {
Jeff Sharkeyc53962d2016-03-01 19:27:23 -07002043 throw e.rethrowFromSystemServer();
John Spurlock80774932015-05-07 17:38:50 -04002044 }
John Spurlock80774932015-05-07 17:38:50 -04002045 }
2046
2047 /**
2048 * Sets the current notification interruption filter.
John Spurlock80774932015-05-07 17:38:50 -04002049 * <p>
Jeff Sharkey6503bd82017-04-19 23:24:18 -06002050 * The interruption filter defines which notifications are allowed to
2051 * interrupt the user (e.g. via sound &amp; vibration) and is applied
2052 * globally.
John Spurlock80774932015-05-07 17:38:50 -04002053 * <p>
Jeff Sharkey6503bd82017-04-19 23:24:18 -06002054 * Only available if policy access is granted to this package. See
2055 * {@link #isNotificationPolicyAccessGranted}.
John Spurlock80774932015-05-07 17:38:50 -04002056 */
Jeff Sharkey6503bd82017-04-19 23:24:18 -06002057 public final void setInterruptionFilter(@InterruptionFilter int interruptionFilter) {
John Spurlock80774932015-05-07 17:38:50 -04002058 final INotificationManager service = getService();
2059 try {
2060 service.setInterruptionFilter(mContext.getOpPackageName(), interruptionFilter);
2061 } catch (RemoteException e) {
Jeff Sharkeyc53962d2016-03-01 19:27:23 -07002062 throw e.rethrowFromSystemServer();
John Spurlock80774932015-05-07 17:38:50 -04002063 }
2064 }
2065
2066 /** @hide */
2067 public static int zenModeToInterruptionFilter(int zen) {
2068 switch (zen) {
2069 case Global.ZEN_MODE_OFF: return INTERRUPTION_FILTER_ALL;
2070 case Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS: return INTERRUPTION_FILTER_PRIORITY;
2071 case Global.ZEN_MODE_ALARMS: return INTERRUPTION_FILTER_ALARMS;
2072 case Global.ZEN_MODE_NO_INTERRUPTIONS: return INTERRUPTION_FILTER_NONE;
2073 default: return INTERRUPTION_FILTER_UNKNOWN;
2074 }
2075 }
2076
2077 /** @hide */
2078 public static int zenModeFromInterruptionFilter(int interruptionFilter, int defValue) {
2079 switch (interruptionFilter) {
2080 case INTERRUPTION_FILTER_ALL: return Global.ZEN_MODE_OFF;
2081 case INTERRUPTION_FILTER_PRIORITY: return Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS;
2082 case INTERRUPTION_FILTER_ALARMS: return Global.ZEN_MODE_ALARMS;
2083 case INTERRUPTION_FILTER_NONE: return Global.ZEN_MODE_NO_INTERRUPTIONS;
2084 default: return defValue;
2085 }
2086 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002087}