blob: 5c43f8f829b0ec08bfedd75ac5a7414f3284f1f9 [file] [log] [blame]
Joe Onorato18e69df2010-05-17 22:26:12 -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
Daniel Sandler5feceeb2013-03-22 18:29:23 -070017package android.service.notification;
Joe Onorato18e69df2010-05-17 22:26:12 -070018
Julia Reynolds7c267522020-01-16 11:26:41 -050019import static android.app.NotificationChannel.PLACEHOLDER_CONVERSATION_ID;
Julia Reynolds7c267522020-01-16 11:26:41 -050020
Julia Reynoldscbc45e72019-03-07 12:31:52 -050021import android.annotation.NonNull;
Joe Onorato18e69df2010-05-17 22:26:12 -070022import android.app.Notification;
Julia Reynoldsa7ba45a2018-08-29 09:07:52 -040023import android.app.NotificationManager;
Will Brockmanc22772c2019-06-14 14:55:31 -040024import android.app.Person;
Artur Satayevdf439592019-12-10 17:47:53 +000025import android.compat.annotation.UnsupportedAppUsage;
Dan Sandler68079d52015-07-22 10:45:30 -040026import android.content.Context;
27import android.content.pm.ApplicationInfo;
28import android.content.pm.PackageManager;
Eyal Posenera9cf9c72018-12-18 16:23:54 +020029import android.metrics.LogMaker;
Mathew Inwood31755f92018-12-20 13:53:36 +000030import android.os.Build;
Joe Onorato18e69df2010-05-17 22:26:12 -070031import android.os.Parcel;
32import android.os.Parcelable;
Dianne Hackbornf02b60a2012-08-16 10:48:27 -070033import android.os.UserHandle;
Julia Reynoldse24faa22020-04-02 12:44:47 -040034import android.provider.Settings;
Julia Reynolds7c267522020-01-16 11:26:41 -050035import android.text.TextUtils;
Joe Onorato18e69df2010-05-17 22:26:12 -070036
Will Brockmancfd98302020-01-29 15:57:30 -050037import com.android.internal.logging.InstanceId;
Will Brockman828427e2019-01-28 09:55:45 -050038import com.android.internal.logging.nano.MetricsProto;
Eyal Posenera9cf9c72018-12-18 16:23:54 +020039import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
40
Will Brockmanc22772c2019-06-14 14:55:31 -040041import java.util.ArrayList;
42
Daniel Sandler2561b0b2012-02-13 21:04:12 -050043/**
Daniel Sandlerfde19b12013-01-17 00:21:05 -050044 * Class encapsulating a Notification. Sent by the NotificationManagerService to clients including
Daniel Sandler5feceeb2013-03-22 18:29:23 -070045 * the status bar and any {@link android.service.notification.NotificationListenerService}s.
Daniel Sandler2561b0b2012-02-13 21:04:12 -050046 */
Joe Onorato18e69df2010-05-17 22:26:12 -070047public class StatusBarNotification implements Parcelable {
Eyal Posenera9cf9c72018-12-18 16:23:54 +020048 static final int MAX_LOG_TAG_LENGTH = 36;
49
Mathew Inwoode3807372018-08-10 09:51:03 +010050 @UnsupportedAppUsage
Daniel Sandlere6f7f2e2013-04-25 15:44:16 -040051 private final String pkg;
Mathew Inwoode3807372018-08-10 09:51:03 +010052 @UnsupportedAppUsage
Daniel Sandlere6f7f2e2013-04-25 15:44:16 -040053 private final int id;
Mathew Inwood31755f92018-12-20 13:53:36 +000054 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
Daniel Sandlere6f7f2e2013-04-25 15:44:16 -040055 private final String tag;
John Spurlocka4294292014-03-24 18:02:32 -040056 private final String key;
Julia Reynoldse46bb372016-03-17 11:05:58 -040057 private String groupKey;
58 private String overrideGroupKey;
Daniel Sandler5feceeb2013-03-22 18:29:23 -070059
Mathew Inwoode3807372018-08-10 09:51:03 +010060 @UnsupportedAppUsage
Daniel Sandlere6f7f2e2013-04-25 15:44:16 -040061 private final int uid;
Christoph Studer8fd7f1e2014-04-11 17:35:05 -040062 private final String opPkg;
Mathew Inwood31755f92018-12-20 13:53:36 +000063 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
Daniel Sandlere6f7f2e2013-04-25 15:44:16 -040064 private final int initialPid;
Mathew Inwood31755f92018-12-20 13:53:36 +000065 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
Daniel Sandlere6f7f2e2013-04-25 15:44:16 -040066 private final Notification notification;
Mathew Inwood31755f92018-12-20 13:53:36 +000067 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
Daniel Sandlere6f7f2e2013-04-25 15:44:16 -040068 private final UserHandle user;
Mathew Inwood31755f92018-12-20 13:53:36 +000069 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
Daniel Sandlere6f7f2e2013-04-25 15:44:16 -040070 private final long postTime;
Will Brockmancfd98302020-01-29 15:57:30 -050071 // A small per-notification ID, used for statsd logging.
72 private InstanceId mInstanceId; // Not final, see setInstanceId()
Jeff Sharkey6d515712012-09-20 16:06:08 -070073
Dan Sandler68079d52015-07-22 10:45:30 -040074 private Context mContext; // used for inflation & icon expansion
Daniel Sandler5feceeb2013-03-22 18:29:23 -070075
Daniel Sandler5feceeb2013-03-22 18:29:23 -070076 /** @hide */
Julia Reynolds924eed12017-01-19 09:52:07 -050077 public StatusBarNotification(String pkg, String opPkg, int id,
Julia Reynolds423b9fc2016-11-09 09:51:08 -050078 String tag, int uid, int initialPid, Notification notification, UserHandle user,
79 String overrideGroupKey, long postTime) {
Julia Reynoldse46bb372016-03-17 11:05:58 -040080 if (pkg == null) throw new NullPointerException();
81 if (notification == null) throw new NullPointerException();
82
83 this.pkg = pkg;
84 this.opPkg = opPkg;
85 this.id = id;
86 this.tag = tag;
87 this.uid = uid;
88 this.initialPid = initialPid;
89 this.notification = notification;
90 this.user = user;
91 this.postTime = postTime;
92 this.overrideGroupKey = overrideGroupKey;
93 this.key = key();
94 this.groupKey = groupKey();
95 }
96
Julia Reynoldsa11d0b12017-02-16 15:01:36 -050097 /**
98 * @deprecated Non-system apps should not need to create StatusBarNotifications.
99 */
Julia Reynolds423b9fc2016-11-09 09:51:08 -0500100 @Deprecated
Christoph Studer8fd7f1e2014-04-11 17:35:05 -0400101 public StatusBarNotification(String pkg, String opPkg, int id, String tag, int uid,
Daniel Sandlerfde19b12013-01-17 00:21:05 -0500102 int initialPid, int score, Notification notification, UserHandle user,
103 long postTime) {
Joe Onorato18e69df2010-05-17 22:26:12 -0700104 if (pkg == null) throw new NullPointerException();
105 if (notification == null) throw new NullPointerException();
106
107 this.pkg = pkg;
Christoph Studer8fd7f1e2014-04-11 17:35:05 -0400108 this.opPkg = opPkg;
Joe Onorato18e69df2010-05-17 22:26:12 -0700109 this.id = id;
110 this.tag = tag;
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -0700111 this.uid = uid;
112 this.initialPid = initialPid;
Joe Onorato18e69df2010-05-17 22:26:12 -0700113 this.notification = notification;
Jeff Sharkey6d515712012-09-20 16:06:08 -0700114 this.user = user;
Daniel Sandlerfde19b12013-01-17 00:21:05 -0500115 this.postTime = postTime;
John Spurlocka4294292014-03-24 18:02:32 -0400116 this.key = key();
Chris Wren1031c972014-07-23 13:11:45 +0000117 this.groupKey = groupKey();
Joe Onorato18e69df2010-05-17 22:26:12 -0700118 }
119
120 public StatusBarNotification(Parcel in) {
Joe Onorato18e69df2010-05-17 22:26:12 -0700121 this.pkg = in.readString();
Christoph Studer8fd7f1e2014-04-11 17:35:05 -0400122 this.opPkg = in.readString();
Joe Onorato18e69df2010-05-17 22:26:12 -0700123 this.id = in.readInt();
124 if (in.readInt() != 0) {
125 this.tag = in.readString();
126 } else {
127 this.tag = null;
128 }
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -0700129 this.uid = in.readInt();
130 this.initialPid = in.readInt();
Joe Onorato18e69df2010-05-17 22:26:12 -0700131 this.notification = new Notification(in);
Jeff Sharkey6d515712012-09-20 16:06:08 -0700132 this.user = UserHandle.readFromParcel(in);
Daniel Sandlerfde19b12013-01-17 00:21:05 -0500133 this.postTime = in.readLong();
Julia Reynoldse46bb372016-03-17 11:05:58 -0400134 if (in.readInt() != 0) {
135 this.overrideGroupKey = in.readString();
Will Brockmancfd98302020-01-29 15:57:30 -0500136 }
137 if (in.readInt() != 0) {
138 this.mInstanceId = InstanceId.CREATOR.createFromParcel(in);
Julia Reynoldse46bb372016-03-17 11:05:58 -0400139 }
John Spurlocka4294292014-03-24 18:02:32 -0400140 this.key = key();
Chris Wren1031c972014-07-23 13:11:45 +0000141 this.groupKey = groupKey();
John Spurlocka4294292014-03-24 18:02:32 -0400142 }
143
144 private String key() {
Julia Reynoldse46bb372016-03-17 11:05:58 -0400145 String sbnKey = user.getIdentifier() + "|" + pkg + "|" + id + "|" + tag + "|" + uid;
146 if (overrideGroupKey != null && getNotification().isGroupSummary()) {
147 sbnKey = sbnKey + "|" + overrideGroupKey;
148 }
149 return sbnKey;
Joe Onorato18e69df2010-05-17 22:26:12 -0700150 }
151
Chris Wren1031c972014-07-23 13:11:45 +0000152 private String groupKey() {
Julia Reynoldse46bb372016-03-17 11:05:58 -0400153 if (overrideGroupKey != null) {
154 return user.getIdentifier() + "|" + pkg + "|" + "g:" + overrideGroupKey;
155 }
Chris Wren1031c972014-07-23 13:11:45 +0000156 final String group = getNotification().getGroup();
157 final String sortKey = getNotification().getSortKey();
158 if (group == null && sortKey == null) {
159 // a group of one
160 return key;
161 }
162 return user.getIdentifier() + "|" + pkg + "|" +
163 (group == null
Julia Reynoldsbad42972017-04-25 13:52:49 -0400164 ? "c:" + notification.getChannelId()
Chris Wren1031c972014-07-23 13:11:45 +0000165 : "g:" + group);
166 }
167
Julia Reynoldse46bb372016-03-17 11:05:58 -0400168 /**
169 * Returns true if this notification is part of a group.
170 */
171 public boolean isGroup() {
Chris Wren8a1638f2016-05-02 16:19:14 -0400172 if (overrideGroupKey != null || isAppGroup()) {
173 return true;
174 }
175 return false;
176 }
177
178 /**
179 * Returns true if application asked that this notification be part of a group.
Chris Wren8a1638f2016-05-02 16:19:14 -0400180 */
181 public boolean isAppGroup() {
182 if (getNotification().getGroup() != null || getNotification().getSortKey() != null) {
Julia Reynoldse46bb372016-03-17 11:05:58 -0400183 return true;
184 }
185 return false;
186 }
187
Joe Onorato18e69df2010-05-17 22:26:12 -0700188 public void writeToParcel(Parcel out, int flags) {
189 out.writeString(this.pkg);
Christoph Studer8fd7f1e2014-04-11 17:35:05 -0400190 out.writeString(this.opPkg);
Joe Onorato18e69df2010-05-17 22:26:12 -0700191 out.writeInt(this.id);
192 if (this.tag != null) {
193 out.writeInt(1);
194 out.writeString(this.tag);
195 } else {
196 out.writeInt(0);
197 }
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -0700198 out.writeInt(this.uid);
199 out.writeInt(this.initialPid);
Joe Onorato18e69df2010-05-17 22:26:12 -0700200 this.notification.writeToParcel(out, flags);
Jeff Sharkey6d515712012-09-20 16:06:08 -0700201 user.writeToParcel(out, flags);
Daniel Sandlerfde19b12013-01-17 00:21:05 -0500202 out.writeLong(this.postTime);
Julia Reynoldse46bb372016-03-17 11:05:58 -0400203 if (this.overrideGroupKey != null) {
204 out.writeInt(1);
205 out.writeString(this.overrideGroupKey);
206 } else {
207 out.writeInt(0);
208 }
Will Brockmancfd98302020-01-29 15:57:30 -0500209 if (this.mInstanceId != null) {
210 out.writeInt(1);
211 mInstanceId.writeToParcel(out, flags);
212 } else {
213 out.writeInt(0);
214 }
Joe Onorato18e69df2010-05-17 22:26:12 -0700215 }
216
217 public int describeContents() {
218 return 0;
219 }
220
Will Brockmanc22772c2019-06-14 14:55:31 -0400221 public static final @android.annotation.NonNull
222 Parcelable.Creator<StatusBarNotification> CREATOR =
223 new Parcelable.Creator<StatusBarNotification>() {
224 public StatusBarNotification createFromParcel(Parcel parcel) {
225 return new StatusBarNotification(parcel);
226 }
Joe Onorato18e69df2010-05-17 22:26:12 -0700227
Will Brockmanc22772c2019-06-14 14:55:31 -0400228 public StatusBarNotification[] newArray(int size) {
229 return new StatusBarNotification[size];
230 }
Joe Onorato18e69df2010-05-17 22:26:12 -0700231 };
232
Daniel Sandler1a497d32013-04-18 14:52:45 -0400233 /**
234 * @hide
235 */
236 public StatusBarNotification cloneLight() {
237 final Notification no = new Notification();
238 this.notification.cloneInto(no, false); // light copy
Will Brockman492b3812020-03-03 16:29:36 +0000239 return cloneShallow(no);
Daniel Sandler1a497d32013-04-18 14:52:45 -0400240 }
241
Jeff Sharkey6d515712012-09-20 16:06:08 -0700242 @Override
Joe Onorato18e69df2010-05-17 22:26:12 -0700243 public StatusBarNotification clone() {
Will Brockman492b3812020-03-03 16:29:36 +0000244 return cloneShallow(this.notification.clone());
245 }
246
247 /**
248 * @param notification Some kind of clone of this.notification.
249 * @return A shallow copy of self, with notification in place of this.notification.
250 */
251 StatusBarNotification cloneShallow(Notification notification) {
252 StatusBarNotification result = new StatusBarNotification(this.pkg, this.opPkg,
Daniel Sandlerfde19b12013-01-17 00:21:05 -0500253 this.id, this.tag, this.uid, this.initialPid,
Will Brockman492b3812020-03-03 16:29:36 +0000254 notification, this.user, this.overrideGroupKey, this.postTime);
255 result.setInstanceId(this.mInstanceId);
256 return result;
Joe Onorato18e69df2010-05-17 22:26:12 -0700257 }
258
Jeff Sharkey6d515712012-09-20 16:06:08 -0700259 @Override
Joe Onorato18e69df2010-05-17 22:26:12 -0700260 public String toString() {
Daniel Sandlerfde19b12013-01-17 00:21:05 -0500261 return String.format(
Julia Reynoldse46bb372016-03-17 11:05:58 -0400262 "StatusBarNotification(pkg=%s user=%s id=%d tag=%s key=%s: %s)",
Daniel Sandlerfde19b12013-01-17 00:21:05 -0500263 this.pkg, this.user, this.id, this.tag,
Julia Reynoldse46bb372016-03-17 11:05:58 -0400264 this.key, this.notification);
Joe Onorato18e69df2010-05-17 22:26:12 -0700265 }
266
Will Brockmanc22772c2019-06-14 14:55:31 -0400267 /**
268 * Convenience method to check the notification's flags for
Daniel Sandler5feceeb2013-03-22 18:29:23 -0700269 * {@link Notification#FLAG_ONGOING_EVENT}.
270 */
Joe Onoratoe345fff2010-05-23 15:18:27 -0400271 public boolean isOngoing() {
272 return (notification.flags & Notification.FLAG_ONGOING_EVENT) != 0;
273 }
274
Will Brockmanc22772c2019-06-14 14:55:31 -0400275 /**
276 * Convenience method to check the notification's flags for
Daniel Sandler5feceeb2013-03-22 18:29:23 -0700277 * either {@link Notification#FLAG_ONGOING_EVENT} or
278 * {@link Notification#FLAG_NO_CLEAR}.
279 */
Joe Onorato5dd11692010-09-27 15:34:04 -0700280 public boolean isClearable() {
281 return ((notification.flags & Notification.FLAG_ONGOING_EVENT) == 0)
282 && ((notification.flags & Notification.FLAG_NO_CLEAR) == 0);
283 }
Daniel Sandlerb9301c32012-08-14 15:08:24 -0400284
Kenny Guya263e4e2014-03-03 18:24:03 +0000285 /**
Julia Reynoldsd5261e12016-12-19 14:14:25 -0500286 * Returns a userid for whom this notification is intended.
Kenny Guya263e4e2014-03-03 18:24:03 +0000287 *
288 * @deprecated Use {@link #getUser()} instead.
289 */
Aurimas Liutikas514c5ef2016-05-24 15:22:55 -0700290 @Deprecated
Daniel Sandlerb9301c32012-08-14 15:08:24 -0400291 public int getUserId() {
Dianne Hackborn50cdf7c32012-09-23 17:08:57 -0700292 return this.user.getIdentifier();
Daniel Sandlerb9301c32012-08-14 15:08:24 -0400293 }
Daniel Sandlere6f7f2e2013-04-25 15:44:16 -0400294
Julia Reynoldsb5535c62020-04-13 11:03:44 -0400295 /**
296 * Like {@link #getUserId()} but handles special users.
297 * @hide
298 */
299 public int getNormalizedUserId() {
300 int userId = getUserId();
301 if (userId == UserHandle.USER_ALL) {
302 userId = UserHandle.USER_SYSTEM;
303 }
304 return userId;
305 }
306
Julia Reynoldsa7ba45a2018-08-29 09:07:52 -0400307 /** The package that the notification belongs to. */
Daniel Sandler4f91efd2013-04-25 16:38:41 -0400308 public String getPackageName() {
Daniel Sandlere6f7f2e2013-04-25 15:44:16 -0400309 return pkg;
310 }
311
Will Brockmanc22772c2019-06-14 14:55:31 -0400312 /** The id supplied to {@link android.app.NotificationManager#notify(int, Notification)}. */
Daniel Sandlere6f7f2e2013-04-25 15:44:16 -0400313 public int getId() {
314 return id;
315 }
316
Will Brockmanc22772c2019-06-14 14:55:31 -0400317 /**
318 * The tag supplied to {@link android.app.NotificationManager#notify(int, Notification)},
319 * or null if no tag was specified.
320 */
Daniel Sandlere6f7f2e2013-04-25 15:44:16 -0400321 public String getTag() {
322 return tag;
323 }
324
Julia Reynoldsa7ba45a2018-08-29 09:07:52 -0400325 /**
326 * The notifying app's ({@link #getPackageName()}'s) uid.
327 */
Daniel Sandlere6f7f2e2013-04-25 15:44:16 -0400328 public int getUid() {
329 return uid;
330 }
331
Julia Reynolds98460762019-03-18 13:13:55 -0400332 /**
333 * The package that posted the notification.
334 * <p> Might be different from {@link #getPackageName()} if the app owning the notification has
Julia Reynoldsa7ba45a2018-08-29 09:07:52 -0400335 * a {@link NotificationManager#setNotificationDelegate(String) notification delegate}.
336 */
Julia Reynoldscbc45e72019-03-07 12:31:52 -0500337 public @NonNull String getOpPkg() {
Christoph Studer8fd7f1e2014-04-11 17:35:05 -0400338 return opPkg;
Daniel Sandlere6f7f2e2013-04-25 15:44:16 -0400339 }
340
341 /** @hide */
Mathew Inwoode3807372018-08-10 09:51:03 +0100342 @UnsupportedAppUsage
Daniel Sandlere6f7f2e2013-04-25 15:44:16 -0400343 public int getInitialPid() {
344 return initialPid;
345 }
346
Will Brockmanc22772c2019-06-14 14:55:31 -0400347 /**
348 * The {@link android.app.Notification} supplied to
349 * {@link android.app.NotificationManager#notify(int, Notification)}.
350 */
Daniel Sandlere6f7f2e2013-04-25 15:44:16 -0400351 public Notification getNotification() {
352 return notification;
353 }
354
355 /**
356 * The {@link android.os.UserHandle} for whom this notification is intended.
Daniel Sandlere6f7f2e2013-04-25 15:44:16 -0400357 */
358 public UserHandle getUser() {
359 return user;
360 }
361
Will Brockmanc22772c2019-06-14 14:55:31 -0400362 /**
363 * The time (in {@link System#currentTimeMillis} time) the notification was posted,
Daniel Sandlere6f7f2e2013-04-25 15:44:16 -0400364 * which may be different than {@link android.app.Notification#when}.
365 */
366 public long getPostTime() {
367 return postTime;
368 }
369
John Spurlocka4294292014-03-24 18:02:32 -0400370 /**
371 * A unique instance key for this notification record.
372 */
373 public String getKey() {
374 return key;
375 }
Chris Wren1031c972014-07-23 13:11:45 +0000376
377 /**
378 * A key that indicates the group with which this message ranks.
379 */
380 public String getGroupKey() {
381 return groupKey;
382 }
Dan Sandler68079d52015-07-22 10:45:30 -0400383
384 /**
Chris Wrenb3921792017-06-01 13:34:46 -0400385 * The ID passed to setGroup(), or the override, or null.
Will Brockmanc22772c2019-06-14 14:55:31 -0400386 *
Chris Wrenb3921792017-06-01 13:34:46 -0400387 * @hide
388 */
389 public String getGroup() {
390 if (overrideGroupKey != null) {
391 return overrideGroupKey;
392 }
393 return getNotification().getGroup();
394 }
395
396 /**
Julia Reynoldse46bb372016-03-17 11:05:58 -0400397 * Sets the override group key.
398 */
399 public void setOverrideGroupKey(String overrideGroupKey) {
400 this.overrideGroupKey = overrideGroupKey;
401 groupKey = groupKey();
402 }
403
404 /**
405 * Returns the override group key.
406 */
407 public String getOverrideGroupKey() {
408 return overrideGroupKey;
409 }
410
411 /**
Dan Sandler68079d52015-07-22 10:45:30 -0400412 * @hide
413 */
Amin Shaikhc3f0b062019-02-12 19:00:17 -0500414 public void clearPackageContext() {
415 mContext = null;
416 }
417
418 /**
419 * @hide
420 */
Will Brockmancfd98302020-01-29 15:57:30 -0500421 public InstanceId getInstanceId() {
422 return mInstanceId;
423 }
424
425 /**
426 * @hide
427 */
428 public void setInstanceId(InstanceId instanceId) {
429 mInstanceId = instanceId;
430 }
431
432 /**
433 * @hide
434 */
Mathew Inwoode3807372018-08-10 09:51:03 +0100435 @UnsupportedAppUsage
Dan Sandler68079d52015-07-22 10:45:30 -0400436 public Context getPackageContext(Context context) {
437 if (mContext == null) {
438 try {
439 ApplicationInfo ai = context.getPackageManager()
Amith Yamasani0d1fd8d2016-10-12 14:21:51 -0700440 .getApplicationInfoAsUser(pkg, PackageManager.MATCH_UNINSTALLED_PACKAGES,
441 getUserId());
Dan Sandler68079d52015-07-22 10:45:30 -0400442 mContext = context.createApplicationContext(ai,
443 Context.CONTEXT_RESTRICTED);
444 } catch (PackageManager.NameNotFoundException e) {
445 mContext = null;
446 }
447 }
448 if (mContext == null) {
449 mContext = context;
450 }
451 return mContext;
452 }
Eyal Posenera9cf9c72018-12-18 16:23:54 +0200453
454 /**
455 * Returns a LogMaker that contains all basic information of the notification.
Will Brockmanc22772c2019-06-14 14:55:31 -0400456 *
Eyal Posenera9cf9c72018-12-18 16:23:54 +0200457 * @hide
458 */
459 public LogMaker getLogMaker() {
Will Brockmanc22772c2019-06-14 14:55:31 -0400460 LogMaker logMaker = new LogMaker(MetricsEvent.VIEW_UNKNOWN).setPackageName(getPackageName())
Eyal Posenera9cf9c72018-12-18 16:23:54 +0200461 .addTaggedData(MetricsEvent.NOTIFICATION_ID, getId())
462 .addTaggedData(MetricsEvent.NOTIFICATION_TAG, getTag())
Will Brockman0ed07ca2019-03-08 11:45:34 -0500463 .addTaggedData(MetricsEvent.FIELD_NOTIFICATION_CHANNEL_ID, getChannelIdLogTag())
464 .addTaggedData(MetricsEvent.FIELD_NOTIFICATION_GROUP_ID, getGroupLogTag())
465 .addTaggedData(MetricsEvent.FIELD_NOTIFICATION_GROUP_SUMMARY,
466 getNotification().isGroupSummary() ? 1 : 0)
467 .addTaggedData(MetricsProto.MetricsEvent.FIELD_NOTIFICATION_CATEGORY,
468 getNotification().category);
Will Brockmanc22772c2019-06-14 14:55:31 -0400469 if (getNotification().extras != null) {
470 // Log the style used, if present. We only log the hash here, as notification log
471 // events are frequent, while there are few styles (hence low chance of collisions).
472 String template = getNotification().extras.getString(Notification.EXTRA_TEMPLATE);
473 if (template != null && !template.isEmpty()) {
474 logMaker.addTaggedData(MetricsEvent.FIELD_NOTIFICATION_STYLE,
475 template.hashCode());
476 }
477 ArrayList<Person> people = getNotification().extras.getParcelableArrayList(
478 Notification.EXTRA_PEOPLE_LIST);
479 if (people != null && !people.isEmpty()) {
480 logMaker.addTaggedData(MetricsEvent.FIELD_NOTIFICATION_PEOPLE, people.size());
481 }
482 }
483 return logMaker;
Eyal Posenera9cf9c72018-12-18 16:23:54 +0200484 }
485
Julia Reynolds7c267522020-01-16 11:26:41 -0500486 /**
487 * @hide
488 */
489 public String getShortcutId(Context context) {
490 String conversationId = getNotification().getShortcutId();
Julia Reynoldse24faa22020-04-02 12:44:47 -0400491 if (TextUtils.isEmpty(conversationId)
492 && (Settings.Global.getInt(context.getContentResolver(),
493 Settings.Global.REQUIRE_SHORTCUTS_FOR_CONVERSATIONS, 0) == 0)
494 && getNotification().getNotificationStyle() == Notification.MessagingStyle.class) {
Julia Reynolds7c267522020-01-16 11:26:41 -0500495 conversationId = getId() + getTag() + PLACEHOLDER_CONVERSATION_ID;
496 }
497 return conversationId;
498 }
499
Will Brockman2b6959e2020-01-22 09:59:50 -0500500 /**
501 * Returns a probably-unique string based on the notification's group name,
502 * with no more than MAX_LOG_TAG_LENGTH characters.
503 * @return String based on group name of notification.
504 * @hide
505 */
506 public String getGroupLogTag() {
Eyal Posenera9cf9c72018-12-18 16:23:54 +0200507 return shortenTag(getGroup());
508 }
509
Will Brockman2b6959e2020-01-22 09:59:50 -0500510 /**
511 * Returns a probably-unique string based on the notification's channel ID,
512 * with no more than MAX_LOG_TAG_LENGTH characters.
513 * @return String based on channel ID of notification.
514 * @hide
515 */
516 public String getChannelIdLogTag() {
Eyal Posenera9cf9c72018-12-18 16:23:54 +0200517 if (notification.getChannelId() == null) {
518 return null;
519 }
520 return shortenTag(notification.getChannelId());
521 }
522
523 // Make logTag with max size MAX_LOG_TAG_LENGTH.
524 // For shorter or equal tags, returns the tag.
525 // For longer tags, truncate the tag and append a hash of the full tag to
526 // fill the maximum size.
527 private String shortenTag(String logTag) {
528 if (logTag == null || logTag.length() <= MAX_LOG_TAG_LENGTH) {
529 return logTag;
530 }
531 String hash = Integer.toHexString(logTag.hashCode());
532 return logTag.substring(0, MAX_LOG_TAG_LENGTH - hash.length() - 1) + "-"
Will Brockmanc22772c2019-06-14 14:55:31 -0400533 + hash;
Eyal Posenera9cf9c72018-12-18 16:23:54 +0200534 }
Joe Onorato18e69df2010-05-17 22:26:12 -0700535}