blob: 872f33a537a2556b490c49b60f0f7de46a702f9f [file] [log] [blame]
Joe Onorato503007d2010-04-16 09:20:55 -07001/*
2 * Copyright (C) 2008 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
Joe Onorato79de0c52010-05-26 17:03:26 -040017package com.android.systemui.statusbar;
Joe Onorato503007d2010-04-16 09:20:55 -070018
Julia Reynolds25926af2018-05-01 17:05:33 -040019import static android.app.Notification.CATEGORY_ALARM;
20import static android.app.Notification.CATEGORY_CALL;
21import static android.app.Notification.CATEGORY_EVENT;
22import static android.app.Notification.CATEGORY_MESSAGE;
23import static android.app.Notification.CATEGORY_REMINDER;
Julia Reynolds24653c32018-03-02 13:16:37 -050024import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_AMBIENT;
25import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_FULL_SCREEN_INTENT;
Julia Reynolds24653c32018-03-02 13:16:37 -050026import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_NOTIFICATION_LIST;
27import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_PEEK;
28import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_STATUS_BAR;
29
Julia Reynolds5bbb6da2018-03-28 10:48:37 -040030import android.Manifest;
Maurice Lam132710e2017-03-03 19:13:42 -080031import android.app.AppGlobals;
Christoph Studer37fe6932014-05-26 13:10:30 +020032import android.app.Notification;
Julia Reynolds924eed12017-01-19 09:52:07 -050033import android.app.NotificationChannel;
Julia Reynolds85769912016-10-25 09:08:57 -040034import android.app.NotificationManager;
Selim Cinekb0dc61b2018-05-22 18:49:36 -070035import android.app.Person;
Julia Reynolds5bbb6da2018-03-28 10:48:37 -040036import android.content.Context;
Maurice Lam132710e2017-03-03 19:13:42 -080037import android.content.pm.IPackageManager;
38import android.content.pm.PackageManager;
Selim Cinek281c2022016-10-13 19:14:43 -070039import android.graphics.drawable.Icon;
Selim Cinekb0dc61b2018-05-22 18:49:36 -070040import android.os.Bundle;
41import android.os.Parcelable;
Maurice Lam132710e2017-03-03 19:13:42 -080042import android.os.RemoteException;
Selim Cinekb18a20f2015-06-04 17:08:35 +020043import android.os.SystemClock;
Christoph Studer37fe6932014-05-26 13:10:30 +020044import android.service.notification.NotificationListenerService.Ranking;
Christoph Studerd0694b62014-06-04 16:36:01 +020045import android.service.notification.NotificationListenerService.RankingMap;
Mady Mellor754d8222017-01-25 15:29:39 -080046import android.service.notification.SnoozeCriterion;
John Spurlockde84f0e2013-06-12 12:41:00 -040047import android.service.notification.StatusBarNotification;
Christoph Studerc8db24b2014-07-25 17:50:30 +020048import android.util.ArrayMap;
Julia Reynoldsfc640012018-02-21 12:25:27 -050049import android.util.ArraySet;
Joe Onoratoe345fff2010-05-23 15:18:27 -040050import android.view.View;
Selim Cinek281c2022016-10-13 19:14:43 -070051import android.widget.ImageView;
Julia Reynoldsd9228f12015-10-20 10:37:27 -040052import android.widget.RemoteViews;
Joe Onorato503007d2010-04-16 09:20:55 -070053
Maurice Lam132710e2017-03-03 19:13:42 -080054import com.android.internal.annotations.VisibleForTesting;
Selim Cinek281c2022016-10-13 19:14:43 -070055import com.android.internal.statusbar.StatusBarIcon;
Selim Cinekb0dc61b2018-05-22 18:49:36 -070056import com.android.internal.util.ArrayUtils;
Selim Cinek281c2022016-10-13 19:14:43 -070057import com.android.internal.util.NotificationColorUtil;
Dan Sandler008cea72017-05-28 12:18:53 -040058import com.android.systemui.Dependency;
59import com.android.systemui.ForegroundServiceController;
Selim Cinek1a48bab2017-02-17 19:38:40 -080060import com.android.systemui.statusbar.notification.InflationException;
Selim Cinek25fd4e2b2015-02-20 17:46:07 +010061import com.android.systemui.statusbar.phone.NotificationGroupManager;
Jason Monk2a6ea9c2017-01-26 11:14:51 -050062import com.android.systemui.statusbar.phone.StatusBar;
Selim Cinekfbe9a442015-04-13 16:09:49 -070063import com.android.systemui.statusbar.policy.HeadsUpManager;
Julia Reynolds25926af2018-05-01 17:05:33 -040064import com.android.systemui.statusbar.policy.ZenModeController;
Selim Cinek25fd4e2b2015-02-20 17:46:07 +010065
Christoph Studerc8db24b2014-07-25 17:50:30 +020066import java.io.PrintWriter;
Joe Onoratoe345fff2010-05-23 15:18:27 -040067import java.util.ArrayList;
Christoph Studer37fe6932014-05-26 13:10:30 +020068import java.util.Collections;
John Spurlockde84f0e2013-06-12 12:41:00 -040069import java.util.Comparator;
Mady Mellor754d8222017-01-25 15:29:39 -080070import java.util.List;
Selim Cinek247fa012016-02-18 09:50:48 -080071import java.util.Objects;
Joe Onoratoe345fff2010-05-23 15:18:27 -040072
73/**
74 * The list of currently displaying notifications.
75 */
Joe Onorato503007d2010-04-16 09:20:55 -070076public class NotificationData {
Christoph Studerc8db24b2014-07-25 17:50:30 +020077
78 private final Environment mEnvironment;
Selim Cinekfbe9a442015-04-13 16:09:49 -070079 private HeadsUpManager mHeadsUpManager;
Christoph Studerc8db24b2014-07-25 17:50:30 +020080
Julia Reynolds25926af2018-05-01 17:05:33 -040081 final ZenModeController mZen = Dependency.get(ZenModeController.class);
Julia Reynoldsfc640012018-02-21 12:25:27 -050082 final ForegroundServiceController mFsc = Dependency.get(ForegroundServiceController.class);
83
Joe Onoratoe345fff2010-05-23 15:18:27 -040084 public static final class Entry {
Selim Cinekb18a20f2015-06-04 17:08:35 +020085 private static final long LAUNCH_COOLDOWN = 2000;
Selim Cinek1397ea32018-01-16 17:34:52 -080086 private static final long REMOTE_INPUT_COOLDOWN = 500;
Selim Cinekb18a20f2015-06-04 17:08:35 +020087 private static final long NOT_LAUNCHED_YET = -LAUNCH_COOLDOWN;
Selim Cinek281c2022016-10-13 19:14:43 -070088 private static final int COLOR_INVALID = 1;
Christoph Studer71f18fd2014-05-20 17:02:04 +020089 public String key;
Joe Onoratoe345fff2010-05-23 15:18:27 -040090 public StatusBarNotification notification;
Julia Reynolds924eed12017-01-19 09:52:07 -050091 public NotificationChannel channel;
Joe Onorato66b4c5b2010-05-23 15:39:40 -040092 public StatusBarIconView icon;
Selim Cinek281c2022016-10-13 19:14:43 -070093 public StatusBarIconView expandedIcon;
Chris Wren51c75102013-07-16 20:49:17 -040094 public ExpandableNotificationRow row; // the outer expanded view
Chris Wrenf0048ce2013-08-07 16:43:43 -040095 private boolean interruption;
Jorim Jaggi36b15232014-06-10 17:24:20 +020096 public boolean autoRedacted; // whether the redacted notification was generated by us
Jorim Jaggia1eeade2014-09-08 22:34:39 +020097 public int targetSdk;
Selim Cinekb18a20f2015-06-04 17:08:35 +020098 private long lastFullScreenIntentLaunchTime = NOT_LAUNCHED_YET;
Julia Reynoldsd9228f12015-10-20 10:37:27 -040099 public RemoteViews cachedContentView;
100 public RemoteViews cachedBigContentView;
101 public RemoteViews cachedHeadsUpContentView;
102 public RemoteViews cachedPublicContentView;
Adrian Roos0aac04f2016-12-08 15:59:29 -0800103 public RemoteViews cachedAmbientContentView;
Adrian Roos777ef562015-12-01 17:37:14 -0800104 public CharSequence remoteInputText;
Mady Mellor754d8222017-01-25 15:29:39 -0800105 public List<SnoozeCriterion> snoozeCriteria;
Dan Sandler1d958f82018-01-09 21:10:26 -0500106 public int userSentiment = Ranking.USER_SENTIMENT_NEUTRAL;
107
Selim Cinek281c2022016-10-13 19:14:43 -0700108 private int mCachedContrastColor = COLOR_INVALID;
109 private int mCachedContrastColorIsFor = COLOR_INVALID;
Selim Cinek67ff2482017-05-25 10:27:28 -0700110 private InflationTask mRunningTask = null;
Selim Cinek04be3892017-08-08 10:58:32 -0700111 private Throwable mDebugThrowable;
Selim Cinek1397ea32018-01-16 17:34:52 -0800112 public CharSequence remoteInputTextWhenReset;
113 public long lastRemoteInputSent = NOT_LAUNCHED_YET;
Julia Reynoldsfc640012018-02-21 12:25:27 -0500114 public ArraySet<Integer> mActiveAppOps = new ArraySet<>(3);
Selim Cinekaa9db1f2018-02-27 17:35:47 -0800115 public CharSequence headsUpStatusBarText;
116 public CharSequence headsUpStatusBarTextPublic;
Julia Reynoldsaa96cf32018-04-17 09:09:04 -0400117 /**
118 * Whether or not this row represents a system notification. Note that if this is
119 * {@code null}, that means we were either unable to retrieve the info or have yet to
120 * retrieve the info.
121 */
122 public Boolean mIsSystemNotification;
Jorim Jaggi36b15232014-06-10 17:24:20 +0200123
Selim Cinekb0dc61b2018-05-22 18:49:36 -0700124 /**
125 * Has the user sent a reply through this Notification.
126 */
127 private boolean hasSentReply;
128
Selim Cinek281c2022016-10-13 19:14:43 -0700129 public Entry(StatusBarNotification n) {
Christoph Studer71f18fd2014-05-20 17:02:04 +0200130 this.key = n.getKey();
Daniel Sandler3eebd1f2010-07-27 08:39:33 -0400131 this.notification = n;
Daniel Sandler3eebd1f2010-07-27 08:39:33 -0400132 }
Chris Wrenf0048ce2013-08-07 16:43:43 -0400133
134 public void setInterruption() {
135 interruption = true;
136 }
Chris Wrend04f6ce2014-06-11 17:37:28 -0400137
138 public boolean hasInterrupted() {
139 return interruption;
140 }
Christoph Studer22f2ee52014-07-29 22:57:21 +0200141
142 /**
143 * Resets the notification entry to be re-used.
144 */
145 public void reset() {
Christoph Studer22f2ee52014-07-29 22:57:21 +0200146 if (row != null) {
147 row.reset();
148 }
149 }
Selim Cinek684a4422015-04-15 16:18:39 -0700150
Selim Cinek684a4422015-04-15 16:18:39 -0700151 public View getExpandedContentView() {
152 return row.getPrivateLayout().getExpandedChild();
153 }
154
Selim Cinek684a4422015-04-15 16:18:39 -0700155 public View getPublicContentView() {
156 return row.getPublicLayout().getContractedChild();
157 }
Selim Cinekb18a20f2015-06-04 17:08:35 +0200158
159 public void notifyFullScreenIntentLaunched() {
Selim Cinekda371df2017-07-21 16:18:21 -0700160 setInterruption();
Selim Cinekb18a20f2015-06-04 17:08:35 +0200161 lastFullScreenIntentLaunchTime = SystemClock.elapsedRealtime();
162 }
163
164 public boolean hasJustLaunchedFullScreenIntent() {
165 return SystemClock.elapsedRealtime() < lastFullScreenIntentLaunchTime + LAUNCH_COOLDOWN;
166 }
Selim Cinek281c2022016-10-13 19:14:43 -0700167
Selim Cinek1397ea32018-01-16 17:34:52 -0800168 public boolean hasJustSentRemoteInput() {
169 return SystemClock.elapsedRealtime() < lastRemoteInputSent + REMOTE_INPUT_COOLDOWN;
170 }
171
Selim Cinek281c2022016-10-13 19:14:43 -0700172 /**
173 * Create the icons for a notification
174 * @param context the context to create the icons with
175 * @param sbn the notification
Selim Cinek1a48bab2017-02-17 19:38:40 -0800176 * @throws InflationException
Selim Cinek281c2022016-10-13 19:14:43 -0700177 */
Selim Cinek1a48bab2017-02-17 19:38:40 -0800178 public void createIcons(Context context, StatusBarNotification sbn)
179 throws InflationException {
Selim Cinek281c2022016-10-13 19:14:43 -0700180 Notification n = sbn.getNotification();
181 final Icon smallIcon = n.getSmallIcon();
182 if (smallIcon == null) {
Selim Cinek1a48bab2017-02-17 19:38:40 -0800183 throw new InflationException("No small icon in notification from "
Selim Cinek281c2022016-10-13 19:14:43 -0700184 + sbn.getPackageName());
185 }
186
187 // Construct the icon.
188 icon = new StatusBarIconView(context,
Selim Cinek72fc8db2017-06-06 18:07:47 -0700189 sbn.getPackageName() + "/0x" + Integer.toHexString(sbn.getId()), sbn);
Selim Cinek281c2022016-10-13 19:14:43 -0700190 icon.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
191
192 // Construct the expanded icon.
193 expandedIcon = new StatusBarIconView(context,
Selim Cinek72fc8db2017-06-06 18:07:47 -0700194 sbn.getPackageName() + "/0x" + Integer.toHexString(sbn.getId()), sbn);
Selim Cinek281c2022016-10-13 19:14:43 -0700195 expandedIcon.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
196 final StatusBarIcon ic = new StatusBarIcon(
197 sbn.getUser(),
198 sbn.getPackageName(),
199 smallIcon,
200 n.iconLevel,
201 n.number,
202 StatusBarIconView.contentDescForNotification(context, n));
203 if (!icon.set(ic) || !expandedIcon.set(ic)) {
204 icon = null;
205 expandedIcon = null;
Selim Cinek1a48bab2017-02-17 19:38:40 -0800206 throw new InflationException("Couldn't create icon: " + ic);
Selim Cinek281c2022016-10-13 19:14:43 -0700207 }
Selim Cinek65989742016-12-09 16:05:38 -0800208 expandedIcon.setVisibility(View.INVISIBLE);
Selim Cinek2b549f42016-11-22 16:38:51 -0800209 expandedIcon.setOnVisibilityChangedListener(
210 newVisibility -> {
211 if (row != null) {
212 row.setIconsVisible(newVisibility != View.VISIBLE);
213 }
214 });
Selim Cinek281c2022016-10-13 19:14:43 -0700215 }
216
217 public void setIconTag(int key, Object tag) {
218 if (icon != null) {
219 icon.setTag(key, tag);
220 expandedIcon.setTag(key, tag);
221 }
222 }
223
224 /**
225 * Update the notification icons.
226 * @param context the context to create the icons with.
Julia Reynoldsfc640012018-02-21 12:25:27 -0500227 * @param sbn the notification to read the icon from.
Selim Cinek1a48bab2017-02-17 19:38:40 -0800228 * @throws InflationException
Selim Cinek281c2022016-10-13 19:14:43 -0700229 */
Selim Cinek72fc8db2017-06-06 18:07:47 -0700230 public void updateIcons(Context context, StatusBarNotification sbn)
231 throws InflationException {
Selim Cinek281c2022016-10-13 19:14:43 -0700232 if (icon != null) {
233 // Update the icon
Selim Cinek72fc8db2017-06-06 18:07:47 -0700234 Notification n = sbn.getNotification();
Selim Cinek281c2022016-10-13 19:14:43 -0700235 final StatusBarIcon ic = new StatusBarIcon(
236 notification.getUser(),
237 notification.getPackageName(),
238 n.getSmallIcon(),
239 n.iconLevel,
240 n.number,
241 StatusBarIconView.contentDescForNotification(context, n));
Selim Cinek72fc8db2017-06-06 18:07:47 -0700242 icon.setNotification(sbn);
243 expandedIcon.setNotification(sbn);
Selim Cinek281c2022016-10-13 19:14:43 -0700244 if (!icon.set(ic) || !expandedIcon.set(ic)) {
Selim Cinek1a48bab2017-02-17 19:38:40 -0800245 throw new InflationException("Couldn't update icon: " + ic);
Selim Cinek281c2022016-10-13 19:14:43 -0700246 }
247 }
248 }
249
Selim Cinekac5f0272017-05-02 16:05:41 -0700250 public int getContrastedColor(Context context, boolean isLowPriority,
251 int backgroundColor) {
252 int rawColor = isLowPriority ? Notification.COLOR_DEFAULT :
Selim Cinek6743c0b2017-01-18 18:24:01 -0800253 notification.getNotification().color;
Selim Cinek281c2022016-10-13 19:14:43 -0700254 if (mCachedContrastColorIsFor == rawColor && mCachedContrastColor != COLOR_INVALID) {
255 return mCachedContrastColor;
256 }
Selim Cinekac5f0272017-05-02 16:05:41 -0700257 final int contrasted = NotificationColorUtil.resolveContrastColor(context, rawColor,
258 backgroundColor);
Selim Cinek281c2022016-10-13 19:14:43 -0700259 mCachedContrastColorIsFor = rawColor;
260 mCachedContrastColor = contrasted;
261 return mCachedContrastColor;
262 }
Selim Cinek2630dc72017-04-20 15:16:10 -0700263
264 /**
265 * Abort all existing inflation tasks
266 */
Selim Cinek0f66a4c2017-04-28 19:26:28 -0700267 public void abortTask() {
Selim Cinek01d3da62017-04-28 15:03:48 -0700268 if (mRunningTask != null) {
269 mRunningTask.abort();
270 mRunningTask = null;
Selim Cinek2630dc72017-04-20 15:16:10 -0700271 }
272 }
273
Selim Cinek67ff2482017-05-25 10:27:28 -0700274 public void setInflationTask(InflationTask abortableTask) {
Selim Cinek01d3da62017-04-28 15:03:48 -0700275 // abort any existing inflation
Selim Cinek67ff2482017-05-25 10:27:28 -0700276 InflationTask existing = mRunningTask;
Selim Cinek0f66a4c2017-04-28 19:26:28 -0700277 abortTask();
278 mRunningTask = abortableTask;
Selim Cinek67ff2482017-05-25 10:27:28 -0700279 if (existing != null && mRunningTask != null) {
280 mRunningTask.supersedeTask(existing);
281 }
Selim Cinek2630dc72017-04-20 15:16:10 -0700282 }
Selim Cinekdc1231c2017-04-27 17:30:50 -0700283
Selim Cinek01d3da62017-04-28 15:03:48 -0700284 public void onInflationTaskFinished() {
285 mRunningTask = null;
Selim Cinekdc1231c2017-04-27 17:30:50 -0700286 }
287
288 @VisibleForTesting
Selim Cinek67ff2482017-05-25 10:27:28 -0700289 public InflationTask getRunningTask() {
Selim Cinek01d3da62017-04-28 15:03:48 -0700290 return mRunningTask;
Selim Cinekdc1231c2017-04-27 17:30:50 -0700291 }
Selim Cinek04be3892017-08-08 10:58:32 -0700292
293 /**
294 * Set a throwable that is used for debugging
295 *
296 * @param debugThrowable the throwable to save
297 */
298 public void setDebugThrowable(Throwable debugThrowable) {
299 mDebugThrowable = debugThrowable;
300 }
301
302 public Throwable getDebugThrowable() {
303 return mDebugThrowable;
304 }
Selim Cinek90d11a12018-01-17 16:24:36 -0800305
306 public void onRemoteInputInserted() {
307 lastRemoteInputSent = NOT_LAUNCHED_YET;
308 remoteInputTextWhenReset = null;
309 }
Selim Cinekb0dc61b2018-05-22 18:49:36 -0700310
311 public void setHasSentReply() {
312 hasSentReply = true;
313 }
314
315 public boolean isLastMessageFromReply() {
316 if (!hasSentReply) {
317 return false;
318 }
319 Bundle extras = notification.getNotification().extras;
320 CharSequence[] replyTexts = extras.getCharSequenceArray(
321 Notification.EXTRA_REMOTE_INPUT_HISTORY);
322 if (!ArrayUtils.isEmpty(replyTexts)) {
323 return true;
324 }
325 Parcelable[] messages = extras.getParcelableArray(Notification.EXTRA_MESSAGES);
326 if (messages != null && messages.length > 0) {
327 Parcelable message = messages[messages.length - 1];
328 if (message instanceof Bundle) {
329 Notification.MessagingStyle.Message lastMessage =
330 Notification.MessagingStyle.Message.getMessageFromBundle(
331 (Bundle) message);
332 if (lastMessage != null) {
333 Person senderPerson = lastMessage.getSenderPerson();
334 if (senderPerson == null) {
335 return true;
336 }
337 Person user = extras.getParcelable(Notification.EXTRA_MESSAGING_PERSON);
338 return Objects.equals(user, senderPerson);
339 }
340 }
341 }
342 return false;
343 }
Joe Onoratoe345fff2010-05-23 15:18:27 -0400344 }
Christoph Studer71f18fd2014-05-20 17:02:04 +0200345
Christoph Studerc8db24b2014-07-25 17:50:30 +0200346 private final ArrayMap<String, Entry> mEntries = new ArrayMap<>();
347 private final ArrayList<Entry> mSortedAndFiltered = new ArrayList<>();
Dieter Hsu36e1ebc2018-06-06 15:41:46 +0800348 private final ArrayList<Entry> mFilteredForUser = new ArrayList<>();
Selim Cinek25fd4e2b2015-02-20 17:46:07 +0100349
350 private NotificationGroupManager mGroupManager;
Christoph Studerc8db24b2014-07-25 17:50:30 +0200351
Christoph Studer1d599da2014-06-12 15:25:59 +0200352 private RankingMap mRankingMap;
353 private final Ranking mTmpRanking = new Ranking();
Selim Cinek25fd4e2b2015-02-20 17:46:07 +0100354
Selim Cinekfbe9a442015-04-13 16:09:49 -0700355 public void setHeadsUpManager(HeadsUpManager headsUpManager) {
356 mHeadsUpManager = headsUpManager;
357 }
358
Christoph Studer37fe6932014-05-26 13:10:30 +0200359 private final Comparator<Entry> mRankingComparator = new Comparator<Entry>() {
Christoph Studer1d599da2014-06-12 15:25:59 +0200360 private final Ranking mRankingA = new Ranking();
361 private final Ranking mRankingB = new Ranking();
362
Christoph Studer37fe6932014-05-26 13:10:30 +0200363 @Override
Daniel Sandler379020a2010-07-29 16:20:06 -0400364 public int compare(Entry a, Entry b) {
Christoph Studer14921162014-09-03 12:51:26 +0200365 final StatusBarNotification na = a.notification;
366 final StatusBarNotification nb = b.notification;
Julia Reynolds85769912016-10-25 09:08:57 -0400367 int aImportance = NotificationManager.IMPORTANCE_DEFAULT;
368 int bImportance = NotificationManager.IMPORTANCE_DEFAULT;
Chris Wrenbdf33762015-12-04 15:50:51 -0500369 int aRank = 0;
370 int bRank = 0;
371
372 if (mRankingMap != null) {
373 // RankingMap as received from NoMan
Kensuke Matsuiefa1a742017-08-03 12:12:36 +0900374 getRanking(a.key, mRankingA);
375 getRanking(b.key, mRankingB);
Chris Wrenbdf33762015-12-04 15:50:51 -0500376 aImportance = mRankingA.getImportance();
377 bImportance = mRankingB.getImportance();
378 aRank = mRankingA.getRank();
379 bRank = mRankingB.getRank();
380 }
Christoph Studer14921162014-09-03 12:51:26 +0200381
Dan Sandler4e787062015-06-17 15:09:48 -0400382 String mediaNotification = mEnvironment.getCurrentMediaNotificationKey();
383
Julia Reynoldsf0f629f2016-02-25 09:34:04 -0500384 // IMPORTANCE_MIN media streams are allowed to drift to the bottom
Dan Sandler4e787062015-06-17 15:09:48 -0400385 final boolean aMedia = a.key.equals(mediaNotification)
Julia Reynolds85769912016-10-25 09:08:57 -0400386 && aImportance > NotificationManager.IMPORTANCE_MIN;
Dan Sandler4e787062015-06-17 15:09:48 -0400387 final boolean bMedia = b.key.equals(mediaNotification)
Julia Reynolds85769912016-10-25 09:08:57 -0400388 && bImportance > NotificationManager.IMPORTANCE_MIN;
Dan Sandler4e787062015-06-17 15:09:48 -0400389
Julia Reynolds85769912016-10-25 09:08:57 -0400390 boolean aSystemMax = aImportance >= NotificationManager.IMPORTANCE_HIGH &&
Christoph Studer14921162014-09-03 12:51:26 +0200391 isSystemNotification(na);
Julia Reynolds85769912016-10-25 09:08:57 -0400392 boolean bSystemMax = bImportance >= NotificationManager.IMPORTANCE_HIGH &&
Christoph Studer14921162014-09-03 12:51:26 +0200393 isSystemNotification(nb);
Christoph Studer14921162014-09-03 12:51:26 +0200394
Selim Cinekfbe9a442015-04-13 16:09:49 -0700395 boolean isHeadsUp = a.row.isHeadsUp();
396 if (isHeadsUp != b.row.isHeadsUp()) {
397 return isHeadsUp ? -1 : 1;
398 } else if (isHeadsUp) {
399 // Provide consistent ranking with headsUpManager
400 return mHeadsUpManager.compare(a, b);
401 } else if (aMedia != bMedia) {
402 // Upsort current media notification.
403 return aMedia ? -1 : 1;
404 } else if (aSystemMax != bSystemMax) {
405 // Upsort PRIORITY_MAX system notifications
406 return aSystemMax ? -1 : 1;
Chris Wrenbdf33762015-12-04 15:50:51 -0500407 } else if (aRank != bRank) {
408 return aRank - bRank;
Chris Wrenf0048ce2013-08-07 16:43:43 -0400409 } else {
Ian Rogers31756df2016-06-06 14:49:30 -0700410 return Long.compare(nb.getNotification().when, na.getNotification().when);
Chris Wrenf0048ce2013-08-07 16:43:43 -0400411 }
Daniel Sandler379020a2010-07-29 16:20:06 -0400412 }
413 };
Joe Onorato503007d2010-04-16 09:20:55 -0700414
Christoph Studerc8db24b2014-07-25 17:50:30 +0200415 public NotificationData(Environment environment) {
416 mEnvironment = environment;
Selim Cinek25fd4e2b2015-02-20 17:46:07 +0100417 mGroupManager = environment.getGroupManager();
Joe Onoratoe345fff2010-05-23 15:18:27 -0400418 }
Joe Onorato503007d2010-04-16 09:20:55 -0700419
Christoph Studerc8db24b2014-07-25 17:50:30 +0200420 /**
421 * Returns the sorted list of active notifications (depending on {@link Environment}
422 *
423 * <p>
424 * This call doesn't update the list of active notifications. Call {@link #filterAndSort()}
425 * when the environment changes.
426 * <p>
427 * Don't hold on to or modify the returned list.
428 */
429 public ArrayList<Entry> getActiveNotifications() {
430 return mSortedAndFiltered;
Daniel Sandler0f0b11c2010-08-04 15:54:58 -0400431 }
432
Dieter Hsu36e1ebc2018-06-06 15:41:46 +0800433 public ArrayList<Entry> getNotificationsForCurrentUser() {
434 mFilteredForUser.clear();
435
436 synchronized (mEntries) {
437 final int N = mEntries.size();
438 for (int i = 0; i < N; i++) {
439 Entry entry = mEntries.valueAt(i);
440 final StatusBarNotification sbn = entry.notification;
441 if (!mEnvironment.isNotificationForCurrentProfiles(sbn)) {
442 continue;
443 }
444 mFilteredForUser.add(entry);
445 }
446 }
447 return mFilteredForUser;
448 }
449
Christoph Studerc8db24b2014-07-25 17:50:30 +0200450 public Entry get(String key) {
451 return mEntries.get(key);
Joe Onorato0e26dff2010-05-24 16:17:02 -0400452 }
453
Selim Cinek2630dc72017-04-20 15:16:10 -0700454 public void add(Entry entry) {
Julia Reynoldse46bb372016-03-17 11:05:58 -0400455 synchronized (mEntries) {
456 mEntries.put(entry.notification.getKey(), entry);
457 }
Selim Cinek25fd4e2b2015-02-20 17:46:07 +0100458 mGroupManager.onEntryAdded(entry);
Dan Sandler008cea72017-05-28 12:18:53 -0400459
Selim Cinek608a57a2017-04-28 16:50:41 -0700460 updateRankingAndSort(mRankingMap);
Daniel Sandler3eebd1f2010-07-27 08:39:33 -0400461 }
462
Christoph Studerd0694b62014-06-04 16:36:01 +0200463 public Entry remove(String key, RankingMap ranking) {
Julia Reynoldse46bb372016-03-17 11:05:58 -0400464 Entry removed = null;
465 synchronized (mEntries) {
466 removed = mEntries.remove(key);
467 }
Christoph Studerc8db24b2014-07-25 17:50:30 +0200468 if (removed == null) return null;
Selim Cinek25fd4e2b2015-02-20 17:46:07 +0100469 mGroupManager.onEntryRemoved(removed);
Julia Reynoldse46bb372016-03-17 11:05:58 -0400470 updateRankingAndSort(ranking);
Christoph Studerc8db24b2014-07-25 17:50:30 +0200471 return removed;
Joe Onorato503007d2010-04-16 09:20:55 -0700472 }
Joe Onorato20da8f82010-05-24 16:39:29 -0400473
Christoph Studerd0694b62014-06-04 16:36:01 +0200474 public void updateRanking(RankingMap ranking) {
Christoph Studer37fe6932014-05-26 13:10:30 +0200475 updateRankingAndSort(ranking);
476 }
477
Julia Reynolds91590062018-04-02 16:24:11 -0400478 public void updateAppOp(int appOp, int uid, String pkg, String key, boolean showIcon) {
Julia Reynoldsfc640012018-02-21 12:25:27 -0500479 synchronized (mEntries) {
480 final int N = mEntries.size();
481 for (int i = 0; i < N; i++) {
482 Entry entry = mEntries.valueAt(i);
483 if (uid == entry.notification.getUid()
Julia Reynolds91590062018-04-02 16:24:11 -0400484 && pkg.equals(entry.notification.getPackageName())
485 && key.equals(entry.key)) {
Julia Reynoldsfc640012018-02-21 12:25:27 -0500486 if (showIcon) {
487 entry.mActiveAppOps.add(appOp);
488 } else {
489 entry.mActiveAppOps.remove(appOp);
490 }
491 }
492 }
493 }
494 }
495
Christoph Studer37fe6932014-05-26 13:10:30 +0200496 public boolean isAmbient(String key) {
John Spurlockf079fc52014-08-09 11:10:03 -0400497 if (mRankingMap != null) {
Kensuke Matsuiefa1a742017-08-03 12:12:36 +0900498 getRanking(key, mTmpRanking);
John Spurlockf079fc52014-08-09 11:10:03 -0400499 return mTmpRanking.isAmbient();
500 }
501 return false;
Christoph Studer37fe6932014-05-26 13:10:30 +0200502 }
503
Chris Wren3ad4e3a2014-09-02 17:23:51 -0400504 public int getVisibilityOverride(String key) {
505 if (mRankingMap != null) {
Kensuke Matsuiefa1a742017-08-03 12:12:36 +0900506 getRanking(key, mTmpRanking);
Chris Wren3ad4e3a2014-09-02 17:23:51 -0400507 return mTmpRanking.getVisibilityOverride();
508 }
Julia Reynoldsead00aa2015-12-07 08:23:48 -0500509 return Ranking.VISIBILITY_NO_OVERRIDE;
Chris Wren3ad4e3a2014-09-02 17:23:51 -0400510 }
511
Julia Reynoldsaa96cf32018-04-17 09:09:04 -0400512 public boolean shouldSuppressFullScreenIntent(Entry entry) {
513 return shouldSuppressVisualEffect(entry, SUPPRESSED_EFFECT_FULL_SCREEN_INTENT);
Julia Reynolds5bbb6da2018-03-28 10:48:37 -0400514 }
515
Julia Reynoldsaa96cf32018-04-17 09:09:04 -0400516 public boolean shouldSuppressPeek(Entry entry) {
517 return shouldSuppressVisualEffect(entry, SUPPRESSED_EFFECT_PEEK);
Julia Reynolds5bbb6da2018-03-28 10:48:37 -0400518 }
519
Julia Reynoldsaa96cf32018-04-17 09:09:04 -0400520 public boolean shouldSuppressStatusBar(Entry entry) {
521 return shouldSuppressVisualEffect(entry, SUPPRESSED_EFFECT_STATUS_BAR);
Julia Reynolds5bbb6da2018-03-28 10:48:37 -0400522 }
523
Julia Reynoldsaa96cf32018-04-17 09:09:04 -0400524 public boolean shouldSuppressAmbient(Entry entry) {
525 return shouldSuppressVisualEffect(entry, SUPPRESSED_EFFECT_AMBIENT);
Julia Reynolds5bbb6da2018-03-28 10:48:37 -0400526 }
527
Julia Reynoldsaa96cf32018-04-17 09:09:04 -0400528 public boolean shouldSuppressNotificationList(Entry entry) {
529 return shouldSuppressVisualEffect(entry, SUPPRESSED_EFFECT_NOTIFICATION_LIST);
Julia Reynolds5bbb6da2018-03-28 10:48:37 -0400530 }
531
Julia Reynoldsaa96cf32018-04-17 09:09:04 -0400532 private boolean shouldSuppressVisualEffect(Entry entry, int effect) {
533 if (isExemptFromDndVisualSuppression(entry)) {
Julia Reynolds5bbb6da2018-03-28 10:48:37 -0400534 return false;
535 }
Julia Reynoldsaa96cf32018-04-17 09:09:04 -0400536 String key = entry.key;
Julia Reynoldsf612869ae2015-11-05 16:48:55 -0500537 if (mRankingMap != null) {
Kensuke Matsuiefa1a742017-08-03 12:12:36 +0900538 getRanking(key, mTmpRanking);
Julia Reynolds5bbb6da2018-03-28 10:48:37 -0400539 return (mTmpRanking.getSuppressedVisualEffects() & effect) != 0;
Julia Reynoldsf612869ae2015-11-05 16:48:55 -0500540 }
541 return false;
542 }
543
Julia Reynoldsaa96cf32018-04-17 09:09:04 -0400544 protected boolean isExemptFromDndVisualSuppression(Entry entry) {
Julia Reynolds25926af2018-05-01 17:05:33 -0400545 if (isNotificationBlockedByPolicy(entry.notification.getNotification())) {
546 return false;
547 }
548
Julia Reynoldsaa96cf32018-04-17 09:09:04 -0400549 if ((entry.notification.getNotification().flags
550 & Notification.FLAG_FOREGROUND_SERVICE) != 0) {
Julia Reynolds5bbb6da2018-03-28 10:48:37 -0400551 return true;
Julia Reynolds24653c32018-03-02 13:16:37 -0500552 }
Julia Reynoldsaa96cf32018-04-17 09:09:04 -0400553 if (entry.notification.getNotification().isMediaNotification()) {
554 return true;
555 }
556 if (entry.mIsSystemNotification != null && entry.mIsSystemNotification) {
Julia Reynolds5bbb6da2018-03-28 10:48:37 -0400557 return true;
Julia Reynolds61721582016-01-05 08:35:25 -0500558 }
559 return false;
560 }
561
Julia Reynolds25926af2018-05-01 17:05:33 -0400562 /**
563 * Categories that are explicitly called out on DND settings screens are always blocked, if
564 * DND has flagged them, even if they are foreground or system notifications that might
565 * otherwise visually bypass DND.
566 */
567 protected boolean isNotificationBlockedByPolicy(Notification n) {
568 if (isCategory(CATEGORY_CALL, n)
569 || isCategory(CATEGORY_MESSAGE, n)
570 || isCategory(CATEGORY_ALARM, n)
571 || isCategory(CATEGORY_EVENT, n)
572 || isCategory(CATEGORY_REMINDER, n)) {
573 return true;
574 }
575 return false;
576 }
577
578 private boolean isCategory(String category, Notification n) {
579 return Objects.equals(n.category, category);
580 }
581
Chris Wrenbdf33762015-12-04 15:50:51 -0500582 public int getImportance(String key) {
583 if (mRankingMap != null) {
Kensuke Matsuiefa1a742017-08-03 12:12:36 +0900584 getRanking(key, mTmpRanking);
Chris Wrenbdf33762015-12-04 15:50:51 -0500585 return mTmpRanking.getImportance();
586 }
Julia Reynolds85769912016-10-25 09:08:57 -0400587 return NotificationManager.IMPORTANCE_UNSPECIFIED;
Chris Wrenbdf33762015-12-04 15:50:51 -0500588 }
589
Julia Reynoldse46bb372016-03-17 11:05:58 -0400590 public String getOverrideGroupKey(String key) {
591 if (mRankingMap != null) {
Kensuke Matsuiefa1a742017-08-03 12:12:36 +0900592 getRanking(key, mTmpRanking);
Julia Reynoldse46bb372016-03-17 11:05:58 -0400593 return mTmpRanking.getOverrideGroupKey();
594 }
595 return null;
596 }
597
Mady Mellor754d8222017-01-25 15:29:39 -0800598 public List<SnoozeCriterion> getSnoozeCriteria(String key) {
599 if (mRankingMap != null) {
Kensuke Matsuiefa1a742017-08-03 12:12:36 +0900600 getRanking(key, mTmpRanking);
Mady Mellor754d8222017-01-25 15:29:39 -0800601 return mTmpRanking.getSnoozeCriteria();
602 }
603 return null;
604 }
605
Julia Reynolds924eed12017-01-19 09:52:07 -0500606 public NotificationChannel getChannel(String key) {
607 if (mRankingMap != null) {
Kensuke Matsuiefa1a742017-08-03 12:12:36 +0900608 getRanking(key, mTmpRanking);
Julia Reynolds924eed12017-01-19 09:52:07 -0500609 return mTmpRanking.getChannel();
610 }
611 return null;
612 }
613
Dieter Hsud39f0d52018-04-14 02:08:30 +0800614 public int getRank(String key) {
615 if (mRankingMap != null) {
616 getRanking(key, mTmpRanking);
617 return mTmpRanking.getRank();
618 }
619 return 0;
620 }
621
Beverly5a20a5e2018-03-06 15:02:44 -0500622 public boolean shouldHide(String key) {
623 if (mRankingMap != null) {
624 getRanking(key, mTmpRanking);
625 return mTmpRanking.isSuspended();
626 }
627 return false;
628 }
629
Christoph Studerd0694b62014-06-04 16:36:01 +0200630 private void updateRankingAndSort(RankingMap ranking) {
Christoph Studer37fe6932014-05-26 13:10:30 +0200631 if (ranking != null) {
Christoph Studer1d599da2014-06-12 15:25:59 +0200632 mRankingMap = ranking;
Julia Reynoldse46bb372016-03-17 11:05:58 -0400633 synchronized (mEntries) {
634 final int N = mEntries.size();
635 for (int i = 0; i < N; i++) {
636 Entry entry = mEntries.valueAt(i);
Kensuke Matsuiefa1a742017-08-03 12:12:36 +0900637 if (!getRanking(entry.key, mTmpRanking)) {
638 continue;
639 }
Selim Cinek7f09ce12017-06-08 13:20:08 -0700640 final StatusBarNotification oldSbn = entry.notification.cloneLight();
Julia Reynoldse46bb372016-03-17 11:05:58 -0400641 final String overrideGroupKey = getOverrideGroupKey(entry.key);
642 if (!Objects.equals(oldSbn.getOverrideGroupKey(), overrideGroupKey)) {
643 entry.notification.setOverrideGroupKey(overrideGroupKey);
644 mGroupManager.onEntryUpdated(entry, oldSbn);
645 }
Julia Reynolds924eed12017-01-19 09:52:07 -0500646 entry.channel = getChannel(entry.key);
Mady Mellor754d8222017-01-25 15:29:39 -0800647 entry.snoozeCriteria = getSnoozeCriteria(entry.key);
Dan Sandler1d958f82018-01-09 21:10:26 -0500648 entry.userSentiment = mTmpRanking.getUserSentiment();
Julia Reynoldse46bb372016-03-17 11:05:58 -0400649 }
650 }
Christoph Studer37fe6932014-05-26 13:10:30 +0200651 }
Christoph Studerc8db24b2014-07-25 17:50:30 +0200652 filterAndSort();
Christoph Studer37fe6932014-05-26 13:10:30 +0200653 }
654
Kensuke Matsuiefa1a742017-08-03 12:12:36 +0900655 /**
656 * Get the ranking from the current ranking map.
657 *
658 * @param key the key to look up
659 * @param outRanking the ranking to populate
660 *
661 * @return {@code true} if the ranking was properly obtained.
662 */
663 @VisibleForTesting
664 protected boolean getRanking(String key, Ranking outRanking) {
665 return mRankingMap.getRanking(key, outRanking);
666 }
667
Christoph Studerc8db24b2014-07-25 17:50:30 +0200668 // TODO: This should not be public. Instead the Environment should notify this class when
669 // anything changed, and this class should call back the UI so it updates itself.
670 public void filterAndSort() {
671 mSortedAndFiltered.clear();
672
Julia Reynoldse46bb372016-03-17 11:05:58 -0400673 synchronized (mEntries) {
674 final int N = mEntries.size();
675 for (int i = 0; i < N; i++) {
676 Entry entry = mEntries.valueAt(i);
Christoph Studerc8db24b2014-07-25 17:50:30 +0200677
Julia Reynoldsaa96cf32018-04-17 09:09:04 -0400678 if (shouldFilterOut(entry)) {
Julia Reynoldse46bb372016-03-17 11:05:58 -0400679 continue;
680 }
681
682 mSortedAndFiltered.add(entry);
Joe Onorato9c1d8232010-05-24 20:02:53 -0400683 }
Christoph Studerc8db24b2014-07-25 17:50:30 +0200684 }
685
Christoph Studerc8db24b2014-07-25 17:50:30 +0200686 Collections.sort(mSortedAndFiltered, mRankingComparator);
687 }
688
Dan Sandler008cea72017-05-28 12:18:53 -0400689 /**
Dan Sandler008cea72017-05-28 12:18:53 -0400690 * @return true if this notification should NOT be shown right now
691 */
Julia Reynoldsaa96cf32018-04-17 09:09:04 -0400692 public boolean shouldFilterOut(Entry entry) {
693 final StatusBarNotification sbn = entry.notification;
Christoph Studerc8db24b2014-07-25 17:50:30 +0200694 if (!(mEnvironment.isDeviceProvisioned() ||
695 showNotificationEvenIfUnprovisioned(sbn))) {
696 return true;
697 }
698
699 if (!mEnvironment.isNotificationForCurrentProfiles(sbn)) {
700 return true;
701 }
702
Robin Lee92b83c62016-08-31 13:27:51 +0100703 if (mEnvironment.isSecurelyLocked(sbn.getUserId()) &&
Julia Reynolds26fa8a52016-02-24 08:31:22 -0500704 (sbn.getNotification().visibility == Notification.VISIBILITY_SECRET
705 || mEnvironment.shouldHideNotifications(sbn.getUserId())
706 || mEnvironment.shouldHideNotifications(sbn.getKey()))) {
Christoph Studerc8db24b2014-07-25 17:50:30 +0200707 return true;
Joe Onorato9c1d8232010-05-24 20:02:53 -0400708 }
Selim Cinek25fd4e2b2015-02-20 17:46:07 +0100709
Julia Reynoldsaa96cf32018-04-17 09:09:04 -0400710 if (mEnvironment.isDozing() && shouldSuppressAmbient(entry)) {
Julia Reynolds24653c32018-03-02 13:16:37 -0500711 return true;
712 }
713
Julia Reynoldsaa96cf32018-04-17 09:09:04 -0400714 if (!mEnvironment.isDozing() && shouldSuppressNotificationList(entry)) {
Julia Reynolds24653c32018-03-02 13:16:37 -0500715 return true;
716 }
717
Beverly5a20a5e2018-03-06 15:02:44 -0500718 if (shouldHide(sbn.getKey())) {
719 return true;
720 }
721
Jason Monk2a6ea9c2017-01-26 11:14:51 -0500722 if (!StatusBar.ENABLE_CHILD_NOTIFICATIONS
Selim Cinekb5605e52015-02-20 18:21:41 +0100723 && mGroupManager.isChildInGroupWithSummary(sbn)) {
Selim Cinek25fd4e2b2015-02-20 17:46:07 +0100724 return true;
725 }
Dan Sandler008cea72017-05-28 12:18:53 -0400726
Julia Reynoldsfc640012018-02-21 12:25:27 -0500727 if (mFsc.isDungeonNotification(sbn) && !mFsc.isDungeonNeededForUser(sbn.getUserId())) {
Dan Sandler008cea72017-05-28 12:18:53 -0400728 // this is a foreground-service disclosure for a user that does not need to show one
729 return true;
730 }
Julia Reynolds3c7de112018-03-28 09:33:13 -0400731 if (mFsc.isSystemAlertNotification(sbn)) {
732 final String[] apps = sbn.getNotification().extras.getStringArray(
733 Notification.EXTRA_FOREGROUND_APPS);
734 if (apps != null && apps.length >= 1) {
735 if (!mFsc.isSystemAlertWarningNeeded(sbn.getUserId(), apps[0])) {
736 return true;
737 }
738 }
Julia Reynoldsfc640012018-02-21 12:25:27 -0500739 }
Dan Sandler008cea72017-05-28 12:18:53 -0400740
Joe Onorato9c1d8232010-05-24 20:02:53 -0400741 return false;
Joe Onorato20da8f82010-05-24 16:39:29 -0400742 }
743
Christoph Studerc8db24b2014-07-25 17:50:30 +0200744 // Q: What kinds of notifications should show during setup?
Maurice Lam132710e2017-03-03 19:13:42 -0800745 // A: Almost none! Only things coming from packages with permission
746 // android.permission.NOTIFICATION_DURING_SETUP that also have special "kind" tags marking them
747 // as relevant for setup (see below).
Christoph Studerc8db24b2014-07-25 17:50:30 +0200748 public static boolean showNotificationEvenIfUnprovisioned(StatusBarNotification sbn) {
Maurice Lam132710e2017-03-03 19:13:42 -0800749 return showNotificationEvenIfUnprovisioned(AppGlobals.getPackageManager(), sbn);
750 }
751
752 @VisibleForTesting
753 static boolean showNotificationEvenIfUnprovisioned(IPackageManager packageManager,
754 StatusBarNotification sbn) {
755 return checkUidPermission(packageManager, Manifest.permission.NOTIFICATION_DURING_SETUP,
756 sbn.getUid()) == PackageManager.PERMISSION_GRANTED
Christoph Studerc8db24b2014-07-25 17:50:30 +0200757 && sbn.getNotification().extras.getBoolean(Notification.EXTRA_ALLOW_DURING_SETUP);
758 }
759
Maurice Lam132710e2017-03-03 19:13:42 -0800760 private static int checkUidPermission(IPackageManager packageManager, String permission,
761 int uid) {
762 try {
763 return packageManager.checkUidPermission(permission, uid);
764 } catch (RemoteException e) {
765 throw e.rethrowFromSystemServer();
766 }
767 }
768
Christoph Studerc8db24b2014-07-25 17:50:30 +0200769 public void dump(PrintWriter pw, String indent) {
770 int N = mSortedAndFiltered.size();
771 pw.print(indent);
772 pw.println("active notifications: " + N);
Christoph Studer11840cd2014-08-21 16:41:45 +0200773 int active;
774 for (active = 0; active < N; active++) {
775 NotificationData.Entry e = mSortedAndFiltered.get(active);
776 dumpEntry(pw, indent, active, e);
Christoph Studerc8db24b2014-07-25 17:50:30 +0200777 }
Julia Reynoldse46bb372016-03-17 11:05:58 -0400778 synchronized (mEntries) {
779 int M = mEntries.size();
780 pw.print(indent);
781 pw.println("inactive notifications: " + (M - active));
782 int inactiveCount = 0;
783 for (int i = 0; i < M; i++) {
784 Entry entry = mEntries.valueAt(i);
785 if (!mSortedAndFiltered.contains(entry)) {
786 dumpEntry(pw, indent, inactiveCount, entry);
787 inactiveCount++;
788 }
Christoph Studerc8db24b2014-07-25 17:50:30 +0200789 }
790 }
791 }
792
793 private void dumpEntry(PrintWriter pw, String indent, int i, Entry e) {
Kensuke Matsuiefa1a742017-08-03 12:12:36 +0900794 getRanking(e.key, mTmpRanking);
Christoph Studerc8db24b2014-07-25 17:50:30 +0200795 pw.print(indent);
796 pw.println(" [" + i + "] key=" + e.key + " icon=" + e.icon);
797 StatusBarNotification n = e.notification;
798 pw.print(indent);
Chris Wrenbdf33762015-12-04 15:50:51 -0500799 pw.println(" pkg=" + n.getPackageName() + " id=" + n.getId() + " importance=" +
800 mTmpRanking.getImportance());
Christoph Studerc8db24b2014-07-25 17:50:30 +0200801 pw.print(indent);
802 pw.println(" notification=" + n.getNotification());
Christoph Studerc8db24b2014-07-25 17:50:30 +0200803 }
804
Christoph Studer14921162014-09-03 12:51:26 +0200805 private static boolean isSystemNotification(StatusBarNotification sbn) {
806 String sbnPackage = sbn.getPackageName();
807 return "android".equals(sbnPackage) || "com.android.systemui".equals(sbnPackage);
808 }
809
Christoph Studerc8db24b2014-07-25 17:50:30 +0200810 /**
811 * Provides access to keyguard state and user settings dependent data.
812 */
813 public interface Environment {
Robin Lee92b83c62016-08-31 13:27:51 +0100814 public boolean isSecurelyLocked(int userId);
Julia Reynolds26fa8a52016-02-24 08:31:22 -0500815 public boolean shouldHideNotifications(int userid);
816 public boolean shouldHideNotifications(String key);
Christoph Studerc8db24b2014-07-25 17:50:30 +0200817 public boolean isDeviceProvisioned();
818 public boolean isNotificationForCurrentProfiles(StatusBarNotification sbn);
Christoph Studer2e731b52014-08-22 16:01:51 +0200819 public String getCurrentMediaNotificationKey();
Selim Cinek25fd4e2b2015-02-20 17:46:07 +0100820 public NotificationGroupManager getGroupManager();
Julia Reynolds24653c32018-03-02 13:16:37 -0500821 /**
822 * @return true iff the device is dozing
823 */
824 boolean isDozing();
Christoph Studerc8db24b2014-07-25 17:50:30 +0200825 }
Joe Onorato503007d2010-04-16 09:20:55 -0700826}