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