only rate limit notification updates
Updates to progress bars are the main culprit in system
performance events caused by apps spamming the notification
service. Rate-limiting only updates allows us to set a lower
threshold wihtout the owrry of mistakenly dropping bursts of
notifications being quickly posted after a network sync.
Also reduce logspam caused by the rate-limit events.
Bug: 30132961
Change-Id: I49acda6a2831204da45e899ddd3d62d571d7174b
diff --git a/core/java/android/app/NotificationManager.java b/core/java/android/app/NotificationManager.java
index 18b72e29..ff514bd 100644
--- a/core/java/android/app/NotificationManager.java
+++ b/core/java/android/app/NotificationManager.java
@@ -312,8 +312,8 @@
try {
service.enqueueNotificationWithTag(pkg, mContext.getOpPackageName(), tag, id,
copy, idOut, user.getIdentifier());
- if (id != idOut[0]) {
- Log.w(TAG, "notify: id corrupted: sent " + id + ", got back " + idOut[0]);
+ if (localLOGV && id != idOut[0]) {
+ Log.v(TAG, "notify: id corrupted: sent " + id + ", got back " + idOut[0]);
}
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 8b5942c..2dbbc88 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -180,7 +180,7 @@
= SystemProperties.getBoolean("debug.child_notifs", true);
static final int MAX_PACKAGE_NOTIFICATIONS = 50;
- static final float DEFAULT_MAX_NOTIFICATION_ENQUEUE_RATE = 50f;
+ static final float DEFAULT_MAX_NOTIFICATION_ENQUEUE_RATE = 10f;
// message codes
static final int MESSAGE_TIMEOUT = 2;
@@ -2538,20 +2538,32 @@
mUsageStats.registerEnqueuedByApp(pkg);
+
+ if (pkg == null || notification == null) {
+ throw new IllegalArgumentException("null not allowed: pkg=" + pkg
+ + " id=" + id + " notification=" + notification);
+ }
+ final StatusBarNotification n = new StatusBarNotification(
+ pkg, opPkg, id, tag, callingUid, callingPid, 0, notification,
+ user);
+
// Limit the number of notifications that any given package except the android
// package or a registered listener can enqueue. Prevents DOS attacks and deals with leaks.
if (!isSystemNotification && !isNotificationFromListener) {
synchronized (mNotificationList) {
- final float appEnqueueRate = mUsageStats.getAppEnqueueRate(pkg);
- if (appEnqueueRate > mMaxPackageEnqueueRate) {
- mUsageStats.registerOverRateQuota(pkg);
- final long now = SystemClock.elapsedRealtime();
- if ((now - mLastOverRateLogTime) > MIN_PACKAGE_OVERRATE_LOG_INTERVAL) {
- Slog.e(TAG, "Package enqueue rate is " + appEnqueueRate
- + ". Shedding events. package=" + pkg);
- mLastOverRateLogTime = now;
+ if(mNotificationsByKey.get(n.getKey()) != null) {
+ // this is an update, rate limit updates only
+ final float appEnqueueRate = mUsageStats.getAppEnqueueRate(pkg);
+ if (appEnqueueRate > mMaxPackageEnqueueRate) {
+ mUsageStats.registerOverRateQuota(pkg);
+ final long now = SystemClock.elapsedRealtime();
+ if ((now - mLastOverRateLogTime) > MIN_PACKAGE_OVERRATE_LOG_INTERVAL) {
+ Slog.e(TAG, "Package enqueue rate is " + appEnqueueRate
+ + ". Shedding events. package=" + pkg);
+ mLastOverRateLogTime = now;
+ }
+ return;
}
- return;
}
int count = 0;
@@ -2574,11 +2586,6 @@
}
}
- if (pkg == null || notification == null) {
- throw new IllegalArgumentException("null not allowed: pkg=" + pkg
- + " id=" + id + " notification=" + notification);
- }
-
// Whitelist pending intents.
if (notification.allPendingIntents != null) {
final int intentCount = notification.allPendingIntents.size();
@@ -2601,9 +2608,6 @@
Notification.PRIORITY_MAX);
// setup local book-keeping
- final StatusBarNotification n = new StatusBarNotification(
- pkg, opPkg, id, tag, callingUid, callingPid, 0, notification,
- user);
final NotificationRecord r = new NotificationRecord(getContext(), n);
mHandler.post(new EnqueueNotificationRunnable(userId, r));