StatusBarNotification.java revision 68079d54f3690885df9c5bbb691090633f3ef541
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 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 */
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    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
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
94    private String key() {
95        return user.getIdentifier() + "|" + pkg + "|" + id + "|" + tag + "|" + uid;
96    }
97
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
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
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     */
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
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
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     */
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     */
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     */
195    public int getUserId() {
196        return this.user.getIdentifier();
197    }
198
199    /** The package of the app that posted the notification. */
200    public String getPackageName() {
201        return pkg;
202    }
203
204    /** The id supplied to {@link android.app.NotificationManager#notify(int,Notification)}. */
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. */
211    public String getTag() {
212        return tag;
213    }
214
215    /** The notifying app's calling uid. @hide */
216    public int getUid() {
217        return uid;
218    }
219
220    /** The package used for AppOps tracking. @hide */
221    public String getOpPkg() {
222        return opPkg;
223    }
224
225    /** @hide */
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)}. */
232    public Notification getNotification() {
233        return notification;
234    }
235
236    /**
237     * The {@link android.os.UserHandle} for whom this notification is intended.
238     */
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     */
246    public long getPostTime() {
247        return postTime;
248    }
249
250    /** @hide */
251    public int getScore() {
252        return score;
253    }
254
255    /**
256     * A unique instance key for this notification record.
257     */
258    public String getKey() {
259        return key;
260    }
261
262    /**
263     * A key that indicates the group with which this message ranks.
264     */
265    public String getGroupKey() {
266        return groupKey;
267    }
268
269    /**
270     * @hide
271     */
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