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; 23d63f9321e62064660d426efd5abbd885c4a24652Dan Sandlerimport android.graphics.drawable.Icon; 24bfa5dc4c6c486bdabadb5ea2e356a7d348e3b975John Spurlockimport android.media.AudioAttributes; 25da4bd209cffad7e47a4bc6e9f02c4bfc333d3d8dChris Wrenimport android.os.UserHandle; 26333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wrenimport android.service.notification.StatusBarNotification; 27bfa5dc4c6c486bdabadb5ea2e356a7d348e3b975John Spurlock 281031c974855ff4117a6d7866e664295786840319Chris Wrenimport com.android.internal.annotations.VisibleForTesting; 296650e5767b3d69268af7238cfa65dde6a9f2e0a3Chris Wrenimport com.android.server.EventLogTags; 30333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren 31333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wrenimport java.io.PrintWriter; 32333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wrenimport java.lang.reflect.Array; 33333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wrenimport java.util.Arrays; 34312d1d01def474e39e4dabbf4aef0b8adaa7caedJohn Spurlockimport java.util.Objects; 35333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren 36333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren/** 37333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren * Holds data about notifications that should not be shared with the 38333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren * {@link android.service.notification.NotificationListenerService}s. 39333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren * 40333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren * <p>These objects should not be mutated unless the code is synchronized 41333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren * on {@link NotificationManagerService#mNotificationList}, and any 42333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren * modification should be followed by a sorting of that list.</p> 43333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren * 44333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren * <p>Is sortable by {@link NotificationComparator}.</p> 45333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren * 46333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren * {@hide} 47333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren */ 48333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wrenpublic final class NotificationRecord { 49333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren final StatusBarNotification sbn; 50365e4c38d58d38bb61d1fdd870346f2f594825fdChristoph Studer final int mOriginalFlags; 51365e4c38d58d38bb61d1fdd870346f2f594825fdChristoph Studer 52333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren NotificationUsageStats.SingleNotificationStats stats; 53333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren boolean isCanceled; 54a344656a010dc3c88aef39109f1ac459792e7607Chris Wren int score; 55f47e51ec605fccf7fed9e50d1adc98fbd4e8b340Amith Yamasani /** Whether the notification was seen by the user via one of the notification listeners. */ 56f47e51ec605fccf7fed9e50d1adc98fbd4e8b340Amith Yamasani boolean mIsSeen; 57333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren 58333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren // These members are used by NotificationSignalExtractors 59333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren // to communicate with the ranking module. 60333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren private float mContactAffinity; 61333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren private boolean mRecentlyIntrusive; 62333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren 63333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren // is this notification currently being intercepted by Zen Mode? 64333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren private boolean mIntercept; 65333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren 6652b7a5a5973c05fe59b751b82ee357fdfc1c5ef7Christoph Studer // The timestamp used for ranking. 6752b7a5a5973c05fe59b751b82ee357fdfc1c5ef7Christoph Studer private long mRankingTimeMs; 6852b7a5a5973c05fe59b751b82ee357fdfc1c5ef7Christoph Studer 69640e387ce4e8aa97a8139fda54a5f5468e2ff18bChris Wren // The first post time, stable across updates. 70640e387ce4e8aa97a8139fda54a5f5468e2ff18bChris Wren private long mCreationTimeMs; 71640e387ce4e8aa97a8139fda54a5f5468e2ff18bChris Wren 726650e5767b3d69268af7238cfa65dde6a9f2e0a3Chris Wren // The most recent visibility event. 736650e5767b3d69268af7238cfa65dde6a9f2e0a3Chris Wren private long mVisibleSinceMs; 746650e5767b3d69268af7238cfa65dde6a9f2e0a3Chris Wren 756650e5767b3d69268af7238cfa65dde6a9f2e0a3Chris Wren // The most recent update time, or the creation time if no updates. 766650e5767b3d69268af7238cfa65dde6a9f2e0a3Chris Wren private long mUpdateTimeMs; 776650e5767b3d69268af7238cfa65dde6a9f2e0a3Chris Wren 78a344656a010dc3c88aef39109f1ac459792e7607Chris Wren // Is this record an update of an old record? 79a344656a010dc3c88aef39109f1ac459792e7607Chris Wren public boolean isUpdate; 8054bbef435ed857fc68941672799fc8001c101119Chris Wren private int mPackagePriority; 81a344656a010dc3c88aef39109f1ac459792e7607Chris Wren 821031c974855ff4117a6d7866e664295786840319Chris Wren private int mAuthoritativeRank; 83cd4adf8b5ef9ac1f90fdddbb405404e173aedc87Christoph Studer private String mGlobalSortKey; 843ad4e3a45bbe44129b14c4d391431e44f1e04f0cChris Wren private int mPackageVisibility; 851031c974855ff4117a6d7866e664295786840319Chris Wren 861031c974855ff4117a6d7866e664295786840319Chris Wren @VisibleForTesting 871031c974855ff4117a6d7866e664295786840319Chris Wren public NotificationRecord(StatusBarNotification sbn, int score) 88333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren { 89333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren this.sbn = sbn; 90a344656a010dc3c88aef39109f1ac459792e7607Chris Wren this.score = score; 91365e4c38d58d38bb61d1fdd870346f2f594825fdChristoph Studer mOriginalFlags = sbn.getNotification().flags; 9252b7a5a5973c05fe59b751b82ee357fdfc1c5ef7Christoph Studer mRankingTimeMs = calculateRankingTimeMs(0L); 93640e387ce4e8aa97a8139fda54a5f5468e2ff18bChris Wren mCreationTimeMs = sbn.getPostTime(); 946650e5767b3d69268af7238cfa65dde6a9f2e0a3Chris Wren mUpdateTimeMs = mCreationTimeMs; 95333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren } 96333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren 97333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren // copy any notes that the ranking system may have made before the update 98333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren public void copyRankingInformation(NotificationRecord previous) { 99333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren mContactAffinity = previous.mContactAffinity; 100333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren mRecentlyIntrusive = previous.mRecentlyIntrusive; 10154bbef435ed857fc68941672799fc8001c101119Chris Wren mPackagePriority = previous.mPackagePriority; 1023ad4e3a45bbe44129b14c4d391431e44f1e04f0cChris Wren mPackageVisibility = previous.mPackageVisibility; 103333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren mIntercept = previous.mIntercept; 10452b7a5a5973c05fe59b751b82ee357fdfc1c5ef7Christoph Studer mRankingTimeMs = calculateRankingTimeMs(previous.getRankingTimeMs()); 105640e387ce4e8aa97a8139fda54a5f5468e2ff18bChris Wren mCreationTimeMs = previous.mCreationTimeMs; 1066650e5767b3d69268af7238cfa65dde6a9f2e0a3Chris Wren mVisibleSinceMs = previous.mVisibleSinceMs; 107cd4adf8b5ef9ac1f90fdddbb405404e173aedc87Christoph Studer // Don't copy mGlobalSortKey, recompute it. 108333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren } 109333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren 110333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren public Notification getNotification() { return sbn.getNotification(); } 111333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren public int getFlags() { return sbn.getNotification().flags; } 112da4bd209cffad7e47a4bc6e9f02c4bfc333d3d8dChris Wren public UserHandle getUser() { return sbn.getUser(); } 113333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren public String getKey() { return sbn.getKey(); } 114da4bd209cffad7e47a4bc6e9f02c4bfc333d3d8dChris Wren /** @deprecated Use {@link #getUser()} instead. */ 115da4bd209cffad7e47a4bc6e9f02c4bfc333d3d8dChris Wren public int getUserId() { return sbn.getUserId(); } 116333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren 117a17703138b0c51226c0e73dd8d34ea037d260aebDan Sandler void dump(PrintWriter pw, String prefix, Context baseContext, boolean redact) { 118333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren final Notification notification = sbn.getNotification(); 119d63f9321e62064660d426efd5abbd885c4a24652Dan Sandler final Icon icon = notification.getSmallIcon(); 120d63f9321e62064660d426efd5abbd885c4a24652Dan Sandler String iconStr = String.valueOf(icon); 121d63f9321e62064660d426efd5abbd885c4a24652Dan Sandler if (icon != null && icon.getType() == Icon.TYPE_RESOURCE) { 122d63f9321e62064660d426efd5abbd885c4a24652Dan Sandler iconStr += " / " + idDebugString(baseContext, icon.getResPackage(), icon.getResId()); 123d63f9321e62064660d426efd5abbd885c4a24652Dan Sandler } 124333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren pw.println(prefix + this); 125333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren pw.println(prefix + " uid=" + sbn.getUid() + " userId=" + sbn.getUserId()); 126d63f9321e62064660d426efd5abbd885c4a24652Dan Sandler pw.println(prefix + " icon=" + iconStr); 127333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren pw.println(prefix + " pri=" + notification.priority + " score=" + sbn.getScore()); 128333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren pw.println(prefix + " key=" + sbn.getKey()); 12924bd0be558838db4ff975e97fa986eb317773fc5Amith Yamasani pw.println(prefix + " seen=" + mIsSeen); 1301031c974855ff4117a6d7866e664295786840319Chris Wren pw.println(prefix + " groupKey=" + getGroupKey()); 131333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren pw.println(prefix + " contentIntent=" + notification.contentIntent); 132333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren pw.println(prefix + " deleteIntent=" + notification.deleteIntent); 133333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren pw.println(prefix + " tickerText=" + notification.tickerText); 134333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren pw.println(prefix + " contentView=" + notification.contentView); 135333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren pw.println(prefix + String.format(" defaults=0x%08x flags=0x%08x", 136333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren notification.defaults, notification.flags)); 137333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren pw.println(prefix + " sound=" + notification.sound); 138bfa5dc4c6c486bdabadb5ea2e356a7d348e3b975John Spurlock pw.println(prefix + " audioStreamType=" + notification.audioStreamType); 139bfa5dc4c6c486bdabadb5ea2e356a7d348e3b975John Spurlock pw.println(prefix + " audioAttributes=" + notification.audioAttributes); 140333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren pw.println(prefix + String.format(" color=0x%08x", notification.color)); 141333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren pw.println(prefix + " vibrate=" + Arrays.toString(notification.vibrate)); 142333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren pw.println(prefix + String.format(" led=0x%08x onMs=%d offMs=%d", 143333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren notification.ledARGB, notification.ledOnMS, notification.ledOffMS)); 144333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren if (notification.actions != null && notification.actions.length > 0) { 145333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren pw.println(prefix + " actions={"); 146333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren final int N = notification.actions.length; 147333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren for (int i=0; i<N; i++) { 148333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren final Notification.Action action = notification.actions[i]; 149333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren pw.println(String.format("%s [%d] \"%s\" -> %s", 150333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren prefix, 151333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren i, 152333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren action.title, 153333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren action.actionIntent.toString() 154333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren )); 155333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren } 156333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren pw.println(prefix + " }"); 157333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren } 158333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren if (notification.extras != null && notification.extras.size() > 0) { 159333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren pw.println(prefix + " extras={"); 160333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren for (String key : notification.extras.keySet()) { 161333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren pw.print(prefix + " " + key + "="); 162333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren Object val = notification.extras.get(key); 163333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren if (val == null) { 164333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren pw.println("null"); 165333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren } else { 166333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren pw.print(val.getClass().getSimpleName()); 167a17703138b0c51226c0e73dd8d34ea037d260aebDan Sandler if (redact && (val instanceof CharSequence || val instanceof String)) { 168333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren // redact contents from bugreports 169333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren } else if (val instanceof Bitmap) { 170333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren pw.print(String.format(" (%dx%d)", 171333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren ((Bitmap) val).getWidth(), 172333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren ((Bitmap) val).getHeight())); 173333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren } else if (val.getClass().isArray()) { 174333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren final int N = Array.getLength(val); 175a17703138b0c51226c0e73dd8d34ea037d260aebDan Sandler pw.print(" (" + N + ")"); 176a17703138b0c51226c0e73dd8d34ea037d260aebDan Sandler if (!redact) { 177a17703138b0c51226c0e73dd8d34ea037d260aebDan Sandler for (int j=0; j<N; j++) { 178a17703138b0c51226c0e73dd8d34ea037d260aebDan Sandler pw.println(); 179a17703138b0c51226c0e73dd8d34ea037d260aebDan Sandler pw.print(String.format("%s [%d] %s", 180a17703138b0c51226c0e73dd8d34ea037d260aebDan Sandler prefix, j, String.valueOf(Array.get(val, j)))); 181a17703138b0c51226c0e73dd8d34ea037d260aebDan Sandler } 182a17703138b0c51226c0e73dd8d34ea037d260aebDan Sandler } 183333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren } else { 184333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren pw.print(" (" + String.valueOf(val) + ")"); 185333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren } 186333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren pw.println(); 187333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren } 188333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren } 189333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren pw.println(prefix + " }"); 190333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren } 191333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren pw.println(prefix + " stats=" + stats.toString()); 192333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren pw.println(prefix + " mContactAffinity=" + mContactAffinity); 193333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren pw.println(prefix + " mRecentlyIntrusive=" + mRecentlyIntrusive); 19454bbef435ed857fc68941672799fc8001c101119Chris Wren pw.println(prefix + " mPackagePriority=" + mPackagePriority); 1953ad4e3a45bbe44129b14c4d391431e44f1e04f0cChris Wren pw.println(prefix + " mPackageVisibility=" + mPackageVisibility); 196333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren pw.println(prefix + " mIntercept=" + mIntercept); 197cd4adf8b5ef9ac1f90fdddbb405404e173aedc87Christoph Studer pw.println(prefix + " mGlobalSortKey=" + mGlobalSortKey); 19852b7a5a5973c05fe59b751b82ee357fdfc1c5ef7Christoph Studer pw.println(prefix + " mRankingTimeMs=" + mRankingTimeMs); 199640e387ce4e8aa97a8139fda54a5f5468e2ff18bChris Wren pw.println(prefix + " mCreationTimeMs=" + mCreationTimeMs); 2006650e5767b3d69268af7238cfa65dde6a9f2e0a3Chris Wren pw.println(prefix + " mVisibleSinceMs=" + mVisibleSinceMs); 2016650e5767b3d69268af7238cfa65dde6a9f2e0a3Chris Wren pw.println(prefix + " mUpdateTimeMs=" + mUpdateTimeMs); 202333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren } 203333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren 204333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren 205333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren static String idDebugString(Context baseContext, String packageName, int id) { 206333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren Context c; 207333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren 208333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren if (packageName != null) { 209333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren try { 210333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren c = baseContext.createPackageContext(packageName, 0); 211333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren } catch (NameNotFoundException e) { 212333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren c = baseContext; 213333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren } 214333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren } else { 215333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren c = baseContext; 216333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren } 217333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren 218333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren Resources r = c.getResources(); 219333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren try { 220333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren return r.getResourceName(id); 221333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren } catch (Resources.NotFoundException e) { 222333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren return "<name unknown>"; 223333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren } 224333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren } 225333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren 226333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren @Override 227333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren public final String toString() { 228333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren return String.format( 229333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren "NotificationRecord(0x%08x: pkg=%s user=%s id=%d tag=%s score=%d key=%s: %s)", 230333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren System.identityHashCode(this), 231333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren this.sbn.getPackageName(), this.sbn.getUser(), this.sbn.getId(), 232333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren this.sbn.getTag(), this.sbn.getScore(), this.sbn.getKey(), 233333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren this.sbn.getNotification()); 234333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren } 235333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren 236333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren public void setContactAffinity(float contactAffinity) { 237333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren mContactAffinity = contactAffinity; 238333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren } 239333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren 240333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren public float getContactAffinity() { 241333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren return mContactAffinity; 242333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren } 243333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren 2441d881a1e986c706963c254fbe2b6296a1cd10b75John Spurlock public void setRecentlyIntrusive(boolean recentlyIntrusive) { 245333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren mRecentlyIntrusive = recentlyIntrusive; 246333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren } 247333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren 248333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren public boolean isRecentlyIntrusive() { 249333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren return mRecentlyIntrusive; 250333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren } 251333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren 25254bbef435ed857fc68941672799fc8001c101119Chris Wren public void setPackagePriority(int packagePriority) { 2536ac5f8df62a4b6d87cf32797d2886efab8e28226John Spurlock mPackagePriority = packagePriority; 25454bbef435ed857fc68941672799fc8001c101119Chris Wren } 25554bbef435ed857fc68941672799fc8001c101119Chris Wren 25654bbef435ed857fc68941672799fc8001c101119Chris Wren public int getPackagePriority() { 25754bbef435ed857fc68941672799fc8001c101119Chris Wren return mPackagePriority; 25854bbef435ed857fc68941672799fc8001c101119Chris Wren } 25954bbef435ed857fc68941672799fc8001c101119Chris Wren 2603ad4e3a45bbe44129b14c4d391431e44f1e04f0cChris Wren public void setPackageVisibilityOverride(int packageVisibility) { 2613ad4e3a45bbe44129b14c4d391431e44f1e04f0cChris Wren mPackageVisibility = packageVisibility; 2623ad4e3a45bbe44129b14c4d391431e44f1e04f0cChris Wren } 2633ad4e3a45bbe44129b14c4d391431e44f1e04f0cChris Wren 2643ad4e3a45bbe44129b14c4d391431e44f1e04f0cChris Wren public int getPackageVisibilityOverride() { 2653ad4e3a45bbe44129b14c4d391431e44f1e04f0cChris Wren return mPackageVisibility; 2663ad4e3a45bbe44129b14c4d391431e44f1e04f0cChris Wren } 2673ad4e3a45bbe44129b14c4d391431e44f1e04f0cChris Wren 268333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren public boolean setIntercepted(boolean intercept) { 269333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren mIntercept = intercept; 270333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren return mIntercept; 271333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren } 272333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren 273333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren public boolean isIntercepted() { 274333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren return mIntercept; 275333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren } 276333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren 277312d1d01def474e39e4dabbf4aef0b8adaa7caedJohn Spurlock public boolean isCategory(String category) { 278bfa5dc4c6c486bdabadb5ea2e356a7d348e3b975John Spurlock return Objects.equals(getNotification().category, category); 279bfa5dc4c6c486bdabadb5ea2e356a7d348e3b975John Spurlock } 280bfa5dc4c6c486bdabadb5ea2e356a7d348e3b975John Spurlock 281bfa5dc4c6c486bdabadb5ea2e356a7d348e3b975John Spurlock public boolean isAudioStream(int stream) { 282bfa5dc4c6c486bdabadb5ea2e356a7d348e3b975John Spurlock return getNotification().audioStreamType == stream; 283bfa5dc4c6c486bdabadb5ea2e356a7d348e3b975John Spurlock } 284bfa5dc4c6c486bdabadb5ea2e356a7d348e3b975John Spurlock 285bfa5dc4c6c486bdabadb5ea2e356a7d348e3b975John Spurlock public boolean isAudioAttributesUsage(int usage) { 286bfa5dc4c6c486bdabadb5ea2e356a7d348e3b975John Spurlock final AudioAttributes attributes = getNotification().audioAttributes; 287bfa5dc4c6c486bdabadb5ea2e356a7d348e3b975John Spurlock return attributes != null && attributes.getUsage() == usage; 288312d1d01def474e39e4dabbf4aef0b8adaa7caedJohn Spurlock } 289312d1d01def474e39e4dabbf4aef0b8adaa7caedJohn Spurlock 29052b7a5a5973c05fe59b751b82ee357fdfc1c5ef7Christoph Studer /** 29152b7a5a5973c05fe59b751b82ee357fdfc1c5ef7Christoph Studer * Returns the timestamp to use for time-based sorting in the ranker. 29252b7a5a5973c05fe59b751b82ee357fdfc1c5ef7Christoph Studer */ 29352b7a5a5973c05fe59b751b82ee357fdfc1c5ef7Christoph Studer public long getRankingTimeMs() { 29452b7a5a5973c05fe59b751b82ee357fdfc1c5ef7Christoph Studer return mRankingTimeMs; 29552b7a5a5973c05fe59b751b82ee357fdfc1c5ef7Christoph Studer } 29652b7a5a5973c05fe59b751b82ee357fdfc1c5ef7Christoph Studer 29752b7a5a5973c05fe59b751b82ee357fdfc1c5ef7Christoph Studer /** 298e6ddb8a1348d2ea53bc3033be43c4dae922b653aChris Wren * @param now this current time in milliseconds. 299e6ddb8a1348d2ea53bc3033be43c4dae922b653aChris Wren * @returns the number of milliseconds since the most recent update, or the post time if none. 3006650e5767b3d69268af7238cfa65dde6a9f2e0a3Chris Wren */ 301e6ddb8a1348d2ea53bc3033be43c4dae922b653aChris Wren public int getFreshnessMs(long now) { 302e6ddb8a1348d2ea53bc3033be43c4dae922b653aChris Wren return (int) (now - mUpdateTimeMs); 3036650e5767b3d69268af7238cfa65dde6a9f2e0a3Chris Wren } 3046650e5767b3d69268af7238cfa65dde6a9f2e0a3Chris Wren 3056650e5767b3d69268af7238cfa65dde6a9f2e0a3Chris Wren /** 306e6ddb8a1348d2ea53bc3033be43c4dae922b653aChris Wren * @param now this current time in milliseconds. 307e6ddb8a1348d2ea53bc3033be43c4dae922b653aChris Wren * @returns the number of milliseconds since the the first post, ignoring updates. 308640e387ce4e8aa97a8139fda54a5f5468e2ff18bChris Wren */ 309e6ddb8a1348d2ea53bc3033be43c4dae922b653aChris Wren public int getLifespanMs(long now) { 310e6ddb8a1348d2ea53bc3033be43c4dae922b653aChris Wren return (int) (now - mCreationTimeMs); 311640e387ce4e8aa97a8139fda54a5f5468e2ff18bChris Wren } 312640e387ce4e8aa97a8139fda54a5f5468e2ff18bChris Wren 313640e387ce4e8aa97a8139fda54a5f5468e2ff18bChris Wren /** 314e6ddb8a1348d2ea53bc3033be43c4dae922b653aChris Wren * @param now this current time in milliseconds. 315e6ddb8a1348d2ea53bc3033be43c4dae922b653aChris Wren * @returns the number of milliseconds since the most recent visibility event, or 0 if never. 3166650e5767b3d69268af7238cfa65dde6a9f2e0a3Chris Wren */ 317e6ddb8a1348d2ea53bc3033be43c4dae922b653aChris Wren public int getExposureMs(long now) { 318e6ddb8a1348d2ea53bc3033be43c4dae922b653aChris Wren return mVisibleSinceMs == 0 ? 0 : (int) (now - mVisibleSinceMs); 3196650e5767b3d69268af7238cfa65dde6a9f2e0a3Chris Wren } 3206650e5767b3d69268af7238cfa65dde6a9f2e0a3Chris Wren 3216650e5767b3d69268af7238cfa65dde6a9f2e0a3Chris Wren /** 3226650e5767b3d69268af7238cfa65dde6a9f2e0a3Chris Wren * Set the visibility of the notification. 3236650e5767b3d69268af7238cfa65dde6a9f2e0a3Chris Wren */ 324d1dbc92d67af4cb72bb2faff9011d36b6833bbfdChris Wren public void setVisibility(boolean visible, int rank) { 3256650e5767b3d69268af7238cfa65dde6a9f2e0a3Chris Wren final long now = System.currentTimeMillis(); 326e6ddb8a1348d2ea53bc3033be43c4dae922b653aChris Wren mVisibleSinceMs = visible ? now : mVisibleSinceMs; 3276650e5767b3d69268af7238cfa65dde6a9f2e0a3Chris Wren stats.onVisibilityChanged(visible); 3286650e5767b3d69268af7238cfa65dde6a9f2e0a3Chris Wren EventLogTags.writeNotificationVisibility(getKey(), visible ? 1 : 0, 3296650e5767b3d69268af7238cfa65dde6a9f2e0a3Chris Wren (int) (now - mCreationTimeMs), 330d1dbc92d67af4cb72bb2faff9011d36b6833bbfdChris Wren (int) (now - mUpdateTimeMs), 331d1dbc92d67af4cb72bb2faff9011d36b6833bbfdChris Wren 0, // exposure time 332d1dbc92d67af4cb72bb2faff9011d36b6833bbfdChris Wren rank); 3336650e5767b3d69268af7238cfa65dde6a9f2e0a3Chris Wren } 3346650e5767b3d69268af7238cfa65dde6a9f2e0a3Chris Wren 3356650e5767b3d69268af7238cfa65dde6a9f2e0a3Chris Wren /** 33652b7a5a5973c05fe59b751b82ee357fdfc1c5ef7Christoph Studer * @param previousRankingTimeMs for updated notifications, {@link #getRankingTimeMs()} 33752b7a5a5973c05fe59b751b82ee357fdfc1c5ef7Christoph Studer * of the previous notification record, 0 otherwise 33852b7a5a5973c05fe59b751b82ee357fdfc1c5ef7Christoph Studer */ 33952b7a5a5973c05fe59b751b82ee357fdfc1c5ef7Christoph Studer private long calculateRankingTimeMs(long previousRankingTimeMs) { 34052b7a5a5973c05fe59b751b82ee357fdfc1c5ef7Christoph Studer Notification n = getNotification(); 34152b7a5a5973c05fe59b751b82ee357fdfc1c5ef7Christoph Studer // Take developer provided 'when', unless it's in the future. 34252b7a5a5973c05fe59b751b82ee357fdfc1c5ef7Christoph Studer if (n.when != 0 && n.when <= sbn.getPostTime()) { 34352b7a5a5973c05fe59b751b82ee357fdfc1c5ef7Christoph Studer return n.when; 34452b7a5a5973c05fe59b751b82ee357fdfc1c5ef7Christoph Studer } 34552b7a5a5973c05fe59b751b82ee357fdfc1c5ef7Christoph Studer // If we've ranked a previous instance with a timestamp, inherit it. This case is 34652b7a5a5973c05fe59b751b82ee357fdfc1c5ef7Christoph Studer // important in order to have ranking stability for updating notifications. 34752b7a5a5973c05fe59b751b82ee357fdfc1c5ef7Christoph Studer if (previousRankingTimeMs > 0) { 34852b7a5a5973c05fe59b751b82ee357fdfc1c5ef7Christoph Studer return previousRankingTimeMs; 34952b7a5a5973c05fe59b751b82ee357fdfc1c5ef7Christoph Studer } 35052b7a5a5973c05fe59b751b82ee357fdfc1c5ef7Christoph Studer return sbn.getPostTime(); 35152b7a5a5973c05fe59b751b82ee357fdfc1c5ef7Christoph Studer } 3521031c974855ff4117a6d7866e664295786840319Chris Wren 353cd4adf8b5ef9ac1f90fdddbb405404e173aedc87Christoph Studer public void setGlobalSortKey(String globalSortKey) { 354cd4adf8b5ef9ac1f90fdddbb405404e173aedc87Christoph Studer mGlobalSortKey = globalSortKey; 3551031c974855ff4117a6d7866e664295786840319Chris Wren } 3561031c974855ff4117a6d7866e664295786840319Chris Wren 357cd4adf8b5ef9ac1f90fdddbb405404e173aedc87Christoph Studer public String getGlobalSortKey() { 358cd4adf8b5ef9ac1f90fdddbb405404e173aedc87Christoph Studer return mGlobalSortKey; 3591031c974855ff4117a6d7866e664295786840319Chris Wren } 3601031c974855ff4117a6d7866e664295786840319Chris Wren 361f47e51ec605fccf7fed9e50d1adc98fbd4e8b340Amith Yamasani /** Check if any of the listeners have marked this notification as seen by the user. */ 362f47e51ec605fccf7fed9e50d1adc98fbd4e8b340Amith Yamasani public boolean isSeen() { 363f47e51ec605fccf7fed9e50d1adc98fbd4e8b340Amith Yamasani return mIsSeen; 364f47e51ec605fccf7fed9e50d1adc98fbd4e8b340Amith Yamasani } 365f47e51ec605fccf7fed9e50d1adc98fbd4e8b340Amith Yamasani 366f47e51ec605fccf7fed9e50d1adc98fbd4e8b340Amith Yamasani /** Mark the notification as seen by the user. */ 367f47e51ec605fccf7fed9e50d1adc98fbd4e8b340Amith Yamasani public void setSeen() { 368f47e51ec605fccf7fed9e50d1adc98fbd4e8b340Amith Yamasani mIsSeen = true; 369f47e51ec605fccf7fed9e50d1adc98fbd4e8b340Amith Yamasani } 370f47e51ec605fccf7fed9e50d1adc98fbd4e8b340Amith Yamasani 3711031c974855ff4117a6d7866e664295786840319Chris Wren public void setAuthoritativeRank(int authoritativeRank) { 3721031c974855ff4117a6d7866e664295786840319Chris Wren mAuthoritativeRank = authoritativeRank; 3731031c974855ff4117a6d7866e664295786840319Chris Wren } 3741031c974855ff4117a6d7866e664295786840319Chris Wren 3751031c974855ff4117a6d7866e664295786840319Chris Wren public int getAuthoritativeRank() { 3761031c974855ff4117a6d7866e664295786840319Chris Wren return mAuthoritativeRank; 3771031c974855ff4117a6d7866e664295786840319Chris Wren } 3781031c974855ff4117a6d7866e664295786840319Chris Wren 3791031c974855ff4117a6d7866e664295786840319Chris Wren public String getGroupKey() { 3801031c974855ff4117a6d7866e664295786840319Chris Wren return sbn.getGroupKey(); 3811031c974855ff4117a6d7866e664295786840319Chris Wren } 382333a61c3a5a83fe9c50ebeb5c947317f61385b7bChris Wren} 383