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;
53333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren
54333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren    // These members are used by NotificationSignalExtractors
55333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren    // to communicate with the ranking module.
56333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren    private float mContactAffinity;
57333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren    private boolean mRecentlyIntrusive;
58333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren
59333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren    // is this notification currently being intercepted by Zen Mode?
60333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren    private boolean mIntercept;
61333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren
6252b7a5a5973c05fe59b751b82ee357fdfc1c5ef7Christoph Studer    // The timestamp used for ranking.
6352b7a5a5973c05fe59b751b82ee357fdfc1c5ef7Christoph Studer    private long mRankingTimeMs;
6452b7a5a5973c05fe59b751b82ee357fdfc1c5ef7Christoph Studer
65a344656a010dc3c88aef39109f1ac459792e7607Chris Wren    // Is this record an update of an old record?
66a344656a010dc3c88aef39109f1ac459792e7607Chris Wren    public boolean isUpdate;
6754bbef435ed857fc68941672799fc8001c101119Chris Wren    private int mPackagePriority;
68a344656a010dc3c88aef39109f1ac459792e7607Chris Wren
691031c974855ff4117a6d7866e664295786840319Chris Wren    private int mAuthoritativeRank;
70cd4adf8b5ef9ac1f90fdddbb405404e173aedc87Christoph Studer    private String mGlobalSortKey;
713ad4e3a45bbe44129b14c4d391431e44f1e04f0cChris Wren    private int mPackageVisibility;
721031c974855ff4117a6d7866e664295786840319Chris Wren
731031c974855ff4117a6d7866e664295786840319Chris Wren    @VisibleForTesting
741031c974855ff4117a6d7866e664295786840319Chris Wren    public NotificationRecord(StatusBarNotification sbn, int score)
75333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren    {
76333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren        this.sbn = sbn;
77a344656a010dc3c88aef39109f1ac459792e7607Chris Wren        this.score = score;
78365e4c38d58d38bb61d1fdd870346f2f594825fdChristoph Studer        mOriginalFlags = sbn.getNotification().flags;
7952b7a5a5973c05fe59b751b82ee357fdfc1c5ef7Christoph Studer        mRankingTimeMs = calculateRankingTimeMs(0L);
80333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren    }
81333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren
82333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren    // copy any notes that the ranking system may have made before the update
83333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren    public void copyRankingInformation(NotificationRecord previous) {
84333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren        mContactAffinity = previous.mContactAffinity;
85333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren        mRecentlyIntrusive = previous.mRecentlyIntrusive;
8654bbef435ed857fc68941672799fc8001c101119Chris Wren        mPackagePriority = previous.mPackagePriority;
873ad4e3a45bbe44129b14c4d391431e44f1e04f0cChris Wren        mPackageVisibility = previous.mPackageVisibility;
88333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren        mIntercept = previous.mIntercept;
8952b7a5a5973c05fe59b751b82ee357fdfc1c5ef7Christoph Studer        mRankingTimeMs = calculateRankingTimeMs(previous.getRankingTimeMs());
90cd4adf8b5ef9ac1f90fdddbb405404e173aedc87Christoph Studer        // Don't copy mGlobalSortKey, recompute it.
91333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren    }
92333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren
93333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren    public Notification getNotification() { return sbn.getNotification(); }
94333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren    public int getFlags() { return sbn.getNotification().flags; }
95da4bd209cffad7e47a4bc6e9f02c4bfc333d3d8dChris Wren    public UserHandle getUser() { return sbn.getUser(); }
96333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren    public String getKey() { return sbn.getKey(); }
97da4bd209cffad7e47a4bc6e9f02c4bfc333d3d8dChris Wren    /** @deprecated Use {@link #getUser()} instead. */
98da4bd209cffad7e47a4bc6e9f02c4bfc333d3d8dChris Wren    public int getUserId() { return sbn.getUserId(); }
99333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren
100333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren    void dump(PrintWriter pw, String prefix, Context baseContext) {
101333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren        final Notification notification = sbn.getNotification();
102333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren        pw.println(prefix + this);
103333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren        pw.println(prefix + "  uid=" + sbn.getUid() + " userId=" + sbn.getUserId());
104333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren        pw.println(prefix + "  icon=0x" + Integer.toHexString(notification.icon)
105333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren                + " / " + idDebugString(baseContext, sbn.getPackageName(), notification.icon));
106333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren        pw.println(prefix + "  pri=" + notification.priority + " score=" + sbn.getScore());
107333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren        pw.println(prefix + "  key=" + sbn.getKey());
1081031c974855ff4117a6d7866e664295786840319Chris Wren        pw.println(prefix + "  groupKey=" + getGroupKey());
109333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren        pw.println(prefix + "  contentIntent=" + notification.contentIntent);
110333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren        pw.println(prefix + "  deleteIntent=" + notification.deleteIntent);
111333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren        pw.println(prefix + "  tickerText=" + notification.tickerText);
112333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren        pw.println(prefix + "  contentView=" + notification.contentView);
113333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren        pw.println(prefix + String.format("  defaults=0x%08x flags=0x%08x",
114333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren                notification.defaults, notification.flags));
115333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren        pw.println(prefix + "  sound=" + notification.sound);
116bfa5dc4c6c486bdabadb5ea2e356a7d348e3b975John Spurlock        pw.println(prefix + "  audioStreamType=" + notification.audioStreamType);
117bfa5dc4c6c486bdabadb5ea2e356a7d348e3b975John Spurlock        pw.println(prefix + "  audioAttributes=" + notification.audioAttributes);
118333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren        pw.println(prefix + String.format("  color=0x%08x", notification.color));
119333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren        pw.println(prefix + "  vibrate=" + Arrays.toString(notification.vibrate));
120333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren        pw.println(prefix + String.format("  led=0x%08x onMs=%d offMs=%d",
121333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren                notification.ledARGB, notification.ledOnMS, notification.ledOffMS));
122333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren        if (notification.actions != null && notification.actions.length > 0) {
123333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren            pw.println(prefix + "  actions={");
124333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren            final int N = notification.actions.length;
125333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren            for (int i=0; i<N; i++) {
126333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren                final Notification.Action action = notification.actions[i];
127333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren                pw.println(String.format("%s    [%d] \"%s\" -> %s",
128333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren                        prefix,
129333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren                        i,
130333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren                        action.title,
131333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren                        action.actionIntent.toString()
132333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren                        ));
133333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren            }
134333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren            pw.println(prefix + "  }");
135333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren        }
136333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren        if (notification.extras != null && notification.extras.size() > 0) {
137333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren            pw.println(prefix + "  extras={");
138333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren            for (String key : notification.extras.keySet()) {
139333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren                pw.print(prefix + "    " + key + "=");
140333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren                Object val = notification.extras.get(key);
141333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren                if (val == null) {
142333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren                    pw.println("null");
143333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren                } else {
144333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren                    pw.print(val.getClass().getSimpleName());
145333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren                    if (val instanceof CharSequence || val instanceof String) {
146333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren                        // redact contents from bugreports
147333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren                    } else if (val instanceof Bitmap) {
148333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren                        pw.print(String.format(" (%dx%d)",
149333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren                                ((Bitmap) val).getWidth(),
150333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren                                ((Bitmap) val).getHeight()));
151333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren                    } else if (val.getClass().isArray()) {
152333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren                        final int N = Array.getLength(val);
153333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren                        pw.println(" (" + N + ")");
154333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren                    } else {
155333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren                        pw.print(" (" + String.valueOf(val) + ")");
156333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren                    }
157333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren                    pw.println();
158333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren                }
159333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren            }
160333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren            pw.println(prefix + "  }");
161333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren        }
162333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren        pw.println(prefix + "  stats=" + stats.toString());
163333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren        pw.println(prefix + "  mContactAffinity=" + mContactAffinity);
164333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren        pw.println(prefix + "  mRecentlyIntrusive=" + mRecentlyIntrusive);
16554bbef435ed857fc68941672799fc8001c101119Chris Wren        pw.println(prefix + "  mPackagePriority=" + mPackagePriority);
1663ad4e3a45bbe44129b14c4d391431e44f1e04f0cChris Wren        pw.println(prefix + "  mPackageVisibility=" + mPackageVisibility);
167333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren        pw.println(prefix + "  mIntercept=" + mIntercept);
168cd4adf8b5ef9ac1f90fdddbb405404e173aedc87Christoph Studer        pw.println(prefix + "  mGlobalSortKey=" + mGlobalSortKey);
16952b7a5a5973c05fe59b751b82ee357fdfc1c5ef7Christoph Studer        pw.println(prefix + "  mRankingTimeMs=" + mRankingTimeMs);
170333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren    }
171333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren
172333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren
173333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren    static String idDebugString(Context baseContext, String packageName, int id) {
174333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren        Context c;
175333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren
176333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren        if (packageName != null) {
177333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren            try {
178333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren                c = baseContext.createPackageContext(packageName, 0);
179333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren            } catch (NameNotFoundException e) {
180333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren                c = baseContext;
181333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren            }
182333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren        } else {
183333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren            c = baseContext;
184333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren        }
185333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren
186333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren        Resources r = c.getResources();
187333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren        try {
188333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren            return r.getResourceName(id);
189333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren        } catch (Resources.NotFoundException e) {
190333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren            return "<name unknown>";
191333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren        }
192333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren    }
193333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren
194333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren    @Override
195333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren    public final String toString() {
196333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren        return String.format(
197333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren                "NotificationRecord(0x%08x: pkg=%s user=%s id=%d tag=%s score=%d key=%s: %s)",
198333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren                System.identityHashCode(this),
199333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren                this.sbn.getPackageName(), this.sbn.getUser(), this.sbn.getId(),
200333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren                this.sbn.getTag(), this.sbn.getScore(), this.sbn.getKey(),
201333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren                this.sbn.getNotification());
202333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren    }
203333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren
204333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren    public void setContactAffinity(float contactAffinity) {
205333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren        mContactAffinity = contactAffinity;
206333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren    }
207333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren
208333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren    public float getContactAffinity() {
209333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren        return mContactAffinity;
210333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren    }
211333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren
212333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren    public void setRecentlyIntusive(boolean recentlyIntrusive) {
213333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren        mRecentlyIntrusive = recentlyIntrusive;
214333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren    }
215333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren
216333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren    public boolean isRecentlyIntrusive() {
217333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren        return mRecentlyIntrusive;
218333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren    }
219333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren
22054bbef435ed857fc68941672799fc8001c101119Chris Wren    public void setPackagePriority(int packagePriority) {
2216ac5f8df62a4b6d87cf32797d2886efab8e28226John Spurlock        mPackagePriority = packagePriority;
22254bbef435ed857fc68941672799fc8001c101119Chris Wren    }
22354bbef435ed857fc68941672799fc8001c101119Chris Wren
22454bbef435ed857fc68941672799fc8001c101119Chris Wren    public int getPackagePriority() {
22554bbef435ed857fc68941672799fc8001c101119Chris Wren        return mPackagePriority;
22654bbef435ed857fc68941672799fc8001c101119Chris Wren    }
22754bbef435ed857fc68941672799fc8001c101119Chris Wren
2283ad4e3a45bbe44129b14c4d391431e44f1e04f0cChris Wren    public void setPackageVisibilityOverride(int packageVisibility) {
2293ad4e3a45bbe44129b14c4d391431e44f1e04f0cChris Wren        mPackageVisibility = packageVisibility;
2303ad4e3a45bbe44129b14c4d391431e44f1e04f0cChris Wren    }
2313ad4e3a45bbe44129b14c4d391431e44f1e04f0cChris Wren
2323ad4e3a45bbe44129b14c4d391431e44f1e04f0cChris Wren    public int getPackageVisibilityOverride() {
2333ad4e3a45bbe44129b14c4d391431e44f1e04f0cChris Wren        return mPackageVisibility;
2343ad4e3a45bbe44129b14c4d391431e44f1e04f0cChris Wren    }
2353ad4e3a45bbe44129b14c4d391431e44f1e04f0cChris Wren
236333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren    public boolean setIntercepted(boolean intercept) {
237333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren        mIntercept = intercept;
238333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren        return mIntercept;
239333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren    }
240333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren
241333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren    public boolean isIntercepted() {
242333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren        return mIntercept;
243333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren    }
244333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren
245312d1d01def474e39e4dabbf4aef0b8adaa7caedJohn Spurlock    public boolean isCategory(String category) {
246bfa5dc4c6c486bdabadb5ea2e356a7d348e3b975John Spurlock        return Objects.equals(getNotification().category, category);
247bfa5dc4c6c486bdabadb5ea2e356a7d348e3b975John Spurlock    }
248bfa5dc4c6c486bdabadb5ea2e356a7d348e3b975John Spurlock
249bfa5dc4c6c486bdabadb5ea2e356a7d348e3b975John Spurlock    public boolean isAudioStream(int stream) {
250bfa5dc4c6c486bdabadb5ea2e356a7d348e3b975John Spurlock        return getNotification().audioStreamType == stream;
251bfa5dc4c6c486bdabadb5ea2e356a7d348e3b975John Spurlock    }
252bfa5dc4c6c486bdabadb5ea2e356a7d348e3b975John Spurlock
253bfa5dc4c6c486bdabadb5ea2e356a7d348e3b975John Spurlock    public boolean isAudioAttributesUsage(int usage) {
254bfa5dc4c6c486bdabadb5ea2e356a7d348e3b975John Spurlock        final AudioAttributes attributes = getNotification().audioAttributes;
255bfa5dc4c6c486bdabadb5ea2e356a7d348e3b975John Spurlock        return attributes != null && attributes.getUsage() == usage;
256312d1d01def474e39e4dabbf4aef0b8adaa7caedJohn Spurlock    }
257312d1d01def474e39e4dabbf4aef0b8adaa7caedJohn Spurlock
25852b7a5a5973c05fe59b751b82ee357fdfc1c5ef7Christoph Studer    /**
25952b7a5a5973c05fe59b751b82ee357fdfc1c5ef7Christoph Studer     * Returns the timestamp to use for time-based sorting in the ranker.
26052b7a5a5973c05fe59b751b82ee357fdfc1c5ef7Christoph Studer     */
26152b7a5a5973c05fe59b751b82ee357fdfc1c5ef7Christoph Studer    public long getRankingTimeMs() {
26252b7a5a5973c05fe59b751b82ee357fdfc1c5ef7Christoph Studer        return mRankingTimeMs;
26352b7a5a5973c05fe59b751b82ee357fdfc1c5ef7Christoph Studer    }
26452b7a5a5973c05fe59b751b82ee357fdfc1c5ef7Christoph Studer
26552b7a5a5973c05fe59b751b82ee357fdfc1c5ef7Christoph Studer    /**
26652b7a5a5973c05fe59b751b82ee357fdfc1c5ef7Christoph Studer     * @param previousRankingTimeMs for updated notifications, {@link #getRankingTimeMs()}
26752b7a5a5973c05fe59b751b82ee357fdfc1c5ef7Christoph Studer     *     of the previous notification record, 0 otherwise
26852b7a5a5973c05fe59b751b82ee357fdfc1c5ef7Christoph Studer     */
26952b7a5a5973c05fe59b751b82ee357fdfc1c5ef7Christoph Studer    private long calculateRankingTimeMs(long previousRankingTimeMs) {
27052b7a5a5973c05fe59b751b82ee357fdfc1c5ef7Christoph Studer        Notification n = getNotification();
27152b7a5a5973c05fe59b751b82ee357fdfc1c5ef7Christoph Studer        // Take developer provided 'when', unless it's in the future.
27252b7a5a5973c05fe59b751b82ee357fdfc1c5ef7Christoph Studer        if (n.when != 0 && n.when <= sbn.getPostTime()) {
27352b7a5a5973c05fe59b751b82ee357fdfc1c5ef7Christoph Studer            return n.when;
27452b7a5a5973c05fe59b751b82ee357fdfc1c5ef7Christoph Studer        }
27552b7a5a5973c05fe59b751b82ee357fdfc1c5ef7Christoph Studer        // If we've ranked a previous instance with a timestamp, inherit it. This case is
27652b7a5a5973c05fe59b751b82ee357fdfc1c5ef7Christoph Studer        // important in order to have ranking stability for updating notifications.
27752b7a5a5973c05fe59b751b82ee357fdfc1c5ef7Christoph Studer        if (previousRankingTimeMs > 0) {
27852b7a5a5973c05fe59b751b82ee357fdfc1c5ef7Christoph Studer            return previousRankingTimeMs;
27952b7a5a5973c05fe59b751b82ee357fdfc1c5ef7Christoph Studer        }
28052b7a5a5973c05fe59b751b82ee357fdfc1c5ef7Christoph Studer        return sbn.getPostTime();
28152b7a5a5973c05fe59b751b82ee357fdfc1c5ef7Christoph Studer    }
2821031c974855ff4117a6d7866e664295786840319Chris Wren
283cd4adf8b5ef9ac1f90fdddbb405404e173aedc87Christoph Studer    public void setGlobalSortKey(String globalSortKey) {
284cd4adf8b5ef9ac1f90fdddbb405404e173aedc87Christoph Studer        mGlobalSortKey = globalSortKey;
2851031c974855ff4117a6d7866e664295786840319Chris Wren    }
2861031c974855ff4117a6d7866e664295786840319Chris Wren
287cd4adf8b5ef9ac1f90fdddbb405404e173aedc87Christoph Studer    public String getGlobalSortKey() {
288cd4adf8b5ef9ac1f90fdddbb405404e173aedc87Christoph Studer        return mGlobalSortKey;
2891031c974855ff4117a6d7866e664295786840319Chris Wren    }
2901031c974855ff4117a6d7866e664295786840319Chris Wren
2911031c974855ff4117a6d7866e664295786840319Chris Wren    public void setAuthoritativeRank(int authoritativeRank) {
2921031c974855ff4117a6d7866e664295786840319Chris Wren        mAuthoritativeRank = authoritativeRank;
2931031c974855ff4117a6d7866e664295786840319Chris Wren    }
2941031c974855ff4117a6d7866e664295786840319Chris Wren
2951031c974855ff4117a6d7866e664295786840319Chris Wren    public int getAuthoritativeRank() {
2961031c974855ff4117a6d7866e664295786840319Chris Wren        return mAuthoritativeRank;
2971031c974855ff4117a6d7866e664295786840319Chris Wren    }
2981031c974855ff4117a6d7866e664295786840319Chris Wren
2991031c974855ff4117a6d7866e664295786840319Chris Wren    public String getGroupKey() {
3001031c974855ff4117a6d7866e664295786840319Chris Wren        return sbn.getGroupKey();
3011031c974855ff4117a6d7866e664295786840319Chris Wren    }
302333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren}
303