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