NotificationRecord.java revision f47e51ec605fccf7fed9e50d1adc98fbd4e8b340
1333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren/*
2333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren * Copyright (C) 2014 The Android Open Source Project
3333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren *
4333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren * Licensed under the Apache License, Version 2.0 (the "License");
5333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren * you may not use this file except in compliance with the License.
6333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren * You may obtain a copy of the License at
7333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren *
8333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren *      http://www.apache.org/licenses/LICENSE-2.0
9333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren *
10333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren * Unless required by applicable law or agreed to in writing, software
11333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren * distributed under the License is distributed on an "AS IS" BASIS,
12333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren * See the License for the specific language governing permissions and
14333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren * limitations under the License.
15333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren */
16333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wrenpackage com.android.server.notification;
17333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren
18333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wrenimport android.app.Notification;
19333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wrenimport android.content.Context;
20333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wrenimport android.content.pm.PackageManager.NameNotFoundException;
21333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wrenimport android.content.res.Resources;
22333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wrenimport android.graphics.Bitmap;
23bfa5dc4c6c486bdabadb5ea2e356a7d348e3b975John Spurlockimport android.media.AudioAttributes;
24da4bd209cffad7e47a4bc6e9f02c4bfc333d3d8dChris Wrenimport android.os.UserHandle;
25333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wrenimport android.service.notification.StatusBarNotification;
26bfa5dc4c6c486bdabadb5ea2e356a7d348e3b975John Spurlock
271031c974855ff4117a6d7866e664295786840319Chris Wrenimport com.android.internal.annotations.VisibleForTesting;
28333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren
29333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wrenimport java.io.PrintWriter;
30333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wrenimport java.lang.reflect.Array;
31333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wrenimport java.util.Arrays;
32312d1d01def474e39e4dabbf4aef0b8adaa7caedJohn Spurlockimport java.util.Objects;
33333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren
34333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren/**
35333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren * Holds data about notifications that should not be shared with the
36333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren * {@link android.service.notification.NotificationListenerService}s.
37333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren *
38333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren * <p>These objects should not be mutated unless the code is synchronized
39333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren * on {@link NotificationManagerService#mNotificationList}, and any
40333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren * modification should be followed by a sorting of that list.</p>
41333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren *
42333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren * <p>Is sortable by {@link NotificationComparator}.</p>
43333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren *
44333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren * {@hide}
45333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren */
46333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wrenpublic final class NotificationRecord {
47333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren    final StatusBarNotification sbn;
48365e4c38d58d38bb61d1fdd870346f2f594825fdChristoph Studer    final int mOriginalFlags;
49365e4c38d58d38bb61d1fdd870346f2f594825fdChristoph Studer
50333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren    NotificationUsageStats.SingleNotificationStats stats;
51333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren    boolean isCanceled;
52a344656a010dc3c88aef39109f1ac459792e7607Chris Wren    int score;
53f47e51ec605fccf7fed9e50d1adc98fbd4e8b340Amith Yamasani    /** Whether the notification was seen by the user via one of the notification listeners. */
54f47e51ec605fccf7fed9e50d1adc98fbd4e8b340Amith Yamasani    boolean mIsSeen;
55333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren
56333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren    // These members are used by NotificationSignalExtractors
57333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren    // to communicate with the ranking module.
58333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren    private float mContactAffinity;
59333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren    private boolean mRecentlyIntrusive;
60333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren
61333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren    // is this notification currently being intercepted by Zen Mode?
62333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren    private boolean mIntercept;
63333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren
6452b7a5a5973c05fe59b751b82ee357fdfc1c5ef7Christoph Studer    // The timestamp used for ranking.
6552b7a5a5973c05fe59b751b82ee357fdfc1c5ef7Christoph Studer    private long mRankingTimeMs;
6652b7a5a5973c05fe59b751b82ee357fdfc1c5ef7Christoph Studer
67640e387ce4e8aa97a8139fda54a5f5468e2ff18bChris Wren    // The first post time, stable across updates.
68640e387ce4e8aa97a8139fda54a5f5468e2ff18bChris Wren    private long mCreationTimeMs;
69640e387ce4e8aa97a8139fda54a5f5468e2ff18bChris Wren
70a344656a010dc3c88aef39109f1ac459792e7607Chris Wren    // Is this record an update of an old record?
71a344656a010dc3c88aef39109f1ac459792e7607Chris Wren    public boolean isUpdate;
7254bbef435ed857fc68941672799fc8001c101119Chris Wren    private int mPackagePriority;
73a344656a010dc3c88aef39109f1ac459792e7607Chris Wren
741031c974855ff4117a6d7866e664295786840319Chris Wren    private int mAuthoritativeRank;
75cd4adf8b5ef9ac1f90fdddbb405404e173aedc87Christoph Studer    private String mGlobalSortKey;
763ad4e3a45bbe44129b14c4d391431e44f1e04f0cChris Wren    private int mPackageVisibility;
771031c974855ff4117a6d7866e664295786840319Chris Wren
781031c974855ff4117a6d7866e664295786840319Chris Wren    @VisibleForTesting
791031c974855ff4117a6d7866e664295786840319Chris Wren    public NotificationRecord(StatusBarNotification sbn, int score)
80333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren    {
81333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren        this.sbn = sbn;
82a344656a010dc3c88aef39109f1ac459792e7607Chris Wren        this.score = score;
83365e4c38d58d38bb61d1fdd870346f2f594825fdChristoph Studer        mOriginalFlags = sbn.getNotification().flags;
8452b7a5a5973c05fe59b751b82ee357fdfc1c5ef7Christoph Studer        mRankingTimeMs = calculateRankingTimeMs(0L);
85640e387ce4e8aa97a8139fda54a5f5468e2ff18bChris Wren        mCreationTimeMs = sbn.getPostTime();
86333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren    }
87333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren
88333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren    // copy any notes that the ranking system may have made before the update
89333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren    public void copyRankingInformation(NotificationRecord previous) {
90333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren        mContactAffinity = previous.mContactAffinity;
91333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren        mRecentlyIntrusive = previous.mRecentlyIntrusive;
9254bbef435ed857fc68941672799fc8001c101119Chris Wren        mPackagePriority = previous.mPackagePriority;
933ad4e3a45bbe44129b14c4d391431e44f1e04f0cChris Wren        mPackageVisibility = previous.mPackageVisibility;
94333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren        mIntercept = previous.mIntercept;
9552b7a5a5973c05fe59b751b82ee357fdfc1c5ef7Christoph Studer        mRankingTimeMs = calculateRankingTimeMs(previous.getRankingTimeMs());
96640e387ce4e8aa97a8139fda54a5f5468e2ff18bChris Wren        mCreationTimeMs = previous.mCreationTimeMs;
97cd4adf8b5ef9ac1f90fdddbb405404e173aedc87Christoph Studer        // Don't copy mGlobalSortKey, recompute it.
98333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren    }
99333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren
100333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren    public Notification getNotification() { return sbn.getNotification(); }
101333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren    public int getFlags() { return sbn.getNotification().flags; }
102da4bd209cffad7e47a4bc6e9f02c4bfc333d3d8dChris Wren    public UserHandle getUser() { return sbn.getUser(); }
103333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren    public String getKey() { return sbn.getKey(); }
104da4bd209cffad7e47a4bc6e9f02c4bfc333d3d8dChris Wren    /** @deprecated Use {@link #getUser()} instead. */
105da4bd209cffad7e47a4bc6e9f02c4bfc333d3d8dChris Wren    public int getUserId() { return sbn.getUserId(); }
106333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren
107333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren    void dump(PrintWriter pw, String prefix, Context baseContext) {
108333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren        final Notification notification = sbn.getNotification();
109333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren        pw.println(prefix + this);
110333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren        pw.println(prefix + "  uid=" + sbn.getUid() + " userId=" + sbn.getUserId());
111333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren        pw.println(prefix + "  icon=0x" + Integer.toHexString(notification.icon)
112333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren                + " / " + idDebugString(baseContext, sbn.getPackageName(), notification.icon));
113333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren        pw.println(prefix + "  pri=" + notification.priority + " score=" + sbn.getScore());
114333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren        pw.println(prefix + "  key=" + sbn.getKey());
1151031c974855ff4117a6d7866e664295786840319Chris Wren        pw.println(prefix + "  groupKey=" + getGroupKey());
116333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren        pw.println(prefix + "  contentIntent=" + notification.contentIntent);
117333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren        pw.println(prefix + "  deleteIntent=" + notification.deleteIntent);
118333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren        pw.println(prefix + "  tickerText=" + notification.tickerText);
119333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren        pw.println(prefix + "  contentView=" + notification.contentView);
120333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren        pw.println(prefix + String.format("  defaults=0x%08x flags=0x%08x",
121333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren                notification.defaults, notification.flags));
122333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren        pw.println(prefix + "  sound=" + notification.sound);
123bfa5dc4c6c486bdabadb5ea2e356a7d348e3b975John Spurlock        pw.println(prefix + "  audioStreamType=" + notification.audioStreamType);
124bfa5dc4c6c486bdabadb5ea2e356a7d348e3b975John Spurlock        pw.println(prefix + "  audioAttributes=" + notification.audioAttributes);
125333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren        pw.println(prefix + String.format("  color=0x%08x", notification.color));
126333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren        pw.println(prefix + "  vibrate=" + Arrays.toString(notification.vibrate));
127333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren        pw.println(prefix + String.format("  led=0x%08x onMs=%d offMs=%d",
128333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren                notification.ledARGB, notification.ledOnMS, notification.ledOffMS));
129333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren        if (notification.actions != null && notification.actions.length > 0) {
130333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren            pw.println(prefix + "  actions={");
131333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren            final int N = notification.actions.length;
132333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren            for (int i=0; i<N; i++) {
133333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren                final Notification.Action action = notification.actions[i];
134333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren                pw.println(String.format("%s    [%d] \"%s\" -> %s",
135333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren                        prefix,
136333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren                        i,
137333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren                        action.title,
138333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren                        action.actionIntent.toString()
139333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren                        ));
140333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren            }
141333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren            pw.println(prefix + "  }");
142333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren        }
143333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren        if (notification.extras != null && notification.extras.size() > 0) {
144333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren            pw.println(prefix + "  extras={");
145333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren            for (String key : notification.extras.keySet()) {
146333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren                pw.print(prefix + "    " + key + "=");
147333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren                Object val = notification.extras.get(key);
148333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren                if (val == null) {
149333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren                    pw.println("null");
150333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren                } else {
151333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren                    pw.print(val.getClass().getSimpleName());
152333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren                    if (val instanceof CharSequence || val instanceof String) {
153333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren                        // redact contents from bugreports
154333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren                    } else if (val instanceof Bitmap) {
155333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren                        pw.print(String.format(" (%dx%d)",
156333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren                                ((Bitmap) val).getWidth(),
157333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren                                ((Bitmap) val).getHeight()));
158333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren                    } else if (val.getClass().isArray()) {
159333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren                        final int N = Array.getLength(val);
160333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren                        pw.println(" (" + N + ")");
161333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren                    } else {
162333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren                        pw.print(" (" + String.valueOf(val) + ")");
163333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren                    }
164333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren                    pw.println();
165333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren                }
166333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren            }
167333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren            pw.println(prefix + "  }");
168333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren        }
169333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren        pw.println(prefix + "  stats=" + stats.toString());
170333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren        pw.println(prefix + "  mContactAffinity=" + mContactAffinity);
171333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren        pw.println(prefix + "  mRecentlyIntrusive=" + mRecentlyIntrusive);
17254bbef435ed857fc68941672799fc8001c101119Chris Wren        pw.println(prefix + "  mPackagePriority=" + mPackagePriority);
1733ad4e3a45bbe44129b14c4d391431e44f1e04f0cChris Wren        pw.println(prefix + "  mPackageVisibility=" + mPackageVisibility);
174333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren        pw.println(prefix + "  mIntercept=" + mIntercept);
175cd4adf8b5ef9ac1f90fdddbb405404e173aedc87Christoph Studer        pw.println(prefix + "  mGlobalSortKey=" + mGlobalSortKey);
17652b7a5a5973c05fe59b751b82ee357fdfc1c5ef7Christoph Studer        pw.println(prefix + "  mRankingTimeMs=" + mRankingTimeMs);
177640e387ce4e8aa97a8139fda54a5f5468e2ff18bChris Wren        pw.println(prefix + "  mCreationTimeMs=" + mCreationTimeMs);
178333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren    }
179333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren
180333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren
181333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren    static String idDebugString(Context baseContext, String packageName, int id) {
182333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren        Context c;
183333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren
184333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren        if (packageName != null) {
185333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren            try {
186333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren                c = baseContext.createPackageContext(packageName, 0);
187333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren            } catch (NameNotFoundException e) {
188333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren                c = baseContext;
189333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren            }
190333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren        } else {
191333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren            c = baseContext;
192333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren        }
193333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren
194333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren        Resources r = c.getResources();
195333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren        try {
196333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren            return r.getResourceName(id);
197333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren        } catch (Resources.NotFoundException e) {
198333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren            return "<name unknown>";
199333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren        }
200333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren    }
201333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren
202333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren    @Override
203333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren    public final String toString() {
204333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren        return String.format(
205333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren                "NotificationRecord(0x%08x: pkg=%s user=%s id=%d tag=%s score=%d key=%s: %s)",
206333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren                System.identityHashCode(this),
207333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren                this.sbn.getPackageName(), this.sbn.getUser(), this.sbn.getId(),
208333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren                this.sbn.getTag(), this.sbn.getScore(), this.sbn.getKey(),
209333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren                this.sbn.getNotification());
210333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren    }
211333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren
212333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren    public void setContactAffinity(float contactAffinity) {
213333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren        mContactAffinity = contactAffinity;
214333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren    }
215333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren
216333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren    public float getContactAffinity() {
217333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren        return mContactAffinity;
218333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren    }
219333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren
2201d881a1e986c706963c254fbe2b6296a1cd10b75John Spurlock    public void setRecentlyIntrusive(boolean recentlyIntrusive) {
221333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren        mRecentlyIntrusive = recentlyIntrusive;
222333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren    }
223333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren
224333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren    public boolean isRecentlyIntrusive() {
225333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren        return mRecentlyIntrusive;
226333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren    }
227333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren
22854bbef435ed857fc68941672799fc8001c101119Chris Wren    public void setPackagePriority(int packagePriority) {
2296ac5f8df62a4b6d87cf32797d2886efab8e28226John Spurlock        mPackagePriority = packagePriority;
23054bbef435ed857fc68941672799fc8001c101119Chris Wren    }
23154bbef435ed857fc68941672799fc8001c101119Chris Wren
23254bbef435ed857fc68941672799fc8001c101119Chris Wren    public int getPackagePriority() {
23354bbef435ed857fc68941672799fc8001c101119Chris Wren        return mPackagePriority;
23454bbef435ed857fc68941672799fc8001c101119Chris Wren    }
23554bbef435ed857fc68941672799fc8001c101119Chris Wren
2363ad4e3a45bbe44129b14c4d391431e44f1e04f0cChris Wren    public void setPackageVisibilityOverride(int packageVisibility) {
2373ad4e3a45bbe44129b14c4d391431e44f1e04f0cChris Wren        mPackageVisibility = packageVisibility;
2383ad4e3a45bbe44129b14c4d391431e44f1e04f0cChris Wren    }
2393ad4e3a45bbe44129b14c4d391431e44f1e04f0cChris Wren
2403ad4e3a45bbe44129b14c4d391431e44f1e04f0cChris Wren    public int getPackageVisibilityOverride() {
2413ad4e3a45bbe44129b14c4d391431e44f1e04f0cChris Wren        return mPackageVisibility;
2423ad4e3a45bbe44129b14c4d391431e44f1e04f0cChris Wren    }
2433ad4e3a45bbe44129b14c4d391431e44f1e04f0cChris Wren
244333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren    public boolean setIntercepted(boolean intercept) {
245333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren        mIntercept = intercept;
246333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren        return mIntercept;
247333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren    }
248333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren
249333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren    public boolean isIntercepted() {
250333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren        return mIntercept;
251333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren    }
252333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren
253312d1d01def474e39e4dabbf4aef0b8adaa7caedJohn Spurlock    public boolean isCategory(String category) {
254bfa5dc4c6c486bdabadb5ea2e356a7d348e3b975John Spurlock        return Objects.equals(getNotification().category, category);
255bfa5dc4c6c486bdabadb5ea2e356a7d348e3b975John Spurlock    }
256bfa5dc4c6c486bdabadb5ea2e356a7d348e3b975John Spurlock
257bfa5dc4c6c486bdabadb5ea2e356a7d348e3b975John Spurlock    public boolean isAudioStream(int stream) {
258bfa5dc4c6c486bdabadb5ea2e356a7d348e3b975John Spurlock        return getNotification().audioStreamType == stream;
259bfa5dc4c6c486bdabadb5ea2e356a7d348e3b975John Spurlock    }
260bfa5dc4c6c486bdabadb5ea2e356a7d348e3b975John Spurlock
261bfa5dc4c6c486bdabadb5ea2e356a7d348e3b975John Spurlock    public boolean isAudioAttributesUsage(int usage) {
262bfa5dc4c6c486bdabadb5ea2e356a7d348e3b975John Spurlock        final AudioAttributes attributes = getNotification().audioAttributes;
263bfa5dc4c6c486bdabadb5ea2e356a7d348e3b975John Spurlock        return attributes != null && attributes.getUsage() == usage;
264312d1d01def474e39e4dabbf4aef0b8adaa7caedJohn Spurlock    }
265312d1d01def474e39e4dabbf4aef0b8adaa7caedJohn Spurlock
26652b7a5a5973c05fe59b751b82ee357fdfc1c5ef7Christoph Studer    /**
26752b7a5a5973c05fe59b751b82ee357fdfc1c5ef7Christoph Studer     * Returns the timestamp to use for time-based sorting in the ranker.
26852b7a5a5973c05fe59b751b82ee357fdfc1c5ef7Christoph Studer     */
26952b7a5a5973c05fe59b751b82ee357fdfc1c5ef7Christoph Studer    public long getRankingTimeMs() {
27052b7a5a5973c05fe59b751b82ee357fdfc1c5ef7Christoph Studer        return mRankingTimeMs;
27152b7a5a5973c05fe59b751b82ee357fdfc1c5ef7Christoph Studer    }
27252b7a5a5973c05fe59b751b82ee357fdfc1c5ef7Christoph Studer
27352b7a5a5973c05fe59b751b82ee357fdfc1c5ef7Christoph Studer    /**
274640e387ce4e8aa97a8139fda54a5f5468e2ff18bChris Wren     * Returns the timestamp of the first post, ignoring updates.
275640e387ce4e8aa97a8139fda54a5f5468e2ff18bChris Wren     */
276640e387ce4e8aa97a8139fda54a5f5468e2ff18bChris Wren    public long getCreationTimeMs() {
277640e387ce4e8aa97a8139fda54a5f5468e2ff18bChris Wren        return mCreationTimeMs;
278640e387ce4e8aa97a8139fda54a5f5468e2ff18bChris Wren    }
279640e387ce4e8aa97a8139fda54a5f5468e2ff18bChris Wren
280640e387ce4e8aa97a8139fda54a5f5468e2ff18bChris Wren    /**
28152b7a5a5973c05fe59b751b82ee357fdfc1c5ef7Christoph Studer     * @param previousRankingTimeMs for updated notifications, {@link #getRankingTimeMs()}
28252b7a5a5973c05fe59b751b82ee357fdfc1c5ef7Christoph Studer     *     of the previous notification record, 0 otherwise
28352b7a5a5973c05fe59b751b82ee357fdfc1c5ef7Christoph Studer     */
28452b7a5a5973c05fe59b751b82ee357fdfc1c5ef7Christoph Studer    private long calculateRankingTimeMs(long previousRankingTimeMs) {
28552b7a5a5973c05fe59b751b82ee357fdfc1c5ef7Christoph Studer        Notification n = getNotification();
28652b7a5a5973c05fe59b751b82ee357fdfc1c5ef7Christoph Studer        // Take developer provided 'when', unless it's in the future.
28752b7a5a5973c05fe59b751b82ee357fdfc1c5ef7Christoph Studer        if (n.when != 0 && n.when <= sbn.getPostTime()) {
28852b7a5a5973c05fe59b751b82ee357fdfc1c5ef7Christoph Studer            return n.when;
28952b7a5a5973c05fe59b751b82ee357fdfc1c5ef7Christoph Studer        }
29052b7a5a5973c05fe59b751b82ee357fdfc1c5ef7Christoph Studer        // If we've ranked a previous instance with a timestamp, inherit it. This case is
29152b7a5a5973c05fe59b751b82ee357fdfc1c5ef7Christoph Studer        // important in order to have ranking stability for updating notifications.
29252b7a5a5973c05fe59b751b82ee357fdfc1c5ef7Christoph Studer        if (previousRankingTimeMs > 0) {
29352b7a5a5973c05fe59b751b82ee357fdfc1c5ef7Christoph Studer            return previousRankingTimeMs;
29452b7a5a5973c05fe59b751b82ee357fdfc1c5ef7Christoph Studer        }
29552b7a5a5973c05fe59b751b82ee357fdfc1c5ef7Christoph Studer        return sbn.getPostTime();
29652b7a5a5973c05fe59b751b82ee357fdfc1c5ef7Christoph Studer    }
2971031c974855ff4117a6d7866e664295786840319Chris Wren
298cd4adf8b5ef9ac1f90fdddbb405404e173aedc87Christoph Studer    public void setGlobalSortKey(String globalSortKey) {
299cd4adf8b5ef9ac1f90fdddbb405404e173aedc87Christoph Studer        mGlobalSortKey = globalSortKey;
3001031c974855ff4117a6d7866e664295786840319Chris Wren    }
3011031c974855ff4117a6d7866e664295786840319Chris Wren
302cd4adf8b5ef9ac1f90fdddbb405404e173aedc87Christoph Studer    public String getGlobalSortKey() {
303cd4adf8b5ef9ac1f90fdddbb405404e173aedc87Christoph Studer        return mGlobalSortKey;
3041031c974855ff4117a6d7866e664295786840319Chris Wren    }
3051031c974855ff4117a6d7866e664295786840319Chris Wren
306f47e51ec605fccf7fed9e50d1adc98fbd4e8b340Amith Yamasani    /** Check if any of the listeners have marked this notification as seen by the user. */
307f47e51ec605fccf7fed9e50d1adc98fbd4e8b340Amith Yamasani    public boolean isSeen() {
308f47e51ec605fccf7fed9e50d1adc98fbd4e8b340Amith Yamasani        return mIsSeen;
309f47e51ec605fccf7fed9e50d1adc98fbd4e8b340Amith Yamasani    }
310f47e51ec605fccf7fed9e50d1adc98fbd4e8b340Amith Yamasani
311f47e51ec605fccf7fed9e50d1adc98fbd4e8b340Amith Yamasani    /** Mark the notification as seen by the user. */
312f47e51ec605fccf7fed9e50d1adc98fbd4e8b340Amith Yamasani    public void setSeen() {
313f47e51ec605fccf7fed9e50d1adc98fbd4e8b340Amith Yamasani        mIsSeen = true;
314f47e51ec605fccf7fed9e50d1adc98fbd4e8b340Amith Yamasani    }
315f47e51ec605fccf7fed9e50d1adc98fbd4e8b340Amith Yamasani
3161031c974855ff4117a6d7866e664295786840319Chris Wren    public void setAuthoritativeRank(int authoritativeRank) {
3171031c974855ff4117a6d7866e664295786840319Chris Wren        mAuthoritativeRank = authoritativeRank;
3181031c974855ff4117a6d7866e664295786840319Chris Wren    }
3191031c974855ff4117a6d7866e664295786840319Chris Wren
3201031c974855ff4117a6d7866e664295786840319Chris Wren    public int getAuthoritativeRank() {
3211031c974855ff4117a6d7866e664295786840319Chris Wren        return mAuthoritativeRank;
3221031c974855ff4117a6d7866e664295786840319Chris Wren    }
3231031c974855ff4117a6d7866e664295786840319Chris Wren
3241031c974855ff4117a6d7866e664295786840319Chris Wren    public String getGroupKey() {
3251031c974855ff4117a6d7866e664295786840319Chris Wren        return sbn.getGroupKey();
3261031c974855ff4117a6d7866e664295786840319Chris Wren    }
327333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren}
328