Home | History | Annotate | Download | only in notification
      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 */
     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