summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--core/java/android/app/INotificationManager.aidl3
-rw-r--r--core/java/android/app/Notification.java20
-rw-r--r--services/core/java/com/android/server/notification/NotificationIntrusivenessExtractor.java9
-rw-r--r--services/core/java/com/android/server/notification/NotificationManagerService.java21
-rw-r--r--services/core/java/com/android/server/notification/NotificationRecord.java2
-rw-r--r--services/core/java/com/android/server/notification/RankingConfig.java4
-rw-r--r--services/core/java/com/android/server/notification/RankingHelper.java230
7 files changed, 178 insertions, 111 deletions
diff --git a/core/java/android/app/INotificationManager.aidl b/core/java/android/app/INotificationManager.aidl
index 5d864df..33262b3 100644
--- a/core/java/android/app/INotificationManager.aidl
+++ b/core/java/android/app/INotificationManager.aidl
@@ -48,6 +48,9 @@ interface INotificationManager
void setPackagePriority(String pkg, int uid, int priority);
int getPackagePriority(String pkg, int uid);
+ void setPackagePeekable(String pkg, int uid, boolean peekable);
+ boolean getPackagePeekable(String pkg, int uid);
+
void setPackageVisibilityOverride(String pkg, int uid, int visibility);
int getPackageVisibilityOverride(String pkg, int uid);
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index b824e97..b31ce04 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -1840,6 +1840,26 @@ public class Notification implements Parcelable
}
/**
+ * {@hide}
+ */
+ public static String priorityToString(@Priority int pri) {
+ switch (pri) {
+ case PRIORITY_MIN:
+ return "MIN";
+ case PRIORITY_LOW:
+ return "LOW";
+ case PRIORITY_DEFAULT:
+ return "DEFAULT";
+ case PRIORITY_HIGH:
+ return "HIGH";
+ case PRIORITY_MAX:
+ return "MAX";
+ default:
+ return "UNKNOWN(" + String.valueOf(pri) + ")";
+ }
+ }
+
+ /**
* @hide
*/
public boolean isValid() {
diff --git a/services/core/java/com/android/server/notification/NotificationIntrusivenessExtractor.java b/services/core/java/com/android/server/notification/NotificationIntrusivenessExtractor.java
index 1335706..22cdd58 100644
--- a/services/core/java/com/android/server/notification/NotificationIntrusivenessExtractor.java
+++ b/services/core/java/com/android/server/notification/NotificationIntrusivenessExtractor.java
@@ -18,6 +18,7 @@ package com.android.server.notification;
import android.app.Notification;
import android.content.Context;
+import android.util.Log;
import android.util.Slog;
/**
@@ -25,8 +26,8 @@ import android.util.Slog;
* notifications and marks them to get a temporary ranking bump.
*/
public class NotificationIntrusivenessExtractor implements NotificationSignalExtractor {
- private static final String TAG = "NotificationNoiseExtractor";
- private static final boolean DBG = false;
+ private static final String TAG = "IntrusivenessExtractor";
+ private static final boolean DBG = Log.isLoggable(TAG, Log.DEBUG);
/** Length of time (in milliseconds) that an intrusive or noisy notification will stay at
the top of the ranking order, before it falls back to its natural position. */
@@ -48,7 +49,7 @@ public class NotificationIntrusivenessExtractor implements NotificationSignalExt
(notification.defaults & Notification.DEFAULT_SOUND) != 0 ||
notification.sound != null ||
notification.fullScreenIntent != null) {
- record.setRecentlyIntusive(true);
+ record.setRecentlyIntrusive(true);
}
return new RankingReconsideration(record.getKey(), HANG_TIME_MS) {
@@ -59,7 +60,7 @@ public class NotificationIntrusivenessExtractor implements NotificationSignalExt
@Override
public void applyChangesLocked(NotificationRecord record) {
- record.setRecentlyIntusive(false);
+ record.setRecentlyIntrusive(false);
}
};
}
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 0c71d5f..c330046 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -1216,6 +1216,19 @@ public class NotificationManagerService extends SystemService {
}
@Override
+ public void setPackagePeekable(String pkg, int uid, boolean peekable) {
+ checkCallerIsSystem();
+
+ mRankingHelper.setPackagePeekable(pkg, uid, peekable);
+ }
+
+ @Override
+ public boolean getPackagePeekable(String pkg, int uid) {
+ checkCallerIsSystem();
+ return mRankingHelper.getPackagePeekable(pkg, uid);
+ }
+
+ @Override
public void setPackageVisibilityOverride(String pkg, int uid, int visibility) {
checkCallerIsSystem();
mRankingHelper.setPackageVisibilityOverride(pkg, uid, visibility);
@@ -1845,6 +1858,14 @@ public class NotificationManagerService extends SystemService {
notification.priority = Notification.PRIORITY_HIGH;
}
}
+ // force no heads up per package config
+ if (!mRankingHelper.getPackagePeekable(pkg, callingUid)) {
+ if (notification.extras == null) {
+ notification.extras = new Bundle();
+ }
+ notification.extras.putInt(Notification.EXTRA_AS_HEADS_UP,
+ Notification.HEADS_UP_NEVER);
+ }
// 1. initial score: buckets of 10, around the app [-20..20]
final int score = notification.priority * NOTIFICATION_PRIORITY_MULTIPLIER;
diff --git a/services/core/java/com/android/server/notification/NotificationRecord.java b/services/core/java/com/android/server/notification/NotificationRecord.java
index ea6f2db..39fd9ab 100644
--- a/services/core/java/com/android/server/notification/NotificationRecord.java
+++ b/services/core/java/com/android/server/notification/NotificationRecord.java
@@ -209,7 +209,7 @@ public final class NotificationRecord {
return mContactAffinity;
}
- public void setRecentlyIntusive(boolean recentlyIntrusive) {
+ public void setRecentlyIntrusive(boolean recentlyIntrusive) {
mRecentlyIntrusive = recentlyIntrusive;
}
diff --git a/services/core/java/com/android/server/notification/RankingConfig.java b/services/core/java/com/android/server/notification/RankingConfig.java
index aea137b..803db10 100644
--- a/services/core/java/com/android/server/notification/RankingConfig.java
+++ b/services/core/java/com/android/server/notification/RankingConfig.java
@@ -20,6 +20,10 @@ public interface RankingConfig {
void setPackagePriority(String packageName, int uid, int priority);
+ boolean getPackagePeekable(String packageName, int uid);
+
+ void setPackagePeekable(String packageName, int uid, boolean peekable);
+
int getPackageVisibilityOverride(String packageName, int uid);
void setPackageVisibilityOverride(String packageName, int uid, int visibility);
diff --git a/services/core/java/com/android/server/notification/RankingHelper.java b/services/core/java/com/android/server/notification/RankingHelper.java
index 518e223..88055ba 100644
--- a/services/core/java/com/android/server/notification/RankingHelper.java
+++ b/services/core/java/com/android/server/notification/RankingHelper.java
@@ -23,9 +23,8 @@ import android.os.UserHandle;
import android.service.notification.NotificationListenerService;
import android.text.TextUtils;
import android.util.ArrayMap;
-import android.util.ArraySet;
import android.util.Slog;
-import android.util.SparseIntArray;
+
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlSerializer;
@@ -34,12 +33,10 @@ import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Collections;
-import java.util.Set;
import java.util.concurrent.TimeUnit;
public class RankingHelper implements RankingConfig {
private static final String TAG = "RankingHelper";
- private static final boolean DEBUG = false;
private static final int XML_VERSION = 1;
@@ -50,16 +47,20 @@ public class RankingHelper implements RankingConfig {
private static final String ATT_NAME = "name";
private static final String ATT_UID = "uid";
private static final String ATT_PRIORITY = "priority";
+ private static final String ATT_PEEKABLE = "peekable";
private static final String ATT_VISIBILITY = "visibility";
+ private static final int DEFAULT_PRIORITY = Notification.PRIORITY_DEFAULT;
+ private static final boolean DEFAULT_PEEKABLE = true;
+ private static final int DEFAULT_VISIBILITY =
+ NotificationListenerService.Ranking.VISIBILITY_NO_OVERRIDE;
+
private final NotificationSignalExtractor[] mSignalExtractors;
private final NotificationComparator mPreliminaryComparator = new NotificationComparator();
private final GlobalSortKeyComparator mFinalComparator = new GlobalSortKeyComparator();
- // Package name to uid, to priority. Would be better as Table<String, Int, Int>
- private final ArrayMap<String, SparseIntArray> mPackagePriorities;
- private final ArrayMap<String, SparseIntArray> mPackageVisibilities;
- private final ArrayMap<String, NotificationRecord> mProxyByGroupTmp;
+ private final ArrayMap<String, Record> mRecords = new ArrayMap<>(); // pkg|uid => Record
+ private final ArrayMap<String, NotificationRecord> mProxyByGroupTmp = new ArrayMap<>();
private final Context mContext;
private final Handler mRankingHandler;
@@ -67,8 +68,6 @@ public class RankingHelper implements RankingConfig {
public RankingHelper(Context context, Handler rankingHandler, String[] extractorNames) {
mContext = context;
mRankingHandler = rankingHandler;
- mPackagePriorities = new ArrayMap<String, SparseIntArray>();
- mPackageVisibilities = new ArrayMap<String, SparseIntArray>();
final int N = extractorNames.length;
mSignalExtractors = new NotificationSignalExtractor[N];
@@ -88,9 +87,9 @@ public class RankingHelper implements RankingConfig {
Slog.w(TAG, "Problem accessing extractor " + extractorNames[i] + ".", e);
}
}
- mProxyByGroupTmp = new ArrayMap<String, NotificationRecord>();
}
+ @SuppressWarnings("unchecked")
public <T extends NotificationSignalExtractor> T findExtractor(Class<T> extractorClass) {
final int N = mSignalExtractors.length;
for (int i = 0; i < N; i++) {
@@ -125,8 +124,7 @@ public class RankingHelper implements RankingConfig {
if (type != XmlPullParser.START_TAG) return;
String tag = parser.getName();
if (!TAG_RANKING.equals(tag)) return;
- mPackagePriorities.clear();
- final int version = safeInt(parser, ATT_VERSION, XML_VERSION);
+ mRecords.clear();
while ((type = parser.next()) != XmlPullParser.END_DOCUMENT) {
tag = parser.getName();
if (type == XmlPullParser.END_TAG && TAG_RANKING.equals(tag)) {
@@ -135,27 +133,20 @@ public class RankingHelper implements RankingConfig {
if (type == XmlPullParser.START_TAG) {
if (TAG_PACKAGE.equals(tag)) {
int uid = safeInt(parser, ATT_UID, UserHandle.USER_ALL);
- int priority = safeInt(parser, ATT_PRIORITY, Notification.PRIORITY_DEFAULT);
- int vis = safeInt(parser, ATT_VISIBILITY,
- NotificationListenerService.Ranking.VISIBILITY_NO_OVERRIDE);
+ int priority = safeInt(parser, ATT_PRIORITY, DEFAULT_PRIORITY);
+ boolean peekable = safeBool(parser, ATT_PEEKABLE, DEFAULT_PEEKABLE);
+ int vis = safeInt(parser, ATT_VISIBILITY, DEFAULT_VISIBILITY);
String name = parser.getAttributeValue(null, ATT_NAME);
if (!TextUtils.isEmpty(name)) {
- if (priority != Notification.PRIORITY_DEFAULT) {
- SparseIntArray priorityByUid = mPackagePriorities.get(name);
- if (priorityByUid == null) {
- priorityByUid = new SparseIntArray();
- mPackagePriorities.put(name, priorityByUid);
- }
- priorityByUid.put(uid, priority);
+ if (priority != DEFAULT_PRIORITY) {
+ getOrCreateRecord(name, uid).priority = priority;
+ }
+ if (peekable != DEFAULT_PEEKABLE) {
+ getOrCreateRecord(name, uid).peekable = peekable;
}
- if (vis != NotificationListenerService.Ranking.VISIBILITY_NO_OVERRIDE) {
- SparseIntArray visibilityByUid = mPackageVisibilities.get(name);
- if (visibilityByUid == null) {
- visibilityByUid = new SparseIntArray();
- mPackageVisibilities.put(name, visibilityByUid);
- }
- visibilityByUid.put(uid, vis);
+ if (vis != DEFAULT_VISIBILITY) {
+ getOrCreateRecord(name, uid).visibility = vis;
}
}
}
@@ -164,49 +155,53 @@ public class RankingHelper implements RankingConfig {
throw new IllegalStateException("Failed to reach END_DOCUMENT");
}
+ private static String recordKey(String pkg, int uid) {
+ return pkg + "|" + uid;
+ }
+
+ private Record getOrCreateRecord(String pkg, int uid) {
+ final String key = recordKey(pkg, uid);
+ Record r = mRecords.get(key);
+ if (r == null) {
+ r = new Record();
+ r.pkg = pkg;
+ r.uid = uid;
+ mRecords.put(key, r);
+ }
+ return r;
+ }
+
+ private void removeDefaultRecords() {
+ final int N = mRecords.size();
+ for (int i = N - 1; i >= 0; i--) {
+ final Record r = mRecords.valueAt(i);
+ if (r.priority == DEFAULT_PRIORITY && r.peekable == DEFAULT_PEEKABLE
+ && r.visibility == DEFAULT_VISIBILITY) {
+ mRecords.remove(i);
+ }
+ }
+ }
+
public void writeXml(XmlSerializer out) throws IOException {
out.startTag(null, TAG_RANKING);
out.attribute(null, ATT_VERSION, Integer.toString(XML_VERSION));
- final Set<String> packageNames = new ArraySet<>(mPackagePriorities.size()
- + mPackageVisibilities.size());
- packageNames.addAll(mPackagePriorities.keySet());
- packageNames.addAll(mPackageVisibilities.keySet());
- final Set<Integer> packageUids = new ArraySet<>();
- for (String packageName : packageNames) {
- packageUids.clear();
- SparseIntArray priorityByUid = mPackagePriorities.get(packageName);
- SparseIntArray visibilityByUid = mPackageVisibilities.get(packageName);
- if (priorityByUid != null) {
- final int M = priorityByUid.size();
- for (int j = 0; j < M; j++) {
- packageUids.add(priorityByUid.keyAt(j));
- }
+ final int N = mRecords.size();
+ for (int i = 0; i < N; i++) {
+ final Record r = mRecords.valueAt(i);
+ out.startTag(null, TAG_PACKAGE);
+ out.attribute(null, ATT_NAME, r.pkg);
+ if (r.priority != DEFAULT_PRIORITY) {
+ out.attribute(null, ATT_PRIORITY, Integer.toString(r.priority));
}
- if (visibilityByUid != null) {
- final int M = visibilityByUid.size();
- for (int j = 0; j < M; j++) {
- packageUids.add(visibilityByUid.keyAt(j));
- }
+ if (r.peekable != DEFAULT_PEEKABLE) {
+ out.attribute(null, ATT_PEEKABLE, Boolean.toString(r.peekable));
}
- for (Integer uid : packageUids) {
- out.startTag(null, TAG_PACKAGE);
- out.attribute(null, ATT_NAME, packageName);
- if (priorityByUid != null) {
- final int priority = priorityByUid.get(uid);
- if (priority != Notification.PRIORITY_DEFAULT) {
- out.attribute(null, ATT_PRIORITY, Integer.toString(priority));
- }
- }
- if (visibilityByUid != null) {
- final int visibility = visibilityByUid.get(uid);
- if (visibility != NotificationListenerService.Ranking.VISIBILITY_NO_OVERRIDE) {
- out.attribute(null, ATT_VISIBILITY, Integer.toString(visibility));
- }
- }
- out.attribute(null, ATT_UID, Integer.toString(uid));
- out.endTag(null, TAG_PACKAGE);
+ if (r.visibility != DEFAULT_VISIBILITY) {
+ out.attribute(null, ATT_VISIBILITY, Integer.toString(r.visibility));
}
+ out.attribute(null, ATT_UID, Integer.toString(r.uid));
+ out.endTag(null, TAG_PACKAGE);
}
out.endTag(null, TAG_RANKING);
}
@@ -295,14 +290,20 @@ public class RankingHelper implements RankingConfig {
}
}
+ private static boolean safeBool(XmlPullParser parser, String att, boolean defValue) {
+ final String val = parser.getAttributeValue(null, att);
+ return tryParseBool(val, defValue);
+ }
+
+ private static boolean tryParseBool(String value, boolean defValue) {
+ if (TextUtils.isEmpty(value)) return defValue;
+ return Boolean.valueOf(value);
+ }
+
@Override
public int getPackagePriority(String packageName, int uid) {
- int priority = Notification.PRIORITY_DEFAULT;
- SparseIntArray priorityByUid = mPackagePriorities.get(packageName);
- if (priorityByUid != null) {
- priority = priorityByUid.get(uid, Notification.PRIORITY_DEFAULT);
- }
- return priority;
+ final Record r = mRecords.get(recordKey(packageName, uid));
+ return r != null ? r.priority : DEFAULT_PRIORITY;
}
@Override
@@ -310,24 +311,31 @@ public class RankingHelper implements RankingConfig {
if (priority == getPackagePriority(packageName, uid)) {
return;
}
- SparseIntArray priorityByUid = mPackagePriorities.get(packageName);
- if (priorityByUid == null) {
- priorityByUid = new SparseIntArray();
- mPackagePriorities.put(packageName, priorityByUid);
+ getOrCreateRecord(packageName, uid).priority = priority;
+ removeDefaultRecords();
+ updateConfig();
+ }
+
+ @Override
+ public boolean getPackagePeekable(String packageName, int uid) {
+ final Record r = mRecords.get(recordKey(packageName, uid));
+ return r != null ? r.peekable : DEFAULT_PEEKABLE;
+ }
+
+ @Override
+ public void setPackagePeekable(String packageName, int uid, boolean peekable) {
+ if (peekable == getPackagePeekable(packageName, uid)) {
+ return;
}
- priorityByUid.put(uid, priority);
+ getOrCreateRecord(packageName, uid).peekable = peekable;
+ removeDefaultRecords();
updateConfig();
}
@Override
public int getPackageVisibilityOverride(String packageName, int uid) {
- int visibility = NotificationListenerService.Ranking.VISIBILITY_NO_OVERRIDE;
- SparseIntArray visibilityByUid = mPackageVisibilities.get(packageName);
- if (visibilityByUid != null) {
- visibility = visibilityByUid.get(uid,
- NotificationListenerService.Ranking.VISIBILITY_NO_OVERRIDE);
- }
- return visibility;
+ final Record r = mRecords.get(recordKey(packageName, uid));
+ return r != null ? r.visibility : DEFAULT_VISIBILITY;
}
@Override
@@ -335,12 +343,8 @@ public class RankingHelper implements RankingConfig {
if (visibility == getPackageVisibilityOverride(packageName, uid)) {
return;
}
- SparseIntArray visibilityByUid = mPackageVisibilities.get(packageName);
- if (visibilityByUid == null) {
- visibilityByUid = new SparseIntArray();
- mPackageVisibilities.put(packageName, visibilityByUid);
- }
- visibilityByUid.put(uid, visibility);
+ getOrCreateRecord(packageName, uid).visibility = visibility;
+ removeDefaultRecords();
updateConfig();
}
@@ -356,28 +360,42 @@ public class RankingHelper implements RankingConfig {
pw.println(mSignalExtractors[i]);
}
}
- final int N = mPackagePriorities.size();
if (filter == null) {
pw.print(prefix);
- pw.println("package priorities:");
+ pw.println("per-package config:");
}
+ final int N = mRecords.size();
for (int i = 0; i < N; i++) {
- String name = mPackagePriorities.keyAt(i);
- if (filter == null || filter.matches(name)) {
- SparseIntArray priorityByUid = mPackagePriorities.get(name);
- final int M = priorityByUid.size();
- for (int j = 0; j < M; j++) {
- int uid = priorityByUid.keyAt(j);
- int priority = priorityByUid.get(uid);
- pw.print(prefix);
- pw.print(" ");
- pw.print(name);
- pw.print(" (");
- pw.print(uid);
- pw.print(") has priority: ");
- pw.println(priority);
+ final Record r = mRecords.valueAt(i);
+ if (filter == null || filter.matches(r.pkg)) {
+ pw.print(prefix);
+ pw.print(" ");
+ pw.print(r.pkg);
+ pw.print(" (");
+ pw.print(r.uid);
+ pw.print(')');
+ if (r.priority != DEFAULT_PRIORITY) {
+ pw.print(" priority=");
+ pw.print(Notification.priorityToString(r.priority));
+ }
+ if (r.peekable != DEFAULT_PEEKABLE) {
+ pw.print(" peekable=");
+ pw.print(r.peekable);
+ }
+ if (r.visibility != DEFAULT_VISIBILITY) {
+ pw.print(" visibility=");
+ pw.print(Notification.visibilityToString(r.visibility));
}
+ pw.println();
}
}
}
+
+ private static class Record {
+ String pkg;
+ int uid;
+ int priority = DEFAULT_PRIORITY;
+ boolean peekable = DEFAULT_PEEKABLE;
+ int visibility = DEFAULT_VISIBILITY;
+ }
}