• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 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 */
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 
55     /** @hide */
StatusBarNotification(String pkg, String opPkg, int id, String tag, int uid, int initialPid, Notification notification, UserHandle user, String overrideGroupKey, long postTime)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 
StatusBarNotification(String pkg, String opPkg, int id, String tag, int uid, int initialPid, int score, Notification notification, UserHandle user, long postTime)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 
StatusBarNotification(Parcel in)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 
key()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 
groupKey()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      */
isGroup()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      */
isAppGroup()156     public boolean isAppGroup() {
157         if (getNotification().getGroup() != null || getNotification().getSortKey() != null) {
158             return true;
159         }
160         return false;
161     }
162 
writeToParcel(Parcel out, int flags)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 
describeContents()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      */
cloneLight()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
clone()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
toString()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      */
isOngoing()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      */
isClearable()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      */
getUserId()252     public int getUserId() {
253         return this.user.getIdentifier();
254     }
255 
256     /** The package of the app that posted the notification. */
getPackageName()257     public String getPackageName() {
258         return pkg;
259     }
260 
261     /** The id supplied to {@link android.app.NotificationManager#notify(int,Notification)}. */
getId()262     public int getId() {
263         return id;
264     }
265 
266     /** The tag supplied to {@link android.app.NotificationManager#notify(int,Notification)},
267      * or null if no tag was specified. */
getTag()268     public String getTag() {
269         return tag;
270     }
271 
272     /** The notifying app's calling uid. @hide */
getUid()273     public int getUid() {
274         return uid;
275     }
276 
277     /** The package used for AppOps tracking. @hide */
getOpPkg()278     public String getOpPkg() {
279         return opPkg;
280     }
281 
282     /** @hide */
getInitialPid()283     public int getInitialPid() {
284         return initialPid;
285     }
286 
287     /** The {@link android.app.Notification} supplied to
288      * {@link android.app.NotificationManager#notify(int,Notification)}. */
getNotification()289     public Notification getNotification() {
290         return notification;
291     }
292 
293     /**
294      * The {@link android.os.UserHandle} for whom this notification is intended.
295      */
getUser()296     public UserHandle getUser() {
297         return user;
298     }
299 
300     /** The time (in {@link System#currentTimeMillis} time) the notification was posted,
301      * which may be different than {@link android.app.Notification#when}.
302      */
getPostTime()303     public long getPostTime() {
304         return postTime;
305     }
306 
307     /**
308      * A unique instance key for this notification record.
309      */
getKey()310     public String getKey() {
311         return key;
312     }
313 
314     /**
315      * A key that indicates the group with which this message ranks.
316      */
getGroupKey()317     public String getGroupKey() {
318         return groupKey;
319     }
320 
321     /**
322      * Sets the override group key.
323      */
setOverrideGroupKey(String overrideGroupKey)324     public void setOverrideGroupKey(String overrideGroupKey) {
325         this.overrideGroupKey = overrideGroupKey;
326         groupKey = groupKey();
327     }
328 
329     /**
330      * Returns the override group key.
331      */
getOverrideGroupKey()332     public String getOverrideGroupKey() {
333         return overrideGroupKey;
334     }
335 
336     /**
337      * @hide
338      */
getPackageContext(Context context)339     public Context getPackageContext(Context context) {
340         if (mContext == null) {
341             try {
342                 ApplicationInfo ai = context.getPackageManager()
343                         .getApplicationInfo(pkg, PackageManager.GET_UNINSTALLED_PACKAGES);
344                 mContext = context.createApplicationContext(ai,
345                         Context.CONTEXT_RESTRICTED);
346             } catch (PackageManager.NameNotFoundException e) {
347                 mContext = null;
348             }
349         }
350         if (mContext == null) {
351             mContext = context;
352         }
353         return mContext;
354     }
355 }
356