StatusBarNotification.java revision a33f5c4312ce708933454dfd1b154ccc46be099c
1/* 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 17package android.service.notification; 18 19import android.app.Notification; 20import android.app.NotificationChannel; 21import android.content.Context; 22import android.content.pm.ApplicationInfo; 23import android.content.pm.PackageManager; 24import android.os.Parcel; 25import android.os.Parcelable; 26import android.os.UserHandle; 27 28/** 29 * Class encapsulating a Notification. Sent by the NotificationManagerService to clients including 30 * the status bar and any {@link android.service.notification.NotificationListenerService}s. 31 */ 32public class StatusBarNotification implements Parcelable { 33 private final String pkg; 34 private final int id; 35 private final String tag; 36 private final String key; 37 private String groupKey; 38 private String overrideGroupKey; 39 40 private final int uid; 41 private final String opPkg; 42 private final int initialPid; 43 private final Notification notification; 44 private final UserHandle user; 45 private final long postTime; 46 47 private Context mContext; // used for inflation & icon expansion 48 49 /** @hide */ 50 public StatusBarNotification(String pkg, String opPkg, int id, 51 String tag, int uid, int initialPid, Notification notification, UserHandle user, 52 String overrideGroupKey, long postTime) { 53 if (pkg == null) throw new NullPointerException(); 54 if (notification == null) throw new NullPointerException(); 55 56 this.pkg = pkg; 57 this.opPkg = opPkg; 58 this.id = id; 59 this.tag = tag; 60 this.uid = uid; 61 this.initialPid = initialPid; 62 this.notification = notification; 63 this.user = user; 64 this.postTime = postTime; 65 this.overrideGroupKey = overrideGroupKey; 66 this.key = key(); 67 this.groupKey = groupKey(); 68 } 69 70 @Deprecated 71 public StatusBarNotification(String pkg, String opPkg, int id, String tag, int uid, 72 int initialPid, int score, Notification notification, UserHandle user, 73 long postTime) { 74 if (pkg == null) throw new NullPointerException(); 75 if (notification == null) throw new NullPointerException(); 76 77 this.pkg = pkg; 78 this.opPkg = opPkg; 79 this.id = id; 80 this.tag = tag; 81 this.uid = uid; 82 this.initialPid = initialPid; 83 this.notification = notification; 84 this.user = user; 85 this.postTime = postTime; 86 this.key = key(); 87 this.groupKey = groupKey(); 88 } 89 90 public StatusBarNotification(Parcel in) { 91 this.pkg = in.readString(); 92 this.opPkg = in.readString(); 93 this.id = in.readInt(); 94 if (in.readInt() != 0) { 95 this.tag = in.readString(); 96 } else { 97 this.tag = null; 98 } 99 this.uid = in.readInt(); 100 this.initialPid = in.readInt(); 101 this.notification = new Notification(in); 102 this.user = UserHandle.readFromParcel(in); 103 this.postTime = in.readLong(); 104 if (in.readInt() != 0) { 105 this.overrideGroupKey = in.readString(); 106 } else { 107 this.overrideGroupKey = null; 108 } 109 this.key = key(); 110 this.groupKey = groupKey(); 111 } 112 113 private String key() { 114 String sbnKey = user.getIdentifier() + "|" + pkg + "|" + id + "|" + tag + "|" + uid; 115 if (overrideGroupKey != null && getNotification().isGroupSummary()) { 116 sbnKey = sbnKey + "|" + overrideGroupKey; 117 } 118 return sbnKey; 119 } 120 121 private String groupKey() { 122 if (overrideGroupKey != null) { 123 return user.getIdentifier() + "|" + pkg + "|" + "g:" + overrideGroupKey; 124 } 125 final String group = getNotification().getGroup(); 126 final String sortKey = getNotification().getSortKey(); 127 if (group == null && sortKey == null) { 128 // a group of one 129 return key; 130 } 131 return user.getIdentifier() + "|" + pkg + "|" + 132 (group == null 133 ? "c:" + notification.getChannel() 134 : "g:" + group); 135 } 136 137 /** 138 * Returns true if this notification is part of a group. 139 */ 140 public boolean isGroup() { 141 if (overrideGroupKey != null || isAppGroup()) { 142 return true; 143 } 144 return false; 145 } 146 147 /** 148 * Returns true if application asked that this notification be part of a group. 149 * @hide 150 */ 151 public boolean isAppGroup() { 152 if (getNotification().getGroup() != null || getNotification().getSortKey() != null) { 153 return true; 154 } 155 return false; 156 } 157 158 public void writeToParcel(Parcel out, int flags) { 159 out.writeString(this.pkg); 160 out.writeString(this.opPkg); 161 out.writeInt(this.id); 162 if (this.tag != null) { 163 out.writeInt(1); 164 out.writeString(this.tag); 165 } else { 166 out.writeInt(0); 167 } 168 out.writeInt(this.uid); 169 out.writeInt(this.initialPid); 170 this.notification.writeToParcel(out, flags); 171 user.writeToParcel(out, flags); 172 173 out.writeLong(this.postTime); 174 if (this.overrideGroupKey != null) { 175 out.writeInt(1); 176 out.writeString(this.overrideGroupKey); 177 } else { 178 out.writeInt(0); 179 } 180 } 181 182 public int describeContents() { 183 return 0; 184 } 185 186 public static final Parcelable.Creator<StatusBarNotification> CREATOR 187 = new Parcelable.Creator<StatusBarNotification>() 188 { 189 public StatusBarNotification createFromParcel(Parcel parcel) 190 { 191 return new StatusBarNotification(parcel); 192 } 193 194 public StatusBarNotification[] newArray(int size) 195 { 196 return new StatusBarNotification[size]; 197 } 198 }; 199 200 /** 201 * @hide 202 */ 203 public StatusBarNotification cloneLight() { 204 final Notification no = new Notification(); 205 this.notification.cloneInto(no, false); // light copy 206 return new StatusBarNotification(this.pkg, this.opPkg, 207 this.id, this.tag, this.uid, this.initialPid, 208 no, this.user, this.overrideGroupKey, this.postTime); 209 } 210 211 @Override 212 public StatusBarNotification clone() { 213 return new StatusBarNotification(this.pkg, this.opPkg, 214 this.id, this.tag, this.uid, this.initialPid, 215 this.notification.clone(), this.user, this.overrideGroupKey, this.postTime); 216 } 217 218 @Override 219 public String toString() { 220 return String.format( 221 "StatusBarNotification(pkg=%s user=%s id=%d tag=%s key=%s: %s)", 222 this.pkg, this.user, this.id, this.tag, 223 this.key, this.notification); 224 } 225 226 /** Convenience method to check the notification's flags for 227 * {@link Notification#FLAG_ONGOING_EVENT}. 228 */ 229 public boolean isOngoing() { 230 return (notification.flags & Notification.FLAG_ONGOING_EVENT) != 0; 231 } 232 233 /** Convenience method to check the notification's flags for 234 * either {@link Notification#FLAG_ONGOING_EVENT} or 235 * {@link Notification#FLAG_NO_CLEAR}. 236 */ 237 public boolean isClearable() { 238 return ((notification.flags & Notification.FLAG_ONGOING_EVENT) == 0) 239 && ((notification.flags & Notification.FLAG_NO_CLEAR) == 0); 240 } 241 242 /** 243 * Returns a userid for whom this notification is intended. 244 * 245 * @deprecated Use {@link #getUser()} instead. 246 */ 247 @Deprecated 248 public int getUserId() { 249 return this.user.getIdentifier(); 250 } 251 252 /** The package of the app that posted the notification. */ 253 public String getPackageName() { 254 return pkg; 255 } 256 257 /** The id supplied to {@link android.app.NotificationManager#notify(int,Notification)}. */ 258 public int getId() { 259 return id; 260 } 261 262 /** The tag supplied to {@link android.app.NotificationManager#notify(int,Notification)}, 263 * or null if no tag was specified. */ 264 public String getTag() { 265 return tag; 266 } 267 268 /** The notifying app's calling uid. @hide */ 269 public int getUid() { 270 return uid; 271 } 272 273 /** The package used for AppOps tracking. @hide */ 274 public String getOpPkg() { 275 return opPkg; 276 } 277 278 /** @hide */ 279 public int getInitialPid() { 280 return initialPid; 281 } 282 283 /** The {@link android.app.Notification} supplied to 284 * {@link android.app.NotificationManager#notify(int,Notification)}. */ 285 public Notification getNotification() { 286 return notification; 287 } 288 289 /** 290 * The {@link android.os.UserHandle} for whom this notification is intended. 291 */ 292 public UserHandle getUser() { 293 return user; 294 } 295 296 /** The time (in {@link System#currentTimeMillis} time) the notification was posted, 297 * which may be different than {@link android.app.Notification#when}. 298 */ 299 public long getPostTime() { 300 return postTime; 301 } 302 303 /** 304 * A unique instance key for this notification record. 305 */ 306 public String getKey() { 307 return key; 308 } 309 310 /** 311 * A key that indicates the group with which this message ranks. 312 */ 313 public String getGroupKey() { 314 return groupKey; 315 } 316 317 /** 318 * Sets the override group key. 319 */ 320 public void setOverrideGroupKey(String overrideGroupKey) { 321 this.overrideGroupKey = overrideGroupKey; 322 groupKey = groupKey(); 323 } 324 325 /** 326 * Returns the override group key. 327 */ 328 public String getOverrideGroupKey() { 329 return overrideGroupKey; 330 } 331 332 /** 333 * @hide 334 */ 335 public Context getPackageContext(Context context) { 336 if (mContext == null) { 337 try { 338 ApplicationInfo ai = context.getPackageManager() 339 .getApplicationInfoAsUser(pkg, PackageManager.MATCH_UNINSTALLED_PACKAGES, 340 getUserId()); 341 mContext = context.createApplicationContext(ai, 342 Context.CONTEXT_RESTRICTED); 343 } catch (PackageManager.NameNotFoundException e) { 344 mContext = null; 345 } 346 } 347 if (mContext == null) { 348 mContext = context; 349 } 350 return mContext; 351 } 352} 353