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 17 package android.service.notification; 18 19 import android.app.Notification; 20 import android.content.Context; 21 import android.content.pm.ApplicationInfo; 22 import android.content.pm.PackageManager; 23 import android.os.Parcel; 24 import android.os.Parcelable; 25 import 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 */ 31 public 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 final String groupKey; 37 38 private final int uid; 39 private final String opPkg; 40 private final int initialPid; 41 private final Notification notification; 42 private final UserHandle user; 43 private final long postTime; 44 45 private final int score; 46 private Context mContext; // used for inflation & icon expansion 47 48 /** @hide */ StatusBarNotification(String pkg, String opPkg, int id, String tag, int uid, int initialPid, int score, Notification notification, UserHandle user)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 StatusBarNotification(String pkg, String opPkg, int id, String tag, int uid, int initialPid, int score, Notification notification, UserHandle user, long postTime)55 public StatusBarNotification(String pkg, String opPkg, int id, String tag, int uid, 56 int initialPid, int score, Notification notification, UserHandle user, 57 long postTime) { 58 if (pkg == null) throw new NullPointerException(); 59 if (notification == null) throw new NullPointerException(); 60 61 this.pkg = pkg; 62 this.opPkg = opPkg; 63 this.id = id; 64 this.tag = tag; 65 this.uid = uid; 66 this.initialPid = initialPid; 67 this.score = score; 68 this.notification = notification; 69 this.user = user; 70 this.postTime = postTime; 71 this.key = key(); 72 this.groupKey = groupKey(); 73 } 74 StatusBarNotification(Parcel in)75 public StatusBarNotification(Parcel in) { 76 this.pkg = in.readString(); 77 this.opPkg = in.readString(); 78 this.id = in.readInt(); 79 if (in.readInt() != 0) { 80 this.tag = in.readString(); 81 } else { 82 this.tag = null; 83 } 84 this.uid = in.readInt(); 85 this.initialPid = in.readInt(); 86 this.score = in.readInt(); 87 this.notification = new Notification(in); 88 this.user = UserHandle.readFromParcel(in); 89 this.postTime = in.readLong(); 90 this.key = key(); 91 this.groupKey = groupKey(); 92 } 93 key()94 private String key() { 95 return user.getIdentifier() + "|" + pkg + "|" + id + "|" + tag + "|" + uid; 96 } 97 groupKey()98 private String groupKey() { 99 final String group = getNotification().getGroup(); 100 final String sortKey = getNotification().getSortKey(); 101 if (group == null && sortKey == null) { 102 // a group of one 103 return key; 104 } 105 return user.getIdentifier() + "|" + pkg + "|" + 106 (group == null 107 ? "p:" + notification.priority 108 : "g:" + group); 109 } 110 writeToParcel(Parcel out, int flags)111 public void writeToParcel(Parcel out, int flags) { 112 out.writeString(this.pkg); 113 out.writeString(this.opPkg); 114 out.writeInt(this.id); 115 if (this.tag != null) { 116 out.writeInt(1); 117 out.writeString(this.tag); 118 } else { 119 out.writeInt(0); 120 } 121 out.writeInt(this.uid); 122 out.writeInt(this.initialPid); 123 out.writeInt(this.score); 124 this.notification.writeToParcel(out, flags); 125 user.writeToParcel(out, flags); 126 127 out.writeLong(this.postTime); 128 } 129 describeContents()130 public int describeContents() { 131 return 0; 132 } 133 134 public static final Parcelable.Creator<StatusBarNotification> CREATOR 135 = new Parcelable.Creator<StatusBarNotification>() 136 { 137 public StatusBarNotification createFromParcel(Parcel parcel) 138 { 139 return new StatusBarNotification(parcel); 140 } 141 142 public StatusBarNotification[] newArray(int size) 143 { 144 return new StatusBarNotification[size]; 145 } 146 }; 147 148 /** 149 * @hide 150 */ cloneLight()151 public StatusBarNotification cloneLight() { 152 final Notification no = new Notification(); 153 this.notification.cloneInto(no, false); // light copy 154 return new StatusBarNotification(this.pkg, this.opPkg, 155 this.id, this.tag, this.uid, this.initialPid, 156 this.score, no, this.user, this.postTime); 157 } 158 159 @Override clone()160 public StatusBarNotification clone() { 161 return new StatusBarNotification(this.pkg, this.opPkg, 162 this.id, this.tag, this.uid, this.initialPid, 163 this.score, this.notification.clone(), this.user, this.postTime); 164 } 165 166 @Override toString()167 public String toString() { 168 return String.format( 169 "StatusBarNotification(pkg=%s user=%s id=%d tag=%s score=%d key=%s: %s)", 170 this.pkg, this.user, this.id, this.tag, 171 this.score, this.key, this.notification); 172 } 173 174 /** Convenience method to check the notification's flags for 175 * {@link Notification#FLAG_ONGOING_EVENT}. 176 */ isOngoing()177 public boolean isOngoing() { 178 return (notification.flags & Notification.FLAG_ONGOING_EVENT) != 0; 179 } 180 181 /** Convenience method to check the notification's flags for 182 * either {@link Notification#FLAG_ONGOING_EVENT} or 183 * {@link Notification#FLAG_NO_CLEAR}. 184 */ isClearable()185 public boolean isClearable() { 186 return ((notification.flags & Notification.FLAG_ONGOING_EVENT) == 0) 187 && ((notification.flags & Notification.FLAG_NO_CLEAR) == 0); 188 } 189 190 /** 191 * Returns a userHandle for the instance of the app that posted this notification. 192 * 193 * @deprecated Use {@link #getUser()} instead. 194 */ getUserId()195 public int getUserId() { 196 return this.user.getIdentifier(); 197 } 198 199 /** The package of the app that posted the notification. */ getPackageName()200 public String getPackageName() { 201 return pkg; 202 } 203 204 /** The id supplied to {@link android.app.NotificationManager#notify(int,Notification)}. */ getId()205 public int getId() { 206 return id; 207 } 208 209 /** The tag supplied to {@link android.app.NotificationManager#notify(int,Notification)}, 210 * or null if no tag was specified. */ getTag()211 public String getTag() { 212 return tag; 213 } 214 215 /** The notifying app's calling uid. @hide */ getUid()216 public int getUid() { 217 return uid; 218 } 219 220 /** The package used for AppOps tracking. @hide */ getOpPkg()221 public String getOpPkg() { 222 return opPkg; 223 } 224 225 /** @hide */ getInitialPid()226 public int getInitialPid() { 227 return initialPid; 228 } 229 230 /** The {@link android.app.Notification} supplied to 231 * {@link android.app.NotificationManager#notify(int,Notification)}. */ getNotification()232 public Notification getNotification() { 233 return notification; 234 } 235 236 /** 237 * The {@link android.os.UserHandle} for whom this notification is intended. 238 */ getUser()239 public UserHandle getUser() { 240 return user; 241 } 242 243 /** The time (in {@link System#currentTimeMillis} time) the notification was posted, 244 * which may be different than {@link android.app.Notification#when}. 245 */ getPostTime()246 public long getPostTime() { 247 return postTime; 248 } 249 250 /** @hide */ getScore()251 public int getScore() { 252 return score; 253 } 254 255 /** 256 * A unique instance key for this notification record. 257 */ getKey()258 public String getKey() { 259 return key; 260 } 261 262 /** 263 * A key that indicates the group with which this message ranks. 264 */ getGroupKey()265 public String getGroupKey() { 266 return groupKey; 267 } 268 269 /** 270 * @hide 271 */ getPackageContext(Context context)272 public Context getPackageContext(Context context) { 273 if (mContext == null) { 274 try { 275 ApplicationInfo ai = context.getPackageManager() 276 .getApplicationInfo(pkg, PackageManager.GET_UNINSTALLED_PACKAGES); 277 mContext = context.createApplicationContext(ai, 278 Context.CONTEXT_RESTRICTED); 279 } catch (PackageManager.NameNotFoundException e) { 280 mContext = null; 281 } 282 } 283 if (mContext == null) { 284 mContext = context; 285 } 286 return mContext; 287 } 288 } 289