blob: 8207e0a112c54e4934a7197a3ad6f6b28a403294 [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
2 * Copyright (C) 2007 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.app;
18
Julia Reynolds0edb50c2016-02-26 14:08:25 -050019import android.annotation.IntDef;
John Spurlock1fc476d2015-04-14 16:05:20 -040020import android.annotation.NonNull;
Julia Reynoldsa7ba45a2018-08-29 09:07:52 -040021import android.annotation.Nullable;
John Spurlockb4782522014-08-22 14:54:46 -040022import android.annotation.SdkConstant;
Julia Reynolds12ad7ca2019-01-28 09:29:16 -050023import android.annotation.SystemApi;
Jeff Sharkeyd86b8fe2017-06-02 17:36:26 -060024import android.annotation.SystemService;
Julia Reynoldsb6c1f992016-11-22 09:26:46 -050025import android.annotation.TestApi;
Mathew Inwood61e8ae62018-08-14 14:17:44 +010026import android.annotation.UnsupportedAppUsage;
Christoph Studer4600f9b2014-07-22 22:44:43 +020027import android.app.Notification.Builder;
John Spurlockb4782522014-08-22 14:54:46 -040028import android.content.ComponentName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080029import android.content.Context;
Julia Reynoldse0d711f2017-09-01 08:50:47 -040030import android.content.Intent;
Dan Sandler994349c2015-04-15 11:02:54 -040031import android.content.pm.ParceledListSlice;
Dan Sandlerd63f9322015-05-06 15:18:49 -040032import android.graphics.drawable.Icon;
John Spurlockb2278d62015-04-07 12:47:12 -040033import android.net.Uri;
Dan Sandler4e787062015-06-17 15:09:48 -040034import android.os.Build;
John Spurlock2b122f42014-08-27 16:29:47 -040035import android.os.Bundle;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080036import android.os.Handler;
37import android.os.IBinder;
John Spurlock1fc476d2015-04-14 16:05:20 -040038import android.os.Parcel;
39import android.os.Parcelable;
Jeff Sharkey69ddab42012-08-25 00:05:46 -070040import android.os.RemoteException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080041import android.os.ServiceManager;
Jeff Sharkeya14acd22013-04-02 18:27:45 -070042import android.os.StrictMode;
Dianne Hackborn41203752012-08-31 14:05:51 -070043import android.os.UserHandle;
John Spurlockb2278d62015-04-07 12:47:12 -040044import android.provider.Settings.Global;
Julia Reynolds68062072018-08-06 15:38:21 -040045import android.service.notification.Condition;
Dan Sandler994349c2015-04-15 11:02:54 -040046import android.service.notification.StatusBarNotification;
John Spurlockcdb57ae2015-02-11 19:04:11 -050047import android.service.notification.ZenModeConfig;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080048import android.util.Log;
Kweku Adams5ec78cd2017-09-25 16:29:54 -070049import android.util.proto.ProtoOutputStream;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080050
Julia Reynolds0edb50c2016-02-26 14:08:25 -050051import java.lang.annotation.Retention;
52import java.lang.annotation.RetentionPolicy;
Beverlyc629ee42018-10-02 16:14:07 -040053import java.util.ArrayList;
Geoffrey Pitsch03533712017-01-05 10:30:07 -050054import java.util.Arrays;
Julia Reynolds361e82d32016-02-26 18:19:49 -050055import java.util.HashMap;
Chris Wren5ab5c742016-05-10 15:32:23 -040056import java.util.List;
Julia Reynolds361e82d32016-02-26 18:19:49 -050057import java.util.Map;
John Spurlock1fc476d2015-04-14 16:05:20 -040058import java.util.Objects;
59
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080060/**
61 * Class to notify the user of events that happen. This is how you tell
62 * the user that something has happened in the background. {@more}
63 *
64 * Notifications can take different forms:
65 * <ul>
66 * <li>A persistent icon that goes in the status bar and is accessible
67 * through the launcher, (when the user selects it, a designated Intent
68 * can be launched),</li>
69 * <li>Turning on or flashing LEDs on the device, or</li>
70 * <li>Alerting the user by flashing the backlight, playing a sound,
71 * or vibrating.</li>
72 * </ul>
73 *
74 * <p>
Peter Collingbourneb97c3492010-10-13 20:04:52 +010075 * Each of the notify methods takes an int id parameter and optionally a
76 * {@link String} tag parameter, which may be {@code null}. These parameters
77 * are used to form a pair (tag, id), or ({@code null}, id) if tag is
78 * unspecified. This pair identifies this notification from your app to the
79 * system, so that pair should be unique within your app. If you call one
80 * of the notify methods with a (tag, id) pair that is currently active and
81 * a new set of notification parameters, it will be updated. For example,
82 * if you pass a new status bar icon, the old icon in the status bar will
83 * be replaced with the new one. This is also the same tag and id you pass
84 * to the {@link #cancel(int)} or {@link #cancel(String, int)} method to clear
85 * this notification.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080086 *
Joe Fernandez558459f2011-10-13 16:47:36 -070087 * <div class="special reference">
88 * <h3>Developer Guides</h3>
89 * <p>For a guide to creating notifications, read the
90 * <a href="{@docRoot}guide/topics/ui/notifiers/notifications.html">Status Bar Notifications</a>
91 * developer guide.</p>
92 * </div>
93 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080094 * @see android.app.Notification
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080095 */
Jeff Sharkeyd86b8fe2017-06-02 17:36:26 -060096@SystemService(Context.NOTIFICATION_SERVICE)
97public class NotificationManager {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080098 private static String TAG = "NotificationManager";
Joe Onorato43a17652011-04-06 19:22:23 -070099 private static boolean localLOGV = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800100
John Spurlockb4782522014-08-22 14:54:46 -0400101 /**
Julia Reynoldsfc9767b2018-01-22 17:45:16 -0500102 * Intent that is broadcast when an application is blocked or unblocked.
103 *
104 * This broadcast is only sent to the app whose block state has changed.
105 *
106 * Input: nothing
Julia Reynolds44ff7c92018-02-05 10:02:30 -0500107 * Output: {@link #EXTRA_BLOCKED_STATE}
Julia Reynoldsfc9767b2018-01-22 17:45:16 -0500108 */
109 @SdkConstant(SdkConstant.SdkConstantType.BROADCAST_INTENT_ACTION)
110 public static final String ACTION_APP_BLOCK_STATE_CHANGED =
111 "android.app.action.APP_BLOCK_STATE_CHANGED";
112
113 /**
Julia Reynolds3eb3ffd2017-11-16 10:11:32 -0500114 * Intent that is broadcast when a {@link NotificationChannel} is blocked
115 * (when {@link NotificationChannel#getImportance()} is {@link #IMPORTANCE_NONE}) or unblocked
116 * (when {@link NotificationChannel#getImportance()} is anything other than
117 * {@link #IMPORTANCE_NONE}).
118 *
119 * This broadcast is only sent to the app that owns the channel that has changed.
120 *
121 * Input: nothing
Julia Reynolds44ff7c92018-02-05 10:02:30 -0500122 * Output: {@link #EXTRA_NOTIFICATION_CHANNEL_ID}
123 * Output: {@link #EXTRA_BLOCKED_STATE}
Julia Reynolds3eb3ffd2017-11-16 10:11:32 -0500124 */
125 @SdkConstant(SdkConstant.SdkConstantType.BROADCAST_INTENT_ACTION)
126 public static final String ACTION_NOTIFICATION_CHANNEL_BLOCK_STATE_CHANGED =
127 "android.app.action.NOTIFICATION_CHANNEL_BLOCK_STATE_CHANGED";
128
129 /**
Julia Reynolds44ff7c92018-02-05 10:02:30 -0500130 * Extra for {@link #ACTION_NOTIFICATION_CHANNEL_BLOCK_STATE_CHANGED} containing the id of the
131 * {@link NotificationChannel} which has a new blocked state.
Julia Reynolds3eb3ffd2017-11-16 10:11:32 -0500132 *
Julia Reynolds44ff7c92018-02-05 10:02:30 -0500133 * The value will be the {@link NotificationChannel#getId()} of the channel.
Julia Reynolds3eb3ffd2017-11-16 10:11:32 -0500134 */
Julia Reynolds44ff7c92018-02-05 10:02:30 -0500135 public static final String EXTRA_NOTIFICATION_CHANNEL_ID =
136 "android.app.extra.NOTIFICATION_CHANNEL_ID";
137
138 /**
139 * Extra for {@link #ACTION_NOTIFICATION_CHANNEL_GROUP_BLOCK_STATE_CHANGED} containing the id
140 * of the {@link NotificationChannelGroup} which has a new blocked state.
141 *
142 * The value will be the {@link NotificationChannelGroup#getId()} of the group.
143 */
144 public static final String EXTRA_NOTIFICATION_CHANNEL_GROUP_ID =
145 "android.app.extra.NOTIFICATION_CHANNEL_GROUP_ID";
146
Julia Reynolds3eb3ffd2017-11-16 10:11:32 -0500147
148 /**
149 * Extra for {@link #ACTION_NOTIFICATION_CHANNEL_BLOCK_STATE_CHANGED} or
150 * {@link #ACTION_NOTIFICATION_CHANNEL_GROUP_BLOCK_STATE_CHANGED} containing the new blocked
151 * state as a boolean.
152 *
153 * The value will be {@code true} if this channel or group is now blocked and {@code false} if
154 * this channel or group is now unblocked.
155 */
156 public static final String EXTRA_BLOCKED_STATE = "android.app.extra.BLOCKED_STATE";
157
Julia Reynolds3eb3ffd2017-11-16 10:11:32 -0500158 /**
159 * Intent that is broadcast when a {@link NotificationChannelGroup} is
160 * {@link NotificationChannelGroup#isBlocked() blocked} or unblocked.
161 *
162 * This broadcast is only sent to the app that owns the channel group that has changed.
163 *
164 * Input: nothing
Julia Reynolds44ff7c92018-02-05 10:02:30 -0500165 * Output: {@link #EXTRA_NOTIFICATION_CHANNEL_GROUP_ID}
166 * Output: {@link #EXTRA_BLOCKED_STATE}
Julia Reynolds3eb3ffd2017-11-16 10:11:32 -0500167 */
168 @SdkConstant(SdkConstant.SdkConstantType.BROADCAST_INTENT_ACTION)
169 public static final String ACTION_NOTIFICATION_CHANNEL_GROUP_BLOCK_STATE_CHANGED =
170 "android.app.action.NOTIFICATION_CHANNEL_GROUP_BLOCK_STATE_CHANGED";
171
172 /**
John Spurlockb4782522014-08-22 14:54:46 -0400173 * Intent that is broadcast when the state of {@link #getEffectsSuppressor()} changes.
174 * This broadcast is only sent to registered receivers.
175 *
176 * @hide
177 */
178 @SdkConstant(SdkConstant.SdkConstantType.BROADCAST_INTENT_ACTION)
179 public static final String ACTION_EFFECTS_SUPPRESSOR_CHANGED
180 = "android.os.action.ACTION_EFFECTS_SUPPRESSOR_CHANGED";
181
John Spurlock1fc476d2015-04-14 16:05:20 -0400182 /**
John Spurlock7c74f782015-06-04 13:01:42 -0400183 * Intent that is broadcast when the state of {@link #isNotificationPolicyAccessGranted()}
184 * changes.
185 *
186 * This broadcast is only sent to registered receivers, and only to the apps that have changed.
187 */
188 @SdkConstant(SdkConstant.SdkConstantType.BROADCAST_INTENT_ACTION)
189 public static final String ACTION_NOTIFICATION_POLICY_ACCESS_GRANTED_CHANGED
190 = "android.app.action.NOTIFICATION_POLICY_ACCESS_GRANTED_CHANGED";
191
192 /**
John Spurlock1fc476d2015-04-14 16:05:20 -0400193 * Intent that is broadcast when the state of getNotificationPolicy() changes.
194 * This broadcast is only sent to registered receivers.
195 */
196 @SdkConstant(SdkConstant.SdkConstantType.BROADCAST_INTENT_ACTION)
197 public static final String ACTION_NOTIFICATION_POLICY_CHANGED
198 = "android.app.action.NOTIFICATION_POLICY_CHANGED";
199
John Spurlock80774932015-05-07 17:38:50 -0400200 /**
201 * Intent that is broadcast when the state of getCurrentInterruptionFilter() changes.
202 * This broadcast is only sent to registered receivers.
203 */
204 @SdkConstant(SdkConstant.SdkConstantType.BROADCAST_INTENT_ACTION)
205 public static final String ACTION_INTERRUPTION_FILTER_CHANGED
206 = "android.app.action.INTERRUPTION_FILTER_CHANGED";
207
208 /**
Jason Monka9927322015-12-13 16:22:37 -0500209 * Intent that is broadcast when the state of getCurrentInterruptionFilter() changes.
210 * @hide
211 */
212 @SdkConstant(SdkConstant.SdkConstantType.BROADCAST_INTENT_ACTION)
213 public static final String ACTION_INTERRUPTION_FILTER_CHANGED_INTERNAL
214 = "android.app.action.INTERRUPTION_FILTER_CHANGED_INTERNAL";
215
Julia Reynolds0edb50c2016-02-26 14:08:25 -0500216 /** @hide */
Jeff Sharkey6503bd82017-04-19 23:24:18 -0600217 @IntDef(prefix = { "INTERRUPTION_FILTER_" }, value = {
218 INTERRUPTION_FILTER_NONE, INTERRUPTION_FILTER_PRIORITY, INTERRUPTION_FILTER_ALARMS,
219 INTERRUPTION_FILTER_ALL, INTERRUPTION_FILTER_UNKNOWN
220 })
Julia Reynolds0edb50c2016-02-26 14:08:25 -0500221 @Retention(RetentionPolicy.SOURCE)
222 public @interface InterruptionFilter {}
223
Jason Monka9927322015-12-13 16:22:37 -0500224 /**
John Spurlock80774932015-05-07 17:38:50 -0400225 * {@link #getCurrentInterruptionFilter() Interruption filter} constant -
Julia Reynoldsdd0605b2016-04-06 10:26:54 -0400226 * Normal interruption filter - no notifications are suppressed.
John Spurlock80774932015-05-07 17:38:50 -0400227 */
228 public static final int INTERRUPTION_FILTER_ALL = 1;
229
230 /**
231 * {@link #getCurrentInterruptionFilter() Interruption filter} constant -
Julia Reynoldsdd0605b2016-04-06 10:26:54 -0400232 * Priority interruption filter - all notifications are suppressed except those that match
233 * the priority criteria. Some audio streams are muted. See
234 * {@link Policy#priorityCallSenders}, {@link Policy#priorityCategories},
235 * {@link Policy#priorityMessageSenders} to define or query this criteria. Users can
236 * additionally specify packages that can bypass this interruption filter.
John Spurlock80774932015-05-07 17:38:50 -0400237 */
238 public static final int INTERRUPTION_FILTER_PRIORITY = 2;
239
240 /**
241 * {@link #getCurrentInterruptionFilter() Interruption filter} constant -
Julia Reynoldsdd0605b2016-04-06 10:26:54 -0400242 * No interruptions filter - all notifications are suppressed and all audio streams (except
243 * those used for phone calls) and vibrations are muted.
John Spurlock80774932015-05-07 17:38:50 -0400244 */
245 public static final int INTERRUPTION_FILTER_NONE = 3;
246
247 /**
248 * {@link #getCurrentInterruptionFilter() Interruption filter} constant -
Julia Reynoldsdd0605b2016-04-06 10:26:54 -0400249 * Alarms only interruption filter - all notifications except those of category
250 * {@link Notification#CATEGORY_ALARM} are suppressed. Some audio streams are muted.
John Spurlock80774932015-05-07 17:38:50 -0400251 */
252 public static final int INTERRUPTION_FILTER_ALARMS = 4;
253
254 /** {@link #getCurrentInterruptionFilter() Interruption filter} constant - returned when
255 * the value is unavailable for any reason.
256 */
257 public static final int INTERRUPTION_FILTER_UNKNOWN = 0;
258
Chris Wren5ab5c742016-05-10 15:32:23 -0400259 /** @hide */
Jeff Sharkey6503bd82017-04-19 23:24:18 -0600260 @IntDef(prefix = { "IMPORTANCE_" }, value = {
261 IMPORTANCE_UNSPECIFIED, IMPORTANCE_NONE,
262 IMPORTANCE_MIN, IMPORTANCE_LOW, IMPORTANCE_DEFAULT, IMPORTANCE_HIGH
263 })
Chris Wren5ab5c742016-05-10 15:32:23 -0400264 @Retention(RetentionPolicy.SOURCE)
265 public @interface Importance {}
266
Julia Reynolds68062072018-08-06 15:38:21 -0400267 /**
268 * Activity Action: Launch an Automatic Zen Rule configuration screen
269 * <p>
270 * Input: Optionally, {@link #EXTRA_AUTOMATIC_RULE_ID}, if the configuration screen for an
271 * existing rule should be displayed. If the rule id is missing or null, apps should display
272 * a configuration screen where users can create a new instance of the rule.
273 * <p>
274 * Output: Nothing
275 * <p>
276 * You can have multiple activities handling this intent, if you support multiple
277 * {@link AutomaticZenRule rules}. In order for the system to properly display all of your
278 * rule types so that users can create new instances or configure existing ones, you need
279 * to add some extra metadata ({@link #META_DATA_AUTOMATIC_RULE_TYPE})
280 * to your activity tag in your manifest. If you'd like to limit the number of rules a user
281 * can create from this flow, you can additionally optionally include
282 * {@link #META_DATA_RULE_INSTANCE_LIMIT}.
283 *
284 * For example,
285 * &lt;meta-data
286 * android:name="android.app.zen.automatic.ruleType"
287 * android:value="@string/my_condition_rule">
288 * &lt;/meta-data>
289 * &lt;meta-data
290 * android:name="android.app.zen.automatic.ruleInstanceLimit"
291 * android:value="1">
292 * &lt;/meta-data>
293 * </p>
294 * </p>
295 *
296 * @see {@link #addAutomaticZenRule(AutomaticZenRule)}
297 */
298 @SdkConstant(SdkConstant.SdkConstantType.ACTIVITY_INTENT_ACTION)
299 public static final String ACTION_AUTOMATIC_ZEN_RULE =
300 "android.app.action.AUTOMATIC_ZEN_RULE";
301
302 /**
303 * Used as an optional string extra on {@link #ACTION_AUTOMATIC_ZEN_RULE} intents. If
304 * provided, contains the id of the {@link AutomaticZenRule} (as returned from
305 * {@link NotificationManager#addAutomaticZenRule(AutomaticZenRule)}) for which configuration
306 * settings should be displayed.
307 */
308 public static final String EXTRA_AUTOMATIC_RULE_ID = "android.app.extra.AUTOMATIC_RULE_ID";
309
310 /**
311 * A required {@code meta-data} tag for activities that handle
312 * {@link #ACTION_AUTOMATIC_ZEN_RULE}.
313 *
314 * This tag should contain a localized name of the type of the zen rule provided by the
315 * activity.
316 */
317 public static final String META_DATA_AUTOMATIC_RULE_TYPE = "android.app.automatic.ruleType";
318
319 /**
320 * An optional {@code meta-data} tag for activities that handle
321 * {@link #ACTION_AUTOMATIC_ZEN_RULE}.
322 *
323 * This tag should contain the maximum number of rule instances that
324 * can be created for this rule type. Omit or enter a value <= 0 to allow unlimited instances.
325 */
326 public static final String META_DATA_RULE_INSTANCE_LIMIT =
327 "android.app.zen.automatic.ruleInstanceLimit";
328
Chris Wren5ab5c742016-05-10 15:32:23 -0400329 /** Value signifying that the user has not expressed a per-app visibility override value.
330 * @hide */
331 public static final int VISIBILITY_NO_OVERRIDE = -1000;
Julia Reynolds85769912016-10-25 09:08:57 -0400332
Chris Wren5ab5c742016-05-10 15:32:23 -0400333 /**
334 * Value signifying that the user has not expressed an importance.
335 *
336 * This value is for persisting preferences, and should never be associated with
337 * an actual notification.
338 */
339 public static final int IMPORTANCE_UNSPECIFIED = -1000;
340
341 /**
Julia Reynoldsbaff4002016-12-15 11:34:26 -0500342 * A notification with no importance: does not show in the shade.
Chris Wren5ab5c742016-05-10 15:32:23 -0400343 */
344 public static final int IMPORTANCE_NONE = 0;
345
346 /**
Dianne Hackborn6e5bd3f2017-07-31 14:22:04 -0700347 * Min notification importance: only shows in the shade, below the fold. This should
348 * not be used with {@link Service#startForeground(int, Notification) Service.startForeground}
349 * since a foreground service is supposed to be something the user cares about so it does
350 * not make semantic sense to mark its notification as minimum importance. If you do this
351 * as of Android version {@link android.os.Build.VERSION_CODES#O}, the system will show
352 * a higher-priority notification about your app running in the background.
Chris Wren5ab5c742016-05-10 15:32:23 -0400353 */
354 public static final int IMPORTANCE_MIN = 1;
355
356 /**
Julia Reynolds12ad7ca2019-01-28 09:29:16 -0500357 * Low notification importance: Shows in the shade, and potentially in the status bar
358 * (see {@link #shouldHideSilentStatusBarIcons()}), but is not audibly intrusive.
Chris Wren5ab5c742016-05-10 15:32:23 -0400359 */
360 public static final int IMPORTANCE_LOW = 2;
361
362 /**
Julia Reynolds85769912016-10-25 09:08:57 -0400363 * Default notification importance: shows everywhere, makes noise, but does not visually
364 * intrude.
Chris Wren5ab5c742016-05-10 15:32:23 -0400365 */
366 public static final int IMPORTANCE_DEFAULT = 3;
367
368 /**
Julia Reynolds85769912016-10-25 09:08:57 -0400369 * Higher notification importance: shows everywhere, makes noise and peeks. May use full screen
370 * intents.
Chris Wren5ab5c742016-05-10 15:32:23 -0400371 */
372 public static final int IMPORTANCE_HIGH = 4;
373
374 /**
Julia Reynolds85769912016-10-25 09:08:57 -0400375 * Unused.
Chris Wren5ab5c742016-05-10 15:32:23 -0400376 */
377 public static final int IMPORTANCE_MAX = 5;
378
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100379 @UnsupportedAppUsage
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800380 private static INotificationManager sService;
381
Dianne Hackbornd8a43f62009-08-17 23:33:56 -0700382 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100383 @UnsupportedAppUsage
Dianne Hackbornd8a43f62009-08-17 23:33:56 -0700384 static public INotificationManager getService()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800385 {
386 if (sService != null) {
387 return sService;
388 }
389 IBinder b = ServiceManager.getService("notification");
390 sService = INotificationManager.Stub.asInterface(b);
391 return sService;
392 }
393
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100394 @UnsupportedAppUsage
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800395 /*package*/ NotificationManager(Context context, Handler handler)
396 {
397 mContext = context;
398 }
399
Jeff Sharkey69ddab42012-08-25 00:05:46 -0700400 /** {@hide} */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100401 @UnsupportedAppUsage
Jeff Sharkey69ddab42012-08-25 00:05:46 -0700402 public static NotificationManager from(Context context) {
403 return (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
404 }
405
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800406 /**
Daniel Sandlere97a3bc2011-02-07 16:47:07 -0500407 * Post a notification to be shown in the status bar. If a notification with
408 * the same id has already been posted by your application and has not yet been canceled, it
409 * will be replaced by the updated information.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800410 *
411 * @param id An identifier for this notification unique within your
412 * application.
Daniel Sandlere97a3bc2011-02-07 16:47:07 -0500413 * @param notification A {@link Notification} object describing what to show the user. Must not
414 * be null.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800415 */
416 public void notify(int id, Notification notification)
417 {
Fred Quintana6ecaff12009-09-25 14:23:13 -0700418 notify(null, id, notification);
419 }
420
421 /**
Julia Reynoldsa7ba45a2018-08-29 09:07:52 -0400422 * Posts a notification to be shown in the status bar. If a notification with
Daniel Sandlere97a3bc2011-02-07 16:47:07 -0500423 * the same tag and id has already been posted by your application and has not yet been
424 * canceled, it will be replaced by the updated information.
Fred Quintana6ecaff12009-09-25 14:23:13 -0700425 *
Julia Reynoldse0d711f2017-09-01 08:50:47 -0400426 * All {@link android.service.notification.NotificationListenerService listener services} will
427 * be granted {@link Intent#FLAG_GRANT_READ_URI_PERMISSION} access to any {@link Uri uris}
428 * provided on this notification or the
429 * {@link NotificationChannel} this notification is posted to using
430 * {@link Context#grantUriPermission(String, Uri, int)}. Permission will be revoked when the
431 * notification is canceled, or you can revoke permissions with
432 * {@link Context#revokeUriPermission(Uri, int)}.
433 *
Peter Collingbourneb97c3492010-10-13 20:04:52 +0100434 * @param tag A string identifier for this notification. May be {@code null}.
435 * @param id An identifier for this notification. The pair (tag, id) must be unique
436 * within your application.
Daniel Sandlere97a3bc2011-02-07 16:47:07 -0500437 * @param notification A {@link Notification} object describing what to
438 * show the user. Must not be null.
Fred Quintana6ecaff12009-09-25 14:23:13 -0700439 */
440 public void notify(String tag, int id, Notification notification)
441 {
Jeff Sharkeyad357d12018-02-02 13:25:31 -0700442 notifyAsUser(tag, id, notification, mContext.getUser());
Dianne Hackborn41203752012-08-31 14:05:51 -0700443 }
444
445 /**
Julia Reynoldsa7ba45a2018-08-29 09:07:52 -0400446 * Posts a notification as a specified package to be shown in the status bar. If a notification
447 * with the same tag and id has already been posted for that package and has not yet been
448 * canceled, it will be replaced by the updated information.
449 *
450 * All {@link android.service.notification.NotificationListenerService listener services} will
451 * be granted {@link Intent#FLAG_GRANT_READ_URI_PERMISSION} access to any {@link Uri uris}
452 * provided on this notification or the
453 * {@link NotificationChannel} this notification is posted to using
454 * {@link Context#grantUriPermission(String, Uri, int)}. Permission will be revoked when the
455 * notification is canceled, or you can revoke permissions with
456 * {@link Context#revokeUriPermission(Uri, int)}.
457 *
458 * @param targetPackage The package to post the notification as. The package must have granted
459 * you access to post notifications on their behalf with
460 * {@link #setNotificationDelegate(String)}.
461 * @param tag A string identifier for this notification. May be {@code null}.
462 * @param id An identifier for this notification. The pair (tag, id) must be unique
463 * within your application.
464 * @param notification A {@link Notification} object describing what to
465 * show the user. Must not be null.
466 */
467 public void notifyAsPackage(@NonNull String targetPackage, @NonNull String tag, int id,
468 Notification notification) {
469 INotificationManager service = getService();
470 String sender = mContext.getPackageName();
471
472 try {
473 if (localLOGV) Log.v(TAG, sender + ": notify(" + id + ", " + notification + ")");
474 service.enqueueNotificationWithTag(targetPackage, sender, tag, id,
475 fixNotification(notification), mContext.getUser().getIdentifier());
476 } catch (RemoteException e) {
477 throw e.rethrowFromSystemServer();
478 }
479 }
480
481 /**
Dianne Hackborn41203752012-08-31 14:05:51 -0700482 * @hide
483 */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100484 @UnsupportedAppUsage
Dianne Hackborn41203752012-08-31 14:05:51 -0700485 public void notifyAsUser(String tag, int id, Notification notification, UserHandle user)
486 {
Dianne Hackborn41203752012-08-31 14:05:51 -0700487 INotificationManager service = getService();
488 String pkg = mContext.getPackageName();
Julia Reynoldsa7ba45a2018-08-29 09:07:52 -0400489
490 try {
491 if (localLOGV) Log.v(TAG, pkg + ": notify(" + id + ", " + notification + ")");
492 service.enqueueNotificationWithTag(pkg, mContext.getOpPackageName(), tag, id,
493 fixNotification(notification), user.getIdentifier());
494 } catch (RemoteException e) {
495 throw e.rethrowFromSystemServer();
496 }
497 }
498
499 private Notification fixNotification(Notification notification) {
500 String pkg = mContext.getPackageName();
Julia Reynoldsda303542015-11-23 14:00:20 -0500501 // Fix the notification as best we can.
502 Notification.addFieldsFromContext(mContext, notification);
Julia Reynoldse0d711f2017-09-01 08:50:47 -0400503
Jeff Sharkey65c4a2b2012-09-25 17:22:27 -0700504 if (notification.sound != null) {
505 notification.sound = notification.sound.getCanonicalUri();
Jeff Sharkeya14acd22013-04-02 18:27:45 -0700506 if (StrictMode.vmFileUriExposureEnabled()) {
Jeff Sharkeyac3be9a2016-02-01 10:39:30 -0700507 notification.sound.checkFileUriExposed("Notification.sound");
Jeff Sharkeya14acd22013-04-02 18:27:45 -0700508 }
Julia Reynoldse0d711f2017-09-01 08:50:47 -0400509
Jeff Sharkey65c4a2b2012-09-25 17:22:27 -0700510 }
Dan Sandlerd63f9322015-05-06 15:18:49 -0400511 fixLegacySmallIcon(notification, pkg);
Julia Reynoldsd9228f12015-10-20 10:37:27 -0400512 if (mContext.getApplicationInfo().targetSdkVersion > Build.VERSION_CODES.LOLLIPOP_MR1) {
513 if (notification.getSmallIcon() == null) {
514 throw new IllegalArgumentException("Invalid notification (no valid small icon): "
515 + notification);
516 }
517 }
Julia Reynoldsa7ba45a2018-08-29 09:07:52 -0400518
Selim Cinekd0426622017-07-11 13:19:59 +0200519 notification.reduceImageSizes(mContext);
Julia Reynoldse0d711f2017-09-01 08:50:47 -0400520
Julia Reynolds8a3b4592017-06-26 17:15:14 -0400521 ActivityManager am = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
522 boolean isLowRam = am.isLowRamDevice();
Julia Reynoldsa7ba45a2018-08-29 09:07:52 -0400523 return Builder.maybeCloneStrippedForDelivery(notification, isLowRam, mContext);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800524 }
525
Dan Sandlerd63f9322015-05-06 15:18:49 -0400526 private void fixLegacySmallIcon(Notification n, String pkg) {
527 if (n.getSmallIcon() == null && n.icon != 0) {
528 n.setSmallIcon(Icon.createWithResource(pkg, n.icon));
529 }
530 }
531
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800532 /**
533 * Cancel a previously shown notification. If it's transient, the view
534 * will be hidden. If it's persistent, it will be removed from the status
535 * bar.
536 */
537 public void cancel(int id)
538 {
Fred Quintana6ecaff12009-09-25 14:23:13 -0700539 cancel(null, id);
540 }
541
542 /**
543 * Cancel a previously shown notification. If it's transient, the view
544 * will be hidden. If it's persistent, it will be removed from the status
545 * bar.
546 */
547 public void cancel(String tag, int id)
548 {
Jeff Sharkeyad357d12018-02-02 13:25:31 -0700549 cancelAsUser(tag, id, mContext.getUser());
Dianne Hackborn41203752012-08-31 14:05:51 -0700550 }
551
552 /**
553 * @hide
554 */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100555 @UnsupportedAppUsage
Dianne Hackborn41203752012-08-31 14:05:51 -0700556 public void cancelAsUser(String tag, int id, UserHandle user)
557 {
558 INotificationManager service = getService();
559 String pkg = mContext.getPackageName();
560 if (localLOGV) Log.v(TAG, pkg + ": cancel(" + id + ")");
561 try {
562 service.cancelNotificationWithTag(pkg, tag, id, user.getIdentifier());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800563 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -0700564 throw e.rethrowFromSystemServer();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800565 }
566 }
567
568 /**
569 * Cancel all previously shown notifications. See {@link #cancel} for the
570 * detailed behavior.
571 */
572 public void cancelAll()
573 {
574 INotificationManager service = getService();
575 String pkg = mContext.getPackageName();
576 if (localLOGV) Log.v(TAG, pkg + ": cancelAll()");
577 try {
Jeff Sharkeyad357d12018-02-02 13:25:31 -0700578 service.cancelAllNotifications(pkg, mContext.getUserId());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800579 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -0700580 throw e.rethrowFromSystemServer();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800581 }
582 }
583
John Spurlockb4782522014-08-22 14:54:46 -0400584 /**
Julia Reynoldsa7ba45a2018-08-29 09:07:52 -0400585 * Allows a package to post notifications on your behalf using
586 * {@link #notifyAsPackage(String, String, int, Notification)}.
587 *
588 * This can be used to allow persistent processes to post notifications based on messages
589 * received on your behalf from the cloud, without your process having to wake up.
590 *
591 * You can check if you have an allowed delegate with {@link #getNotificationDelegate()} and
592 * revoke your delegate with {@link #revokeNotificationDelegate()}.
593 *
594 * @param delegate Package name of the app which can send notifications on your behalf.
595 */
596 public void setNotificationDelegate(@NonNull String delegate) {
597 INotificationManager service = getService();
598 String pkg = mContext.getPackageName();
599 if (localLOGV) Log.v(TAG, pkg + ": cancelAll()");
600 try {
601 service.setNotificationDelegate(pkg, delegate);
602 } catch (RemoteException e) {
603 throw e.rethrowFromSystemServer();
604 }
605 }
606
607 /**
608 * Revokes permission for your {@link #setNotificationDelegate(String) notification delegate}
609 * to post notifications on your behalf.
610 */
611 public void revokeNotificationDelegate() {
612 INotificationManager service = getService();
613 String pkg = mContext.getPackageName();
614 try {
615 service.revokeNotificationDelegate(pkg);
616 } catch (RemoteException e) {
617 throw e.rethrowFromSystemServer();
618 }
619 }
620
621 /**
622 * Returns the {@link #setNotificationDelegate(String) delegate} that can post notifications on
623 * your behalf, if there currently is one.
624 */
625 public @Nullable String getNotificationDelegate() {
626 INotificationManager service = getService();
627 String pkg = mContext.getPackageName();
628 try {
629 return service.getNotificationDelegate(pkg);
630 } catch (RemoteException e) {
631 throw e.rethrowFromSystemServer();
632 }
633 }
634
635 /**
636 * Returns whether you are allowed to post notifications on behalf of a given package, with
637 * {@link #notifyAsPackage(String, String, int, Notification)}.
638 *
639 * See {@link #setNotificationDelegate(String)}.
640 */
641 public boolean canNotifyAsPackage(String pkg) {
642 INotificationManager service = getService();
643 try {
644 return service.canNotifyAsPackage(mContext.getPackageName(), pkg);
645 } catch (RemoteException e) {
646 throw e.rethrowFromSystemServer();
647 }
648 }
649
650 /**
Julia Reynolds59e152e2017-01-25 17:42:53 -0500651 * Creates a group container for {@link NotificationChannel} objects.
652 *
Julia Reynolds1d97e6a2017-03-13 15:05:40 -0400653 * This can be used to rename an existing group.
Julia Reynolds59e152e2017-01-25 17:42:53 -0500654 * <p>
655 * Group information is only used for presentation, not for behavior. Groups are optional
656 * for channels, and you can have a mix of channels that belong to groups and channels
657 * that do not.
658 * </p>
659 * <p>
660 * For example, if your application supports multiple accounts, and those accounts will
661 * have similar channels, you can create a group for each account with account specific
662 * labels instead of appending account information to each channel's label.
663 * </p>
664 *
665 * @param group The group to create
666 */
667 public void createNotificationChannelGroup(@NonNull NotificationChannelGroup group) {
668 createNotificationChannelGroups(Arrays.asList(group));
669 }
670
671 /**
672 * Creates multiple notification channel groups.
673 *
674 * @param groups The list of groups to create
675 */
676 public void createNotificationChannelGroups(@NonNull List<NotificationChannelGroup> groups) {
677 INotificationManager service = getService();
678 try {
679 service.createNotificationChannelGroups(mContext.getPackageName(),
680 new ParceledListSlice(groups));
681 } catch (RemoteException e) {
682 throw e.rethrowFromSystemServer();
683 }
684 }
685
686 /**
Geoffrey Pitsch03533712017-01-05 10:30:07 -0500687 * Creates a notification channel that notifications can be posted to.
688 *
Julia Reynolds2c891c92017-03-17 14:23:47 -0400689 * This can also be used to restore a deleted channel and to update an existing channel's
Julia Reynolds005c8b92017-08-24 10:35:53 -0400690 * name, description, group, and/or importance.
Julia Reynolds0ffc13b2017-04-27 13:54:36 -0400691 *
692 * <p>The name and description should only be changed if the locale changes
Julia Reynolds2c891c92017-03-17 14:23:47 -0400693 * or in response to the user renaming this channel. For example, if a user has a channel
694 * named 'John Doe' that represents messages from a 'John Doe', and 'John Doe' changes his name
695 * to 'John Smith,' the channel can be renamed to match.
Geoffrey Pitsch07532c32017-07-18 11:44:06 -0400696 *
697 * <p>The importance of an existing channel will only be changed if the new importance is lower
698 * than the current value and the user has not altered any settings on this channel.
699 *
Julia Reynolds005c8b92017-08-24 10:35:53 -0400700 * <p>The group an existing channel will only be changed if the channel does not already
701 * belong to a group.
702 *
Julia Reynolds2c891c92017-03-17 14:23:47 -0400703 * All other fields are ignored for channels that already exist.
Julia Reynolds59e152e2017-01-25 17:42:53 -0500704 *
Geoffrey Pitsch03533712017-01-05 10:30:07 -0500705 * @param channel the channel to create. Note that the created channel may differ from this
Julia Reynoldse8665332017-03-13 13:00:41 -0400706 * value. If the provided channel is malformed, a RemoteException will be
Julia Reynolds1d97e6a2017-03-13 15:05:40 -0400707 * thrown.
Julia Reynoldsb5e44b72016-08-16 15:00:25 -0400708 */
Geoffrey Pitsch03533712017-01-05 10:30:07 -0500709 public void createNotificationChannel(@NonNull NotificationChannel channel) {
710 createNotificationChannels(Arrays.asList(channel));
Geoffrey Pitsche75a66e2016-11-22 11:12:11 -0500711 }
712
713 /**
Julia Reynolds1d97e6a2017-03-13 15:05:40 -0400714 * Creates multiple notification channels that different notifications can be posted to. See
715 * {@link #createNotificationChannel(NotificationChannel)}.
Geoffrey Pitsche75a66e2016-11-22 11:12:11 -0500716 *
Julia Reynolds1d97e6a2017-03-13 15:05:40 -0400717 * @param channels the list of channels to attempt to create.
Geoffrey Pitsche75a66e2016-11-22 11:12:11 -0500718 */
Geoffrey Pitsch03533712017-01-05 10:30:07 -0500719 public void createNotificationChannels(@NonNull List<NotificationChannel> channels) {
Julia Reynoldsb5e44b72016-08-16 15:00:25 -0400720 INotificationManager service = getService();
721 try {
Geoffrey Pitsch03533712017-01-05 10:30:07 -0500722 service.createNotificationChannels(mContext.getPackageName(),
723 new ParceledListSlice(channels));
Julia Reynoldsb5e44b72016-08-16 15:00:25 -0400724 } catch (RemoteException e) {
725 throw e.rethrowFromSystemServer();
726 }
727 }
728
729 /**
730 * Returns the notification channel settings for a given channel id.
Julia Reynolds0ffc13b2017-04-27 13:54:36 -0400731 *
732 * The channel must belong to your package, or it will not be returned.
Julia Reynoldsb5e44b72016-08-16 15:00:25 -0400733 */
734 public NotificationChannel getNotificationChannel(String channelId) {
735 INotificationManager service = getService();
736 try {
737 return service.getNotificationChannel(mContext.getPackageName(), channelId);
738 } catch (RemoteException e) {
739 throw e.rethrowFromSystemServer();
740 }
741 }
742
743 /**
Julia Reynolds0ffc13b2017-04-27 13:54:36 -0400744 * Returns all notification channels belonging to the calling package.
Julia Reynoldsb5e44b72016-08-16 15:00:25 -0400745 */
746 public List<NotificationChannel> getNotificationChannels() {
747 INotificationManager service = getService();
748 try {
749 return service.getNotificationChannels(mContext.getPackageName()).getList();
750 } catch (RemoteException e) {
751 throw e.rethrowFromSystemServer();
752 }
753 }
754
755 /**
Julia Reynoldsb5e44b72016-08-16 15:00:25 -0400756 * Deletes the given notification channel.
Julia Reynolds0ffc13b2017-04-27 13:54:36 -0400757 *
758 * <p>If you {@link #createNotificationChannel(NotificationChannel) create} a new channel with
759 * this same id, the deleted channel will be un-deleted with all of the same settings it
760 * had before it was deleted.
Julia Reynoldsb5e44b72016-08-16 15:00:25 -0400761 */
762 public void deleteNotificationChannel(String channelId) {
763 INotificationManager service = getService();
764 try {
765 service.deleteNotificationChannel(mContext.getPackageName(), channelId);
766 } catch (RemoteException e) {
767 throw e.rethrowFromSystemServer();
768 }
769 }
770
771 /**
Julia Reynolds3eb3ffd2017-11-16 10:11:32 -0500772 * Returns the notification channel group settings for a given channel group id.
773 *
774 * The channel group must belong to your package, or null will be returned.
775 */
776 public NotificationChannelGroup getNotificationChannelGroup(String channelGroupId) {
777 INotificationManager service = getService();
778 try {
779 return service.getNotificationChannelGroup(mContext.getPackageName(), channelGroupId);
780 } catch (RemoteException e) {
781 throw e.rethrowFromSystemServer();
782 }
783 }
784
785 /**
Julia Reynolds9bfba592017-03-15 14:03:55 -0400786 * Returns all notification channel groups belonging to the calling app.
787 */
788 public List<NotificationChannelGroup> getNotificationChannelGroups() {
789 INotificationManager service = getService();
790 try {
Beverlyc629ee42018-10-02 16:14:07 -0400791 final ParceledListSlice<NotificationChannelGroup> parceledList =
792 service.getNotificationChannelGroups(mContext.getPackageName());
793 if (parceledList != null) {
794 return parceledList.getList();
795 }
Julia Reynolds9bfba592017-03-15 14:03:55 -0400796 } catch (RemoteException e) {
797 throw e.rethrowFromSystemServer();
798 }
Beverlyc629ee42018-10-02 16:14:07 -0400799 return new ArrayList<>();
Julia Reynolds9bfba592017-03-15 14:03:55 -0400800 }
801
802 /**
Julia Reynolds0ffc13b2017-04-27 13:54:36 -0400803 * Deletes the given notification channel group, and all notification channels that
804 * belong to it.
Julia Reynolds9bfba592017-03-15 14:03:55 -0400805 */
806 public void deleteNotificationChannelGroup(String groupId) {
807 INotificationManager service = getService();
808 try {
809 service.deleteNotificationChannelGroup(mContext.getPackageName(), groupId);
810 } catch (RemoteException e) {
811 throw e.rethrowFromSystemServer();
812 }
813 }
814
815 /**
John Spurlockb4782522014-08-22 14:54:46 -0400816 * @hide
817 */
Julia Reynoldsb6c1f992016-11-22 09:26:46 -0500818 @TestApi
John Spurlockb4782522014-08-22 14:54:46 -0400819 public ComponentName getEffectsSuppressor() {
820 INotificationManager service = getService();
821 try {
822 return service.getEffectsSuppressor();
823 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -0700824 throw e.rethrowFromSystemServer();
John Spurlockb4782522014-08-22 14:54:46 -0400825 }
826 }
827
John Spurlock2b122f42014-08-27 16:29:47 -0400828 /**
829 * @hide
830 */
Julia Reynolds87621942019-01-29 16:19:36 -0500831 @TestApi
John Spurlock2b122f42014-08-27 16:29:47 -0400832 public boolean matchesCallFilter(Bundle extras) {
833 INotificationManager service = getService();
834 try {
835 return service.matchesCallFilter(extras);
836 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -0700837 throw e.rethrowFromSystemServer();
John Spurlock2b122f42014-08-27 16:29:47 -0400838 }
839 }
840
John Spurlock530052a2014-11-30 16:26:19 -0500841 /**
842 * @hide
843 */
844 public boolean isSystemConditionProviderEnabled(String path) {
845 INotificationManager service = getService();
846 try {
847 return service.isSystemConditionProviderEnabled(path);
848 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -0700849 throw e.rethrowFromSystemServer();
John Spurlock530052a2014-11-30 16:26:19 -0500850 }
851 }
852
John Spurlockcdb57ae2015-02-11 19:04:11 -0500853 /**
854 * @hide
855 */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100856 @UnsupportedAppUsage
John Spurlockb2278d62015-04-07 12:47:12 -0400857 public void setZenMode(int mode, Uri conditionId, String reason) {
John Spurlockcdb57ae2015-02-11 19:04:11 -0500858 INotificationManager service = getService();
859 try {
John Spurlockb2278d62015-04-07 12:47:12 -0400860 service.setZenMode(mode, conditionId, reason);
John Spurlockcdb57ae2015-02-11 19:04:11 -0500861 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -0700862 throw e.rethrowFromSystemServer();
John Spurlockcdb57ae2015-02-11 19:04:11 -0500863 }
864 }
865
866 /**
867 * @hide
868 */
John Spurlockb2278d62015-04-07 12:47:12 -0400869 public int getZenMode() {
John Spurlockcdb57ae2015-02-11 19:04:11 -0500870 INotificationManager service = getService();
871 try {
John Spurlockb2278d62015-04-07 12:47:12 -0400872 return service.getZenMode();
John Spurlockcdb57ae2015-02-11 19:04:11 -0500873 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -0700874 throw e.rethrowFromSystemServer();
John Spurlockcdb57ae2015-02-11 19:04:11 -0500875 }
876 }
877
878 /**
879 * @hide
880 */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100881 @UnsupportedAppUsage
John Spurlockb2278d62015-04-07 12:47:12 -0400882 public ZenModeConfig getZenModeConfig() {
John Spurlockcdb57ae2015-02-11 19:04:11 -0500883 INotificationManager service = getService();
884 try {
John Spurlockb2278d62015-04-07 12:47:12 -0400885 return service.getZenModeConfig();
John Spurlockcdb57ae2015-02-11 19:04:11 -0500886 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -0700887 throw e.rethrowFromSystemServer();
John Spurlockcdb57ae2015-02-11 19:04:11 -0500888 }
John Spurlockcdb57ae2015-02-11 19:04:11 -0500889 }
890
John Spurlock1fc476d2015-04-14 16:05:20 -0400891 /**
Julia Reynolds43b70cd2016-01-14 15:05:34 -0500892 * @hide
893 */
Beverlyff2df9b2018-10-10 16:54:10 -0400894 public NotificationManager.Policy getConsolidatedNotificationPolicy() {
895 INotificationManager service = getService();
896 try {
897 return service.getConsolidatedNotificationPolicy();
898 } catch (RemoteException e) {
899 throw e.rethrowFromSystemServer();
900 }
901 }
902
903 /**
904 * @hide
905 */
Julia Reynolds43b70cd2016-01-14 15:05:34 -0500906 public int getRuleInstanceCount(ComponentName owner) {
907 INotificationManager service = getService();
908 try {
909 return service.getRuleInstanceCount(owner);
910 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -0700911 throw e.rethrowFromSystemServer();
Julia Reynolds43b70cd2016-01-14 15:05:34 -0500912 }
Julia Reynolds43b70cd2016-01-14 15:05:34 -0500913 }
914
915 /**
Julia Reynoldsa47a27f2015-08-24 08:31:47 -0400916 * Returns AutomaticZenRules owned by the caller.
917 *
918 * <p>
Julia Reynolds361e82d32016-02-26 18:19:49 -0500919 * Throws a SecurityException if policy access is granted to this package.
Julia Reynoldsa47a27f2015-08-24 08:31:47 -0400920 * See {@link #isNotificationPolicyAccessGranted}.
921 */
Julia Reynolds361e82d32016-02-26 18:19:49 -0500922 public Map<String, AutomaticZenRule> getAutomaticZenRules() {
Julia Reynoldsa47a27f2015-08-24 08:31:47 -0400923 INotificationManager service = getService();
924 try {
Julia Reynolds361e82d32016-02-26 18:19:49 -0500925 List<ZenModeConfig.ZenRule> rules = service.getZenRules();
926 Map<String, AutomaticZenRule> ruleMap = new HashMap<>();
927 for (ZenModeConfig.ZenRule rule : rules) {
Julia Reynolds68062072018-08-06 15:38:21 -0400928 ruleMap.put(rule.id, new AutomaticZenRule(rule.name, rule.component,
929 rule.configurationActivity, rule.conditionId, rule.zenPolicy,
930 zenModeToInterruptionFilter(rule.zenMode), rule.enabled,
931 rule.creationTime));
Julia Reynolds361e82d32016-02-26 18:19:49 -0500932 }
933 return ruleMap;
Julia Reynoldsa47a27f2015-08-24 08:31:47 -0400934 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -0700935 throw e.rethrowFromSystemServer();
Julia Reynoldsa47a27f2015-08-24 08:31:47 -0400936 }
Julia Reynoldsa47a27f2015-08-24 08:31:47 -0400937 }
938
939 /**
Julia Reynolds4fe98d62015-10-06 16:23:41 -0400940 * Returns the AutomaticZenRule with the given id, if it exists and the caller has access.
Julia Reynoldsa47a27f2015-08-24 08:31:47 -0400941 *
942 * <p>
Julia Reynolds361e82d32016-02-26 18:19:49 -0500943 * Throws a SecurityException if policy access is granted to this package.
Julia Reynoldsa47a27f2015-08-24 08:31:47 -0400944 * See {@link #isNotificationPolicyAccessGranted}.
945 *
946 * <p>
Julia Reynolds4fe98d62015-10-06 16:23:41 -0400947 * 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 -0400948 * doesn't own the matching rule. See {@link AutomaticZenRule#getOwner}.
949 */
Julia Reynolds4fe98d62015-10-06 16:23:41 -0400950 public AutomaticZenRule getAutomaticZenRule(String id) {
Julia Reynoldsa47a27f2015-08-24 08:31:47 -0400951 INotificationManager service = getService();
952 try {
Julia Reynolds4fe98d62015-10-06 16:23:41 -0400953 return service.getAutomaticZenRule(id);
Julia Reynoldsa47a27f2015-08-24 08:31:47 -0400954 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -0700955 throw e.rethrowFromSystemServer();
Julia Reynoldsa47a27f2015-08-24 08:31:47 -0400956 }
Julia Reynoldsa47a27f2015-08-24 08:31:47 -0400957 }
958
959 /**
Julia Reynolds4fe98d62015-10-06 16:23:41 -0400960 * Creates the given zen rule.
Julia Reynoldsa47a27f2015-08-24 08:31:47 -0400961 *
962 * <p>
Julia Reynolds361e82d32016-02-26 18:19:49 -0500963 * Throws a SecurityException if policy access is granted to this package.
Julia Reynoldsa47a27f2015-08-24 08:31:47 -0400964 * See {@link #isNotificationPolicyAccessGranted}.
965 *
Julia Reynolds4fe98d62015-10-06 16:23:41 -0400966 * @param automaticZenRule the rule to create.
Julia Reynolds361e82d32016-02-26 18:19:49 -0500967 * @return The id of the newly created rule; null if the rule could not be created.
Julia Reynoldsa47a27f2015-08-24 08:31:47 -0400968 */
Julia Reynolds361e82d32016-02-26 18:19:49 -0500969 public String addAutomaticZenRule(AutomaticZenRule automaticZenRule) {
Julia Reynoldsa47a27f2015-08-24 08:31:47 -0400970 INotificationManager service = getService();
971 try {
Julia Reynolds4fe98d62015-10-06 16:23:41 -0400972 return service.addAutomaticZenRule(automaticZenRule);
Julia Reynoldsa47a27f2015-08-24 08:31:47 -0400973 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -0700974 throw e.rethrowFromSystemServer();
Julia Reynoldsa47a27f2015-08-24 08:31:47 -0400975 }
Julia Reynoldsa47a27f2015-08-24 08:31:47 -0400976 }
977
978 /**
Julia Reynolds4fe98d62015-10-06 16:23:41 -0400979 * Updates the given zen rule.
Julia Reynoldsa47a27f2015-08-24 08:31:47 -0400980 *
981 * <p>
Julia Reynolds361e82d32016-02-26 18:19:49 -0500982 * Throws a SecurityException if policy access is granted to this package.
Julia Reynoldsa47a27f2015-08-24 08:31:47 -0400983 * See {@link #isNotificationPolicyAccessGranted}.
984 *
985 * <p>
986 * Callers can only update rules that they own. See {@link AutomaticZenRule#getOwner}.
Julia Reynolds361e82d32016-02-26 18:19:49 -0500987 * @param id The id of the rule to update
Geoffrey Pitsche75a66e2016-11-22 11:12:11 -0500988 * @param automaticZenRule the rule to update.
Julia Reynoldsa47a27f2015-08-24 08:31:47 -0400989 * @return Whether the rule was successfully updated.
990 */
Julia Reynolds361e82d32016-02-26 18:19:49 -0500991 public boolean updateAutomaticZenRule(String id, AutomaticZenRule automaticZenRule) {
Julia Reynoldsa47a27f2015-08-24 08:31:47 -0400992 INotificationManager service = getService();
993 try {
Julia Reynolds361e82d32016-02-26 18:19:49 -0500994 return service.updateAutomaticZenRule(id, automaticZenRule);
Julia Reynoldsa47a27f2015-08-24 08:31:47 -0400995 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -0700996 throw e.rethrowFromSystemServer();
Julia Reynoldsa47a27f2015-08-24 08:31:47 -0400997 }
Julia Reynoldsa47a27f2015-08-24 08:31:47 -0400998 }
999
1000 /**
Julia Reynolds68062072018-08-06 15:38:21 -04001001 * Informs the notification manager that the state of an {@link AutomaticZenRule} has changed.
1002 * Use this method to put the system into Do Not Disturb mode or request that it exits Do Not
1003 * Disturb mode. The calling app must own the provided {@link android.app.AutomaticZenRule}.
1004 * <p>
1005 * This method can be used in conjunction with or as a replacement to
1006 * {@link android.service.notification.ConditionProviderService#notifyCondition(Condition)}.
1007 * </p>
1008 * @param id The id of the rule whose state should change
1009 * @param condition The new state of this rule
1010 */
1011 public void setAutomaticZenRuleState(String id, Condition condition) {
1012 INotificationManager service = getService();
1013 try {
1014 service.setAutomaticZenRuleState(id, condition);
1015 } catch (RemoteException e) {
1016 throw e.rethrowFromSystemServer();
1017 }
1018 }
1019
1020 /**
Julia Reynolds4fe98d62015-10-06 16:23:41 -04001021 * Deletes the automatic zen rule with the given id.
Julia Reynoldsa47a27f2015-08-24 08:31:47 -04001022 *
1023 * <p>
Julia Reynolds361e82d32016-02-26 18:19:49 -05001024 * Throws a SecurityException if policy access is granted to this package.
Julia Reynoldsa47a27f2015-08-24 08:31:47 -04001025 * See {@link #isNotificationPolicyAccessGranted}.
1026 *
1027 * <p>
1028 * Callers can only delete rules that they own. See {@link AutomaticZenRule#getOwner}.
Julia Reynolds4fe98d62015-10-06 16:23:41 -04001029 * @param id the id of the rule to delete.
Julia Reynoldsa47a27f2015-08-24 08:31:47 -04001030 * @return Whether the rule was successfully deleted.
1031 */
Julia Reynolds4fe98d62015-10-06 16:23:41 -04001032 public boolean removeAutomaticZenRule(String id) {
Julia Reynoldsa47a27f2015-08-24 08:31:47 -04001033 INotificationManager service = getService();
1034 try {
Julia Reynolds4fe98d62015-10-06 16:23:41 -04001035 return service.removeAutomaticZenRule(id);
Julia Reynoldsa47a27f2015-08-24 08:31:47 -04001036 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07001037 throw e.rethrowFromSystemServer();
Julia Reynoldsa47a27f2015-08-24 08:31:47 -04001038 }
Julia Reynoldsa47a27f2015-08-24 08:31:47 -04001039 }
1040
1041 /**
Julia Reynoldsc8e54e82015-11-30 16:43:05 -05001042 * Deletes all automatic zen rules owned by the given package.
1043 *
1044 * @hide
1045 */
1046 public boolean removeAutomaticZenRules(String packageName) {
1047 INotificationManager service = getService();
1048 try {
1049 return service.removeAutomaticZenRules(packageName);
1050 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07001051 throw e.rethrowFromSystemServer();
Julia Reynoldsc8e54e82015-11-30 16:43:05 -05001052 }
Julia Reynoldsc8e54e82015-11-30 16:43:05 -05001053 }
1054
Julia Reynolds0edb50c2016-02-26 14:08:25 -05001055 /**
Jeff Sharkey6503bd82017-04-19 23:24:18 -06001056 * Returns the user specified importance for notifications from the calling
1057 * package.
Julia Reynolds0edb50c2016-02-26 14:08:25 -05001058 */
Chris Wren5ab5c742016-05-10 15:32:23 -04001059 public @Importance int getImportance() {
Julia Reynolds81afbcd2016-02-09 14:54:08 -05001060 INotificationManager service = getService();
1061 try {
Julia Reynoldsef37f282016-02-12 09:11:27 -05001062 return service.getPackageImportance(mContext.getPackageName());
Julia Reynolds81afbcd2016-02-09 14:54:08 -05001063 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07001064 throw e.rethrowFromSystemServer();
Julia Reynolds81afbcd2016-02-09 14:54:08 -05001065 }
Julia Reynolds81afbcd2016-02-09 14:54:08 -05001066 }
1067
Julia Reynolds0edb50c2016-02-26 14:08:25 -05001068 /**
1069 * Returns whether notifications from the calling package are blocked.
1070 */
Julia Reynolds81afbcd2016-02-09 14:54:08 -05001071 public boolean areNotificationsEnabled() {
1072 INotificationManager service = getService();
1073 try {
1074 return service.areNotificationsEnabled(mContext.getPackageName());
1075 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07001076 throw e.rethrowFromSystemServer();
Julia Reynolds81afbcd2016-02-09 14:54:08 -05001077 }
Julia Reynolds81afbcd2016-02-09 14:54:08 -05001078 }
1079
Julia Reynolds33ab8a02018-12-17 16:19:52 -05001080
1081 /**
1082 * Sets whether notifications posted by this app can appear outside of the
1083 * notification shade, floating over other apps' content.
1084 *
1085 * <p>This value will be ignored for notifications that are posted to channels that do not
Mady Mellorc39b4ae2019-01-09 17:11:37 -08001086 * allow bubbles ({@link NotificationChannel#canBubble()}.
Julia Reynolds33ab8a02018-12-17 16:19:52 -05001087 *
Mady Mellorc39b4ae2019-01-09 17:11:37 -08001088 * @see Notification#getBubbleMetadata()
Julia Reynolds33ab8a02018-12-17 16:19:52 -05001089 */
Mady Mellorc39b4ae2019-01-09 17:11:37 -08001090 public boolean areBubblesAllowed() {
Julia Reynolds33ab8a02018-12-17 16:19:52 -05001091 INotificationManager service = getService();
1092 try {
Mady Mellorc39b4ae2019-01-09 17:11:37 -08001093 return service.areBubblesAllowed(mContext.getPackageName());
Julia Reynolds33ab8a02018-12-17 16:19:52 -05001094 } catch (RemoteException e) {
1095 throw e.rethrowFromSystemServer();
1096 }
1097 }
1098
Julia Reynoldsc8e54e82015-11-30 16:43:05 -05001099 /**
Julia Reynoldsb40cd092019-01-25 09:35:02 -05001100 * Returns whether notifications from this package are temporarily hidden. This
1101 * could be done because the package was marked as distracting to the user via
1102 * {@code PackageManager#setDistractingPackageRestrictions(String[], int)} or because the
1103 * package is {@code PackageManager#setPackagesSuspended(String[], boolean, PersistableBundle,
1104 * PersistableBundle, SuspendDialogInfo) suspended}.
1105 */
1106 public boolean areNotificationsPaused() {
1107 INotificationManager service = getService();
1108 try {
1109 return service.isPackagePaused(mContext.getPackageName());
1110 } catch (RemoteException e) {
1111 throw e.rethrowFromSystemServer();
1112 }
1113 }
1114
1115 /**
Beverly312ef3e2017-11-15 11:12:51 -05001116 * Checks the ability to modify notification do not disturb policy for the calling package.
John Spurlock1fc476d2015-04-14 16:05:20 -04001117 *
John Spurlock7c74f782015-06-04 13:01:42 -04001118 * <p>
Beverly312ef3e2017-11-15 11:12:51 -05001119 * Returns true if the calling package can modify notification policy.
John Spurlock7c74f782015-06-04 13:01:42 -04001120 *
1121 * <p>
Julia Reynoldsb852e562017-06-06 16:14:18 -04001122 * Apps can request policy access by sending the user to the activity that matches the system
1123 * intent action {@link android.provider.Settings#ACTION_NOTIFICATION_POLICY_ACCESS_SETTINGS}.
John Spurlock7c74f782015-06-04 13:01:42 -04001124 *
1125 * <p>
1126 * Use {@link #ACTION_NOTIFICATION_POLICY_ACCESS_GRANTED_CHANGED} to listen for
1127 * user grant or denial of this access.
John Spurlock1fc476d2015-04-14 16:05:20 -04001128 */
John Spurlock80774932015-05-07 17:38:50 -04001129 public boolean isNotificationPolicyAccessGranted() {
John Spurlock1fc476d2015-04-14 16:05:20 -04001130 INotificationManager service = getService();
1131 try {
John Spurlock80774932015-05-07 17:38:50 -04001132 return service.isNotificationPolicyAccessGranted(mContext.getOpPackageName());
1133 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07001134 throw e.rethrowFromSystemServer();
John Spurlock80774932015-05-07 17:38:50 -04001135 }
John Spurlock80774932015-05-07 17:38:50 -04001136 }
1137
Julia Reynoldsb852e562017-06-06 16:14:18 -04001138 /**
1139 * Checks whether the user has approved a given
1140 * {@link android.service.notification.NotificationListenerService}.
1141 *
1142 * <p>
1143 * The listener service must belong to the calling app.
1144 *
1145 * <p>
1146 * Apps can request notification listener access by sending the user to the activity that
1147 * matches the system intent action
1148 * {@link android.provider.Settings#ACTION_NOTIFICATION_LISTENER_SETTINGS}.
1149 */
1150 public boolean isNotificationListenerAccessGranted(ComponentName listener) {
1151 INotificationManager service = getService();
1152 try {
1153 return service.isNotificationListenerAccessGranted(listener);
1154 } catch (RemoteException e) {
1155 throw e.rethrowFromSystemServer();
1156 }
1157 }
1158
Fabian Kozynskid9425662019-01-29 13:08:30 -05001159 /**
1160 * Checks whether the user has approved a given
1161 * {@link android.service.notification.NotificationAssistantService}.
1162 *
1163 * <p>
1164 * The assistant service must belong to the calling app.
1165 *
1166 * <p>
1167 * Apps can request notification assistant access by sending the user to the activity that
1168 * matches the system intent action
1169 * TODO: STOPSHIP: Add correct intent
1170 * {@link android.provider.Settings#ACTION_MANAGE_DEFAULT_APPS_SETTINGS}.
1171 */
Julia Reynoldsb852e562017-06-06 16:14:18 -04001172 public boolean isNotificationAssistantAccessGranted(ComponentName assistant) {
1173 INotificationManager service = getService();
1174 try {
1175 return service.isNotificationAssistantAccessGranted(assistant);
1176 } catch (RemoteException e) {
1177 throw e.rethrowFromSystemServer();
1178 }
1179 }
1180
Julia Reynolds12ad7ca2019-01-28 09:29:16 -05001181 /**
1182 * Returns whether the user wants silent notifications (see {@link #IMPORTANCE_LOW} to appear
1183 * in the status bar.
1184 *
1185 * <p>Only available for {@link #isNotificationListenerAccessGranted(ComponentName) notification
1186 * listeners}.
1187 */
1188 public boolean shouldHideSilentStatusBarIcons() {
1189 INotificationManager service = getService();
1190 try {
1191 return service.shouldHideSilentStatusIcons(mContext.getOpPackageName());
1192 } catch (RemoteException e) {
1193 throw e.rethrowFromSystemServer();
1194 }
1195 }
1196
John Spurlock80774932015-05-07 17:38:50 -04001197 /** @hide */
1198 public boolean isNotificationPolicyAccessGrantedForPackage(String pkg) {
1199 INotificationManager service = getService();
1200 try {
1201 return service.isNotificationPolicyAccessGrantedForPackage(pkg);
John Spurlock1fc476d2015-04-14 16:05:20 -04001202 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07001203 throw e.rethrowFromSystemServer();
John Spurlock1fc476d2015-04-14 16:05:20 -04001204 }
John Spurlock1fc476d2015-04-14 16:05:20 -04001205 }
1206
1207 /**
Julia Reynoldsb852e562017-06-06 16:14:18 -04001208 * @hide
1209 */
1210 public List<String> getEnabledNotificationListenerPackages() {
1211 INotificationManager service = getService();
1212 try {
1213 return service.getEnabledNotificationListenerPackages();
1214 } catch (RemoteException e) {
1215 throw e.rethrowFromSystemServer();
1216 }
1217 }
1218
1219 /**
Beverlyff2df9b2018-10-10 16:54:10 -04001220 * Gets the current user-specified default notification policy.
John Spurlock1fc476d2015-04-14 16:05:20 -04001221 *
John Spurlock80774932015-05-07 17:38:50 -04001222 * <p>
John Spurlock1fc476d2015-04-14 16:05:20 -04001223 */
John Spurlock80774932015-05-07 17:38:50 -04001224 public Policy getNotificationPolicy() {
John Spurlock1fc476d2015-04-14 16:05:20 -04001225 INotificationManager service = getService();
1226 try {
John Spurlock80774932015-05-07 17:38:50 -04001227 return service.getNotificationPolicy(mContext.getOpPackageName());
John Spurlock1fc476d2015-04-14 16:05:20 -04001228 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07001229 throw e.rethrowFromSystemServer();
John Spurlock1fc476d2015-04-14 16:05:20 -04001230 }
John Spurlock1fc476d2015-04-14 16:05:20 -04001231 }
1232
1233 /**
1234 * Sets the current notification policy.
1235 *
John Spurlock80774932015-05-07 17:38:50 -04001236 * <p>
John Spurlock7c74f782015-06-04 13:01:42 -04001237 * Only available if policy access is granted to this package.
1238 * See {@link #isNotificationPolicyAccessGranted}.
John Spurlock80774932015-05-07 17:38:50 -04001239 *
John Spurlock1fc476d2015-04-14 16:05:20 -04001240 * @param policy The new desired policy.
1241 */
John Spurlock80774932015-05-07 17:38:50 -04001242 public void setNotificationPolicy(@NonNull Policy policy) {
John Spurlock1fc476d2015-04-14 16:05:20 -04001243 checkRequired("policy", policy);
1244 INotificationManager service = getService();
1245 try {
John Spurlock80774932015-05-07 17:38:50 -04001246 service.setNotificationPolicy(mContext.getOpPackageName(), policy);
John Spurlock1fc476d2015-04-14 16:05:20 -04001247 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07001248 throw e.rethrowFromSystemServer();
John Spurlock1fc476d2015-04-14 16:05:20 -04001249 }
1250 }
1251
John Spurlock80774932015-05-07 17:38:50 -04001252 /** @hide */
1253 public void setNotificationPolicyAccessGranted(String pkg, boolean granted) {
1254 INotificationManager service = getService();
1255 try {
1256 service.setNotificationPolicyAccessGranted(pkg, granted);
1257 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07001258 throw e.rethrowFromSystemServer();
John Spurlock80774932015-05-07 17:38:50 -04001259 }
1260 }
1261
1262 /** @hide */
Julia Reynoldsb852e562017-06-06 16:14:18 -04001263 public void setNotificationListenerAccessGranted(ComponentName listener, boolean granted) {
John Spurlock80774932015-05-07 17:38:50 -04001264 INotificationManager service = getService();
1265 try {
Julia Reynoldsb852e562017-06-06 16:14:18 -04001266 service.setNotificationListenerAccessGranted(listener, granted);
John Spurlock80774932015-05-07 17:38:50 -04001267 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07001268 throw e.rethrowFromSystemServer();
John Spurlock80774932015-05-07 17:38:50 -04001269 }
Julia Reynoldsb852e562017-06-06 16:14:18 -04001270 }
1271
1272 /** @hide */
1273 public void setNotificationListenerAccessGrantedForUser(ComponentName listener, int userId,
1274 boolean granted) {
1275 INotificationManager service = getService();
1276 try {
1277 service.setNotificationListenerAccessGrantedForUser(listener, userId, granted);
1278 } catch (RemoteException e) {
1279 throw e.rethrowFromSystemServer();
1280 }
1281 }
1282
Fabian Kozynskid9425662019-01-29 13:08:30 -05001283 /**
1284 * Grants/revokes Notification Assistant access to {@code assistant} for current user.
1285 *
1286 * @param assistant Name of component to grant/revoke access or {@code null} to revoke access to
1287 * current assistant
1288 * @param granted Grant/revoke access
1289 * @hide
1290 */
1291 @SystemApi
1292 public void setNotificationAssistantAccessGranted(ComponentName assistant, boolean granted) {
1293 INotificationManager service = getService();
1294 try {
1295 service.setNotificationAssistantAccessGranted(assistant, granted);
1296 } catch (RemoteException e) {
1297 throw e.rethrowFromSystemServer();
1298 }
1299 }
1300
1301 /**
1302 * Grants/revokes Notification Assistant access to {@code assistant} for given user.
1303 *
1304 * @param assistant Name of component to grant/revoke access or {@code null} to revoke access to
1305 * current assistant
1306 * @param user handle to associate assistant with
1307 * @param granted Grant/revoke access
1308 * @hide
1309 */
1310 @SystemApi
1311 public void setNotificationAssistantAccessGrantedForUser(ComponentName assistant,
1312 UserHandle user, boolean granted) {
1313 INotificationManager service = getService();
1314 try {
1315 service.setNotificationAssistantAccessGrantedForUser(assistant, user.getIdentifier(),
1316 granted);
1317 } catch (RemoteException e) {
1318 throw e.rethrowFromSystemServer();
1319 }
1320 }
1321
Julia Reynoldsb852e562017-06-06 16:14:18 -04001322 /** @hide */
1323 public List<ComponentName> getEnabledNotificationListeners(int userId) {
1324 INotificationManager service = getService();
1325 try {
1326 return service.getEnabledNotificationListeners(userId);
1327 } catch (RemoteException e) {
1328 throw e.rethrowFromSystemServer();
1329 }
John Spurlock80774932015-05-07 17:38:50 -04001330 }
1331
Fabian Kozynskid9425662019-01-29 13:08:30 -05001332 /** @hide */
1333 @SystemApi
1334 public @Nullable ComponentName getAllowedNotificationAssistantForUser(UserHandle user) {
1335 INotificationManager service = getService();
1336 try {
1337 return service.getAllowedNotificationAssistantForUser(user.getIdentifier());
1338 } catch (RemoteException e) {
1339 throw e.rethrowFromSystemServer();
1340 }
1341 }
1342
1343 /** @hide */
1344 @SystemApi
1345 public @Nullable ComponentName getAllowedNotificationAssistant() {
1346 INotificationManager service = getService();
1347 try {
1348 return service.getAllowedNotificationAssistant();
1349 } catch (RemoteException e) {
1350 throw e.rethrowFromSystemServer();
1351 }
1352 }
1353
1354
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001355 private Context mContext;
John Spurlock1fc476d2015-04-14 16:05:20 -04001356
1357 private static void checkRequired(String name, Object value) {
1358 if (value == null) {
1359 throw new IllegalArgumentException(name + " is required");
1360 }
1361 }
1362
1363 /**
1364 * Notification policy configuration. Represents user-preferences for notification
Julia Reynoldscedacef2016-03-04 08:18:47 -05001365 * filtering.
John Spurlock1fc476d2015-04-14 16:05:20 -04001366 */
1367 public static class Policy implements android.os.Parcelable {
1368 /** Reminder notifications are prioritized. */
1369 public static final int PRIORITY_CATEGORY_REMINDERS = 1 << 0;
1370 /** Event notifications are prioritized. */
1371 public static final int PRIORITY_CATEGORY_EVENTS = 1 << 1;
1372 /** Message notifications are prioritized. */
1373 public static final int PRIORITY_CATEGORY_MESSAGES = 1 << 2;
1374 /** Calls are prioritized. */
1375 public static final int PRIORITY_CATEGORY_CALLS = 1 << 3;
1376 /** Calls from repeat callers are prioritized. */
1377 public static final int PRIORITY_CATEGORY_REPEAT_CALLERS = 1 << 4;
Beverly04216872017-09-28 10:55:32 -04001378 /** Alarms are prioritized */
1379 public static final int PRIORITY_CATEGORY_ALARMS = 1 << 5;
Beverlyd6964762018-02-16 14:07:03 -05001380 /** Media, game, voice navigation are prioritized */
1381 public static final int PRIORITY_CATEGORY_MEDIA = 1 << 6;
1382 /**System (catch-all for non-never suppressible sounds) are prioritized */
1383 public static final int PRIORITY_CATEGORY_SYSTEM = 1 << 7;
John Spurlock1fc476d2015-04-14 16:05:20 -04001384
Beverlyd6964762018-02-16 14:07:03 -05001385 /**
1386 * @hide
1387 */
1388 public static final int[] ALL_PRIORITY_CATEGORIES = {
Beverly04216872017-09-28 10:55:32 -04001389 PRIORITY_CATEGORY_ALARMS,
Beverlyd6964762018-02-16 14:07:03 -05001390 PRIORITY_CATEGORY_MEDIA,
1391 PRIORITY_CATEGORY_SYSTEM,
John Spurlock1fc476d2015-04-14 16:05:20 -04001392 PRIORITY_CATEGORY_REMINDERS,
1393 PRIORITY_CATEGORY_EVENTS,
1394 PRIORITY_CATEGORY_MESSAGES,
1395 PRIORITY_CATEGORY_CALLS,
1396 PRIORITY_CATEGORY_REPEAT_CALLERS,
1397 };
1398
1399 /** Any sender is prioritized. */
1400 public static final int PRIORITY_SENDERS_ANY = 0;
1401 /** Saved contacts are prioritized. */
1402 public static final int PRIORITY_SENDERS_CONTACTS = 1;
1403 /** Only starred contacts are prioritized. */
1404 public static final int PRIORITY_SENDERS_STARRED = 2;
1405
1406 /** Notification categories to prioritize. Bitmask of PRIORITY_CATEGORY_* constants. */
1407 public final int priorityCategories;
1408
John Spurlock80774932015-05-07 17:38:50 -04001409 /** Notification senders to prioritize for calls. One of:
John Spurlock1fc476d2015-04-14 16:05:20 -04001410 * PRIORITY_SENDERS_ANY, PRIORITY_SENDERS_CONTACTS, PRIORITY_SENDERS_STARRED */
John Spurlock80774932015-05-07 17:38:50 -04001411 public final int priorityCallSenders;
John Spurlock1fc476d2015-04-14 16:05:20 -04001412
John Spurlock80774932015-05-07 17:38:50 -04001413 /** Notification senders to prioritize for messages. One of:
1414 * PRIORITY_SENDERS_ANY, PRIORITY_SENDERS_CONTACTS, PRIORITY_SENDERS_STARRED */
1415 public final int priorityMessageSenders;
1416
Julia Reynoldsd5607292016-02-05 15:25:58 -05001417 /**
1418 * @hide
1419 */
Julia Reynoldsf612869ae2015-11-05 16:48:55 -05001420 public static final int SUPPRESSED_EFFECTS_UNSET = -1;
Julia Reynoldsccc6ae62018-03-01 16:24:49 -05001421
Julia Reynoldsd5607292016-02-05 15:25:58 -05001422 /**
Julia Reynoldscedacef2016-03-04 08:18:47 -05001423 * Whether notifications suppressed by DND should not interrupt visually (e.g. with
1424 * notification lights or by turning the screen on) when the screen is off.
Julia Reynoldsccc6ae62018-03-01 16:24:49 -05001425 *
1426 * @deprecated use {@link #SUPPRESSED_EFFECT_FULL_SCREEN_INTENT} and
1427 * {@link #SUPPRESSED_EFFECT_AMBIENT} and {@link #SUPPRESSED_EFFECT_LIGHTS} individually.
Julia Reynoldsd5607292016-02-05 15:25:58 -05001428 */
Julia Reynoldsccc6ae62018-03-01 16:24:49 -05001429 @Deprecated
Julia Reynoldsd5607292016-02-05 15:25:58 -05001430 public static final int SUPPRESSED_EFFECT_SCREEN_OFF = 1 << 0;
1431 /**
Julia Reynoldscedacef2016-03-04 08:18:47 -05001432 * Whether notifications suppressed by DND should not interrupt visually when the screen
1433 * is on (e.g. by peeking onto the screen).
Julia Reynoldsccc6ae62018-03-01 16:24:49 -05001434 *
1435 * @deprecated use {@link #SUPPRESSED_EFFECT_PEEK}.
Julia Reynoldsd5607292016-02-05 15:25:58 -05001436 */
Julia Reynoldsccc6ae62018-03-01 16:24:49 -05001437 @Deprecated
Julia Reynoldsd5607292016-02-05 15:25:58 -05001438 public static final int SUPPRESSED_EFFECT_SCREEN_ON = 1 << 1;
Julia Reynoldsf612869ae2015-11-05 16:48:55 -05001439
Julia Reynoldsccc6ae62018-03-01 16:24:49 -05001440 /**
1441 * Whether {@link Notification#fullScreenIntent full screen intents} from
1442 * notifications intercepted by DND are blocked.
1443 */
1444 public static final int SUPPRESSED_EFFECT_FULL_SCREEN_INTENT = 1 << 2;
1445
1446 /**
1447 * Whether {@link NotificationChannel#shouldShowLights() notification lights} from
1448 * notifications intercepted by DND are blocked.
1449 */
1450 public static final int SUPPRESSED_EFFECT_LIGHTS = 1 << 3;
1451
1452 /**
1453 * Whether notifications intercepted by DND are prevented from peeking.
1454 */
1455 public static final int SUPPRESSED_EFFECT_PEEK = 1 << 4;
1456
1457 /**
1458 * Whether notifications intercepted by DND are prevented from appearing in the status bar,
1459 * on devices that support status bars.
1460 */
1461 public static final int SUPPRESSED_EFFECT_STATUS_BAR = 1 << 5;
1462
1463 /**
1464 * Whether {@link NotificationChannel#canShowBadge() badges} from
1465 * notifications intercepted by DND are blocked on devices that support badging.
1466 */
1467 public static final int SUPPRESSED_EFFECT_BADGE = 1 << 6;
1468
1469 /**
1470 * Whether notification intercepted by DND are prevented from appearing on ambient displays
1471 * on devices that support ambient display.
1472 */
1473 public static final int SUPPRESSED_EFFECT_AMBIENT = 1 << 7;
1474
1475 /**
1476 * Whether notification intercepted by DND are prevented from appearing in notification
1477 * list views like the notification shade or lockscreen on devices that support those
1478 * views.
1479 */
1480 public static final int SUPPRESSED_EFFECT_NOTIFICATION_LIST = 1 << 8;
1481
Julia Reynoldsf612869ae2015-11-05 16:48:55 -05001482 private static final int[] ALL_SUPPRESSED_EFFECTS = {
Julia Reynoldsd5607292016-02-05 15:25:58 -05001483 SUPPRESSED_EFFECT_SCREEN_OFF,
Julia Reynolds61721582016-01-05 08:35:25 -05001484 SUPPRESSED_EFFECT_SCREEN_ON,
Julia Reynoldsccc6ae62018-03-01 16:24:49 -05001485 SUPPRESSED_EFFECT_FULL_SCREEN_INTENT,
1486 SUPPRESSED_EFFECT_LIGHTS,
1487 SUPPRESSED_EFFECT_PEEK,
1488 SUPPRESSED_EFFECT_STATUS_BAR,
1489 SUPPRESSED_EFFECT_BADGE,
1490 SUPPRESSED_EFFECT_AMBIENT,
1491 SUPPRESSED_EFFECT_NOTIFICATION_LIST
Julia Reynoldsf612869ae2015-11-05 16:48:55 -05001492 };
1493
Julia Reynolds47f42802018-04-09 08:47:39 -04001494 private static final int[] SCREEN_OFF_SUPPRESSED_EFFECTS = {
1495 SUPPRESSED_EFFECT_SCREEN_OFF,
1496 SUPPRESSED_EFFECT_FULL_SCREEN_INTENT,
1497 SUPPRESSED_EFFECT_LIGHTS,
1498 SUPPRESSED_EFFECT_AMBIENT,
1499 };
1500
1501 private static final int[] SCREEN_ON_SUPPRESSED_EFFECTS = {
1502 SUPPRESSED_EFFECT_SCREEN_ON,
1503 SUPPRESSED_EFFECT_PEEK,
1504 SUPPRESSED_EFFECT_STATUS_BAR,
1505 SUPPRESSED_EFFECT_BADGE,
1506 SUPPRESSED_EFFECT_NOTIFICATION_LIST
1507 };
1508
Julia Reynoldsf612869ae2015-11-05 16:48:55 -05001509 /**
1510 * Visual effects to suppress for a notification that is filtered by Do Not Disturb mode.
1511 * Bitmask of SUPPRESSED_EFFECT_* constants.
1512 */
1513 public final int suppressedVisualEffects;
1514
Julia Reynoldscedacef2016-03-04 08:18:47 -05001515 /**
Beverly86d076f2018-04-17 14:44:52 -04001516 * @hide
1517 */
1518 public static final int STATE_CHANNELS_BYPASSING_DND = 1 << 0;
1519
1520 /**
1521 * @hide
1522 */
1523 public static final int STATE_UNSET = -1;
1524
1525 /**
1526 * Notification state information that is necessary to determine Do Not Disturb behavior.
1527 * Bitmask of STATE_* constants.
1528 * @hide
1529 */
1530 public final int state;
1531
1532 /**
Julia Reynoldscedacef2016-03-04 08:18:47 -05001533 * Constructs a policy for Do Not Disturb priority mode behavior.
1534 *
Julia Reynoldsccc6ae62018-03-01 16:24:49 -05001535 * <p>
1536 * Apps that target API levels below {@link Build.VERSION_CODES#P} cannot
1537 * change user-designated values to allow or disallow
1538 * {@link Policy#PRIORITY_CATEGORY_ALARMS}, {@link Policy#PRIORITY_CATEGORY_SYSTEM}, and
1539 * {@link Policy#PRIORITY_CATEGORY_MEDIA} from bypassing dnd.
1540 *
Julia Reynoldscedacef2016-03-04 08:18:47 -05001541 * @param priorityCategories bitmask of categories of notifications that can bypass DND.
1542 * @param priorityCallSenders which callers can bypass DND.
1543 * @param priorityMessageSenders which message senders can bypass DND.
1544 */
John Spurlock80774932015-05-07 17:38:50 -04001545 public Policy(int priorityCategories, int priorityCallSenders, int priorityMessageSenders) {
Julia Reynoldsf612869ae2015-11-05 16:48:55 -05001546 this(priorityCategories, priorityCallSenders, priorityMessageSenders,
Beverly86d076f2018-04-17 14:44:52 -04001547 SUPPRESSED_EFFECTS_UNSET, STATE_UNSET);
Julia Reynoldsf612869ae2015-11-05 16:48:55 -05001548 }
1549
Julia Reynoldscedacef2016-03-04 08:18:47 -05001550 /**
1551 * Constructs a policy for Do Not Disturb priority mode behavior.
1552 *
Julia Reynoldsccc6ae62018-03-01 16:24:49 -05001553 * <p>
1554 * Apps that target API levels below {@link Build.VERSION_CODES#P} cannot
1555 * change user-designated values to allow or disallow
1556 * {@link Policy#PRIORITY_CATEGORY_ALARMS}, {@link Policy#PRIORITY_CATEGORY_SYSTEM}, and
1557 * {@link Policy#PRIORITY_CATEGORY_MEDIA} from bypassing dnd.
1558 * <p>
1559 * Additionally, apps that target API levels below {@link Build.VERSION_CODES#P} can
1560 * only modify the {@link #SUPPRESSED_EFFECT_SCREEN_ON} and
1561 * {@link #SUPPRESSED_EFFECT_SCREEN_OFF} bits of the suppressed visual effects field.
1562 * All other suppressed effects will be ignored and reconstituted from the screen on
1563 * and screen off values.
1564 * <p>
1565 * Apps that target {@link Build.VERSION_CODES#P} or above can set any
1566 * suppressed visual effects. However, if any suppressed effects >
1567 * {@link #SUPPRESSED_EFFECT_SCREEN_ON} are set, {@link #SUPPRESSED_EFFECT_SCREEN_ON}
1568 * and {@link #SUPPRESSED_EFFECT_SCREEN_OFF} will be ignored and reconstituted from
1569 * the more specific suppressed visual effect bits. Apps should migrate to targeting
1570 * specific effects instead of the deprecated {@link #SUPPRESSED_EFFECT_SCREEN_ON} and
1571 * {@link #SUPPRESSED_EFFECT_SCREEN_OFF} effects.
1572 *
Julia Reynoldscedacef2016-03-04 08:18:47 -05001573 * @param priorityCategories bitmask of categories of notifications that can bypass DND.
1574 * @param priorityCallSenders which callers can bypass DND.
1575 * @param priorityMessageSenders which message senders can bypass DND.
1576 * @param suppressedVisualEffects which visual interruptions should be suppressed from
1577 * notifications that are filtered by DND.
1578 */
Julia Reynoldsf612869ae2015-11-05 16:48:55 -05001579 public Policy(int priorityCategories, int priorityCallSenders, int priorityMessageSenders,
1580 int suppressedVisualEffects) {
John Spurlock1fc476d2015-04-14 16:05:20 -04001581 this.priorityCategories = priorityCategories;
John Spurlock80774932015-05-07 17:38:50 -04001582 this.priorityCallSenders = priorityCallSenders;
1583 this.priorityMessageSenders = priorityMessageSenders;
Julia Reynoldsf612869ae2015-11-05 16:48:55 -05001584 this.suppressedVisualEffects = suppressedVisualEffects;
Beverly86d076f2018-04-17 14:44:52 -04001585 this.state = STATE_UNSET;
1586 }
1587
1588 /** @hide */
1589 public Policy(int priorityCategories, int priorityCallSenders, int priorityMessageSenders,
1590 int suppressedVisualEffects, int state) {
1591 this.priorityCategories = priorityCategories;
1592 this.priorityCallSenders = priorityCallSenders;
1593 this.priorityMessageSenders = priorityMessageSenders;
1594 this.suppressedVisualEffects = suppressedVisualEffects;
1595 this.state = state;
John Spurlock1fc476d2015-04-14 16:05:20 -04001596 }
1597
1598 /** @hide */
1599 public Policy(Parcel source) {
Beverly86d076f2018-04-17 14:44:52 -04001600 this(source.readInt(), source.readInt(), source.readInt(), source.readInt(),
1601 source.readInt());
John Spurlock1fc476d2015-04-14 16:05:20 -04001602 }
1603
1604 @Override
1605 public void writeToParcel(Parcel dest, int flags) {
1606 dest.writeInt(priorityCategories);
John Spurlock80774932015-05-07 17:38:50 -04001607 dest.writeInt(priorityCallSenders);
1608 dest.writeInt(priorityMessageSenders);
Julia Reynoldsf612869ae2015-11-05 16:48:55 -05001609 dest.writeInt(suppressedVisualEffects);
Beverly86d076f2018-04-17 14:44:52 -04001610 dest.writeInt(state);
John Spurlock1fc476d2015-04-14 16:05:20 -04001611 }
1612
1613 @Override
1614 public int describeContents() {
1615 return 0;
1616 }
1617
1618 @Override
1619 public int hashCode() {
Julia Reynoldsf612869ae2015-11-05 16:48:55 -05001620 return Objects.hash(priorityCategories, priorityCallSenders, priorityMessageSenders,
1621 suppressedVisualEffects);
John Spurlock1fc476d2015-04-14 16:05:20 -04001622 }
1623
1624 @Override
1625 public boolean equals(Object o) {
1626 if (!(o instanceof Policy)) return false;
1627 if (o == this) return true;
1628 final Policy other = (Policy) o;
1629 return other.priorityCategories == priorityCategories
John Spurlock80774932015-05-07 17:38:50 -04001630 && other.priorityCallSenders == priorityCallSenders
Julia Reynoldsf612869ae2015-11-05 16:48:55 -05001631 && other.priorityMessageSenders == priorityMessageSenders
Beverly9cb05c92018-11-28 10:03:23 -05001632 && suppressedVisualEffectsEqual(suppressedVisualEffects,
1633 other.suppressedVisualEffects);
1634 }
1635
1636
1637 private boolean suppressedVisualEffectsEqual(int suppressedEffects,
1638 int otherSuppressedVisualEffects) {
1639 if (suppressedEffects == otherSuppressedVisualEffects) {
1640 return true;
1641 }
1642
1643 if ((suppressedEffects & SUPPRESSED_EFFECT_SCREEN_ON) != 0) {
1644 suppressedEffects |= SUPPRESSED_EFFECT_PEEK;
1645 }
1646 if ((suppressedEffects & SUPPRESSED_EFFECT_SCREEN_OFF) != 0) {
1647 suppressedEffects |= SUPPRESSED_EFFECT_FULL_SCREEN_INTENT;
1648 suppressedEffects |= SUPPRESSED_EFFECT_LIGHTS;
1649 suppressedEffects |= SUPPRESSED_EFFECT_AMBIENT;
1650 }
1651
1652 if ((otherSuppressedVisualEffects & SUPPRESSED_EFFECT_SCREEN_ON) != 0) {
1653 otherSuppressedVisualEffects |= SUPPRESSED_EFFECT_PEEK;
1654 }
1655 if ((otherSuppressedVisualEffects & SUPPRESSED_EFFECT_SCREEN_OFF) != 0) {
1656 otherSuppressedVisualEffects |= SUPPRESSED_EFFECT_FULL_SCREEN_INTENT;
1657 otherSuppressedVisualEffects |= SUPPRESSED_EFFECT_LIGHTS;
1658 otherSuppressedVisualEffects |= SUPPRESSED_EFFECT_AMBIENT;
1659 }
1660
1661 if ((suppressedEffects & SUPPRESSED_EFFECT_SCREEN_ON)
1662 != (otherSuppressedVisualEffects & SUPPRESSED_EFFECT_SCREEN_ON)) {
1663 int currSuppressedEffects = (suppressedEffects & SUPPRESSED_EFFECT_SCREEN_ON) != 0
1664 ? otherSuppressedVisualEffects : suppressedEffects;
1665 if ((currSuppressedEffects & SUPPRESSED_EFFECT_PEEK) == 0) {
1666 return false;
1667 }
1668 }
1669
1670 if ((suppressedEffects & SUPPRESSED_EFFECT_SCREEN_OFF)
1671 != (otherSuppressedVisualEffects & SUPPRESSED_EFFECT_SCREEN_OFF)) {
1672 int currSuppressedEffects = (suppressedEffects & SUPPRESSED_EFFECT_SCREEN_OFF) != 0
1673 ? otherSuppressedVisualEffects : suppressedEffects;
1674 if ((currSuppressedEffects & SUPPRESSED_EFFECT_FULL_SCREEN_INTENT) == 0
1675 || (currSuppressedEffects & SUPPRESSED_EFFECT_LIGHTS) == 0
1676 || (currSuppressedEffects & SUPPRESSED_EFFECT_AMBIENT) == 0) {
1677 return false;
1678 }
1679 }
1680
1681 int thisWithoutOldEffects = suppressedEffects
1682 & ~SUPPRESSED_EFFECT_SCREEN_ON
1683 & ~SUPPRESSED_EFFECT_SCREEN_OFF;
1684 int otherWithoutOldEffects = otherSuppressedVisualEffects
1685 & ~SUPPRESSED_EFFECT_SCREEN_ON
1686 & ~SUPPRESSED_EFFECT_SCREEN_OFF;
1687 return thisWithoutOldEffects == otherWithoutOldEffects;
John Spurlock1fc476d2015-04-14 16:05:20 -04001688 }
1689
1690 @Override
1691 public String toString() {
1692 return "NotificationManager.Policy["
1693 + "priorityCategories=" + priorityCategoriesToString(priorityCategories)
John Spurlock80774932015-05-07 17:38:50 -04001694 + ",priorityCallSenders=" + prioritySendersToString(priorityCallSenders)
1695 + ",priorityMessageSenders=" + prioritySendersToString(priorityMessageSenders)
Julia Reynoldsf612869ae2015-11-05 16:48:55 -05001696 + ",suppressedVisualEffects="
1697 + suppressedEffectsToString(suppressedVisualEffects)
Beverly86d076f2018-04-17 14:44:52 -04001698 + ",areChannelsBypassingDnd=" + (((state & STATE_CHANNELS_BYPASSING_DND) != 0)
1699 ? "true" : "false")
John Spurlock1fc476d2015-04-14 16:05:20 -04001700 + "]";
1701 }
1702
Kweku Adams5ec78cd2017-09-25 16:29:54 -07001703 /** @hide */
Kweku Adamsbc84aec2018-01-23 13:33:12 -08001704 public void writeToProto(ProtoOutputStream proto, long fieldId) {
Kweku Adams5ec78cd2017-09-25 16:29:54 -07001705 final long pToken = proto.start(fieldId);
1706
1707 bitwiseToProtoEnum(proto, PolicyProto.PRIORITY_CATEGORIES, priorityCategories);
1708 proto.write(PolicyProto.PRIORITY_CALL_SENDER, priorityCallSenders);
1709 proto.write(PolicyProto.PRIORITY_MESSAGE_SENDER, priorityMessageSenders);
1710 bitwiseToProtoEnum(
1711 proto, PolicyProto.SUPPRESSED_VISUAL_EFFECTS, suppressedVisualEffects);
1712
1713 proto.end(pToken);
1714 }
1715
1716 private static void bitwiseToProtoEnum(ProtoOutputStream proto, long fieldId, int data) {
1717 for (int i = 1; data > 0; ++i, data >>>= 1) {
1718 if ((data & 1) == 1) {
1719 proto.write(fieldId, i);
1720 }
1721 }
1722 }
1723
Julia Reynoldsccc6ae62018-03-01 16:24:49 -05001724 /**
1725 * @hide
1726 */
1727 public static int getAllSuppressedVisualEffects() {
1728 int effects = 0;
1729 for (int i = 0; i < ALL_SUPPRESSED_EFFECTS.length; i++) {
1730 effects |= ALL_SUPPRESSED_EFFECTS[i];
1731 }
1732 return effects;
1733 }
1734
1735 /**
1736 * @hide
1737 */
1738 public static boolean areAllVisualEffectsSuppressed(int effects) {
1739 for (int i = 0; i < ALL_SUPPRESSED_EFFECTS.length; i++) {
1740 final int effect = ALL_SUPPRESSED_EFFECTS[i];
1741 if ((effects & effect) == 0) {
1742 return false;
1743 }
1744 }
1745 return true;
1746 }
1747
Julia Reynolds9aa1c9e2018-04-09 11:31:15 -04001748 private static int toggleEffects(int currentEffects, int[] effects, boolean suppress) {
1749 for (int i = 0; i < effects.length; i++) {
1750 final int effect = effects[i];
1751 if (suppress) {
1752 currentEffects |= effect;
1753 } else {
1754 currentEffects &= ~effect;
1755 }
1756 }
1757 return currentEffects;
1758 }
1759
Julia Reynoldsf612869ae2015-11-05 16:48:55 -05001760 public static String suppressedEffectsToString(int effects) {
1761 if (effects <= 0) return "";
1762 final StringBuilder sb = new StringBuilder();
1763 for (int i = 0; i < ALL_SUPPRESSED_EFFECTS.length; i++) {
1764 final int effect = ALL_SUPPRESSED_EFFECTS[i];
1765 if ((effects & effect) != 0) {
1766 if (sb.length() > 0) sb.append(',');
1767 sb.append(effectToString(effect));
1768 }
1769 effects &= ~effect;
1770 }
1771 if (effects != 0) {
1772 if (sb.length() > 0) sb.append(',');
1773 sb.append("UNKNOWN_").append(effects);
1774 }
1775 return sb.toString();
1776 }
1777
John Spurlock1fc476d2015-04-14 16:05:20 -04001778 public static String priorityCategoriesToString(int priorityCategories) {
1779 if (priorityCategories == 0) return "";
1780 final StringBuilder sb = new StringBuilder();
1781 for (int i = 0; i < ALL_PRIORITY_CATEGORIES.length; i++) {
1782 final int priorityCategory = ALL_PRIORITY_CATEGORIES[i];
1783 if ((priorityCategories & priorityCategory) != 0) {
1784 if (sb.length() > 0) sb.append(',');
1785 sb.append(priorityCategoryToString(priorityCategory));
1786 }
1787 priorityCategories &= ~priorityCategory;
1788 }
1789 if (priorityCategories != 0) {
1790 if (sb.length() > 0) sb.append(',');
1791 sb.append("PRIORITY_CATEGORY_UNKNOWN_").append(priorityCategories);
1792 }
1793 return sb.toString();
1794 }
1795
Julia Reynoldsf612869ae2015-11-05 16:48:55 -05001796 private static String effectToString(int effect) {
1797 switch (effect) {
Julia Reynoldsccc6ae62018-03-01 16:24:49 -05001798 case SUPPRESSED_EFFECT_FULL_SCREEN_INTENT:
1799 return "SUPPRESSED_EFFECT_FULL_SCREEN_INTENT";
1800 case SUPPRESSED_EFFECT_LIGHTS:
1801 return "SUPPRESSED_EFFECT_LIGHTS";
1802 case SUPPRESSED_EFFECT_PEEK:
1803 return "SUPPRESSED_EFFECT_PEEK";
1804 case SUPPRESSED_EFFECT_STATUS_BAR:
1805 return "SUPPRESSED_EFFECT_STATUS_BAR";
1806 case SUPPRESSED_EFFECT_BADGE:
1807 return "SUPPRESSED_EFFECT_BADGE";
1808 case SUPPRESSED_EFFECT_AMBIENT:
1809 return "SUPPRESSED_EFFECT_AMBIENT";
1810 case SUPPRESSED_EFFECT_NOTIFICATION_LIST:
1811 return "SUPPRESSED_EFFECT_NOTIFICATION_LIST";
1812 case SUPPRESSED_EFFECT_SCREEN_OFF:
1813 return "SUPPRESSED_EFFECT_SCREEN_OFF";
1814 case SUPPRESSED_EFFECT_SCREEN_ON:
1815 return "SUPPRESSED_EFFECT_SCREEN_ON";
1816 case SUPPRESSED_EFFECTS_UNSET:
1817 return "SUPPRESSED_EFFECTS_UNSET";
Julia Reynoldsf612869ae2015-11-05 16:48:55 -05001818 default: return "UNKNOWN_" + effect;
1819 }
1820 }
1821
John Spurlock1fc476d2015-04-14 16:05:20 -04001822 private static String priorityCategoryToString(int priorityCategory) {
1823 switch (priorityCategory) {
1824 case PRIORITY_CATEGORY_REMINDERS: return "PRIORITY_CATEGORY_REMINDERS";
1825 case PRIORITY_CATEGORY_EVENTS: return "PRIORITY_CATEGORY_EVENTS";
1826 case PRIORITY_CATEGORY_MESSAGES: return "PRIORITY_CATEGORY_MESSAGES";
1827 case PRIORITY_CATEGORY_CALLS: return "PRIORITY_CATEGORY_CALLS";
1828 case PRIORITY_CATEGORY_REPEAT_CALLERS: return "PRIORITY_CATEGORY_REPEAT_CALLERS";
Beverly04216872017-09-28 10:55:32 -04001829 case PRIORITY_CATEGORY_ALARMS: return "PRIORITY_CATEGORY_ALARMS";
Beverlyd6964762018-02-16 14:07:03 -05001830 case PRIORITY_CATEGORY_MEDIA: return "PRIORITY_CATEGORY_MEDIA";
1831 case PRIORITY_CATEGORY_SYSTEM: return "PRIORITY_CATEGORY_SYSTEM";
John Spurlock1fc476d2015-04-14 16:05:20 -04001832 default: return "PRIORITY_CATEGORY_UNKNOWN_" + priorityCategory;
1833 }
1834 }
1835
1836 public static String prioritySendersToString(int prioritySenders) {
1837 switch (prioritySenders) {
1838 case PRIORITY_SENDERS_ANY: return "PRIORITY_SENDERS_ANY";
1839 case PRIORITY_SENDERS_CONTACTS: return "PRIORITY_SENDERS_CONTACTS";
1840 case PRIORITY_SENDERS_STARRED: return "PRIORITY_SENDERS_STARRED";
1841 default: return "PRIORITY_SENDERS_UNKNOWN_" + prioritySenders;
1842 }
1843 }
1844
1845 public static final Parcelable.Creator<Policy> CREATOR = new Parcelable.Creator<Policy>() {
1846 @Override
1847 public Policy createFromParcel(Parcel in) {
1848 return new Policy(in);
1849 }
1850
1851 @Override
1852 public Policy[] newArray(int size) {
1853 return new Policy[size];
1854 }
1855 };
Beverlyff2df9b2018-10-10 16:54:10 -04001856
1857 /** @hide **/
1858 public boolean allowAlarms() {
1859 return (priorityCategories & PRIORITY_CATEGORY_ALARMS) != 0;
1860 }
1861
1862 /** @hide **/
1863 public boolean allowMedia() {
1864 return (priorityCategories & PRIORITY_CATEGORY_MEDIA) != 0;
1865 }
1866
1867 /** @hide **/
1868 public boolean allowSystem() {
1869 return (priorityCategories & PRIORITY_CATEGORY_SYSTEM) != 0;
1870 }
1871
1872 /** @hide **/
1873 public boolean allowRepeatCallers() {
1874 return (priorityCategories & PRIORITY_CATEGORY_REPEAT_CALLERS) != 0;
1875 }
1876
1877 /** @hide **/
1878 public boolean allowCalls() {
1879 return (priorityCategories & PRIORITY_CATEGORY_CALLS) != 0;
1880 }
1881
1882 /** @hide **/
1883 public boolean allowMessages() {
1884 return (priorityCategories & PRIORITY_CATEGORY_MESSAGES) != 0;
1885 }
1886
1887 /** @hide **/
1888 public boolean allowEvents() {
1889 return (priorityCategories & PRIORITY_CATEGORY_EVENTS) != 0;
1890 }
1891
1892 /** @hide **/
1893 public boolean allowReminders() {
1894 return (priorityCategories & PRIORITY_CATEGORY_REMINDERS) != 0;
1895 }
1896
1897 /** @hide **/
1898 public int allowCallsFrom() {
1899 return priorityCallSenders;
1900 }
1901
1902 /** @hide **/
1903 public int allowMessagesFrom() {
1904 return priorityMessageSenders;
1905 }
1906
Beverly12196702018-12-12 15:05:51 -05001907 /** @hide **/
1908 public boolean showFullScreenIntents() {
1909 return (suppressedVisualEffects & SUPPRESSED_EFFECT_FULL_SCREEN_INTENT) == 0;
1910 }
1911
1912 /** @hide **/
1913 public boolean showLights() {
1914 return (suppressedVisualEffects & SUPPRESSED_EFFECT_LIGHTS) == 0;
1915 }
1916
1917 /** @hide **/
1918 public boolean showPeeking() {
1919 return (suppressedVisualEffects & SUPPRESSED_EFFECT_PEEK) == 0;
1920 }
1921
1922 /** @hide **/
1923 public boolean showStatusBarIcons() {
1924 return (suppressedVisualEffects & SUPPRESSED_EFFECT_STATUS_BAR) == 0;
1925 }
1926
1927 /** @hide **/
1928 public boolean showAmbient() {
1929 return (suppressedVisualEffects & SUPPRESSED_EFFECT_AMBIENT) == 0;
1930 }
1931
1932 /** @hide **/
1933 public boolean showBadges() {
1934 return (suppressedVisualEffects & SUPPRESSED_EFFECT_BADGE) == 0;
1935 }
1936
1937 /** @hide **/
1938 public boolean showInNotificationList() {
1939 return (suppressedVisualEffects & SUPPRESSED_EFFECT_NOTIFICATION_LIST) == 0;
1940 }
1941
Beverlyff2df9b2018-10-10 16:54:10 -04001942 /**
1943 * returns a deep copy of this policy
1944 * @hide
1945 */
1946 public Policy copy() {
1947 final Parcel parcel = Parcel.obtain();
1948 try {
1949 writeToParcel(parcel, 0);
1950 parcel.setDataPosition(0);
1951 return new Policy(parcel);
1952 } finally {
1953 parcel.recycle();
1954 }
1955 }
John Spurlock1fc476d2015-04-14 16:05:20 -04001956 }
1957
Dan Sandler994349c2015-04-15 11:02:54 -04001958 /**
1959 * Recover a list of active notifications: ones that have been posted by the calling app that
1960 * have not yet been dismissed by the user or {@link #cancel(String, int)}ed by the app.
1961 *
Julia Reynoldsd12392c2018-12-17 14:06:04 -05001962 * <p><Each notification is embedded in a {@link StatusBarNotification} object, including the
Dan Sandler994349c2015-04-15 11:02:54 -04001963 * original <code>tag</code> and <code>id</code> supplied to
1964 * {@link #notify(String, int, Notification) notify()}
1965 * (via {@link StatusBarNotification#getTag() getTag()} and
1966 * {@link StatusBarNotification#getId() getId()}) as well as a copy of the original
1967 * {@link Notification} object (via {@link StatusBarNotification#getNotification()}).
Julia Reynoldsd12392c2018-12-17 14:06:04 -05001968 * </p>
1969 * <p>From {@link Build.VERSION_CODES#Q}, will also return notifications you've posted as an
1970 * app's notification delegate via
1971 * {@link NotificationManager#notifyAsPackage(String, String, int, Notification)}.
1972 * </p>
Dan Sandler994349c2015-04-15 11:02:54 -04001973 *
1974 * @return An array of {@link StatusBarNotification}.
1975 */
1976 public StatusBarNotification[] getActiveNotifications() {
1977 final INotificationManager service = getService();
1978 final String pkg = mContext.getPackageName();
1979 try {
1980 final ParceledListSlice<StatusBarNotification> parceledList
Jeff Sharkeyad357d12018-02-02 13:25:31 -07001981 = service.getAppActiveNotifications(pkg, mContext.getUserId());
Julia Reynolds34a80842018-09-21 13:01:00 -04001982 if (parceledList != null) {
1983 final List<StatusBarNotification> list = parceledList.getList();
1984 return list.toArray(new StatusBarNotification[list.size()]);
1985 }
Dan Sandler994349c2015-04-15 11:02:54 -04001986 } catch (RemoteException e) {
Jeff Sharkeyc53962d2016-03-01 19:27:23 -07001987 throw e.rethrowFromSystemServer();
Dan Sandler994349c2015-04-15 11:02:54 -04001988 }
Julia Reynolds34a80842018-09-21 13:01:00 -04001989 return new StatusBarNotification[0];
Dan Sandler994349c2015-04-15 11:02:54 -04001990 }
John Spurlock80774932015-05-07 17:38:50 -04001991
1992 /**
1993 * Gets the current notification interruption filter.
John Spurlock80774932015-05-07 17:38:50 -04001994 * <p>
Jeff Sharkey6503bd82017-04-19 23:24:18 -06001995 * The interruption filter defines which notifications are allowed to
1996 * interrupt the user (e.g. via sound &amp; vibration) and is applied
1997 * globally.
John Spurlock80774932015-05-07 17:38:50 -04001998 */
Julia Reynolds0edb50c2016-02-26 14:08:25 -05001999 public final @InterruptionFilter int getCurrentInterruptionFilter() {
John Spurlock80774932015-05-07 17:38:50 -04002000 final INotificationManager service = getService();
2001 try {
2002 return zenModeToInterruptionFilter(service.getZenMode());
2003 } catch (RemoteException e) {
Jeff Sharkeyc53962d2016-03-01 19:27:23 -07002004 throw e.rethrowFromSystemServer();
John Spurlock80774932015-05-07 17:38:50 -04002005 }
John Spurlock80774932015-05-07 17:38:50 -04002006 }
2007
2008 /**
2009 * Sets the current notification interruption filter.
John Spurlock80774932015-05-07 17:38:50 -04002010 * <p>
Jeff Sharkey6503bd82017-04-19 23:24:18 -06002011 * The interruption filter defines which notifications are allowed to
2012 * interrupt the user (e.g. via sound &amp; vibration) and is applied
2013 * globally.
John Spurlock80774932015-05-07 17:38:50 -04002014 * <p>
Jeff Sharkey6503bd82017-04-19 23:24:18 -06002015 * Only available if policy access is granted to this package. See
2016 * {@link #isNotificationPolicyAccessGranted}.
John Spurlock80774932015-05-07 17:38:50 -04002017 */
Jeff Sharkey6503bd82017-04-19 23:24:18 -06002018 public final void setInterruptionFilter(@InterruptionFilter int interruptionFilter) {
John Spurlock80774932015-05-07 17:38:50 -04002019 final INotificationManager service = getService();
2020 try {
2021 service.setInterruptionFilter(mContext.getOpPackageName(), interruptionFilter);
2022 } catch (RemoteException e) {
Jeff Sharkeyc53962d2016-03-01 19:27:23 -07002023 throw e.rethrowFromSystemServer();
John Spurlock80774932015-05-07 17:38:50 -04002024 }
2025 }
2026
2027 /** @hide */
2028 public static int zenModeToInterruptionFilter(int zen) {
2029 switch (zen) {
2030 case Global.ZEN_MODE_OFF: return INTERRUPTION_FILTER_ALL;
2031 case Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS: return INTERRUPTION_FILTER_PRIORITY;
2032 case Global.ZEN_MODE_ALARMS: return INTERRUPTION_FILTER_ALARMS;
2033 case Global.ZEN_MODE_NO_INTERRUPTIONS: return INTERRUPTION_FILTER_NONE;
2034 default: return INTERRUPTION_FILTER_UNKNOWN;
2035 }
2036 }
2037
2038 /** @hide */
2039 public static int zenModeFromInterruptionFilter(int interruptionFilter, int defValue) {
2040 switch (interruptionFilter) {
2041 case INTERRUPTION_FILTER_ALL: return Global.ZEN_MODE_OFF;
2042 case INTERRUPTION_FILTER_PRIORITY: return Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS;
2043 case INTERRUPTION_FILTER_ALARMS: return Global.ZEN_MODE_ALARMS;
2044 case INTERRUPTION_FILTER_NONE: return Global.ZEN_MODE_NO_INTERRUPTIONS;
2045 default: return defValue;
2046 }
2047 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002048}