summaryrefslogtreecommitdiffstats
path: root/services
diff options
context:
space:
mode:
authorDanny Baumann <dannybaumann@web.de>2016-10-19 13:38:06 +0200
committerDanny Baumann <dannybaumann@web.de>2016-10-20 16:44:25 +0200
commitac7b58ec1c8b07537960bfafe40e31ddc9a94719 (patch)
treeee40ffee4e20ddc0cbfa6a64827b445a4d05ff0d /services
parente05eda22dd6d2e4834b5ff2b364d4258ad590f3e (diff)
downloadframeworks_base-ac7b58ec1c8b07537960bfafe40e31ddc9a94719.zip
frameworks_base-ac7b58ec1c8b07537960bfafe40e31ddc9a94719.tar.gz
frameworks_base-ac7b58ec1c8b07537960bfafe40e31ddc9a94719.tar.bz2
Support enforcing a minimum delay between notification sounds of an app.
Useful e.g. for messenger apps. Change-Id: If8e8cc9e2f02d70537c1f9dc14f22bbd0ec1e9a6
Diffstat (limited to 'services')
-rw-r--r--services/core/java/com/android/server/notification/NotificationManagerService.java47
-rw-r--r--services/core/java/com/android/server/notification/RankingHelper.java25
2 files changed, 71 insertions, 1 deletions
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 43efddd..b2b6580 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -76,6 +76,7 @@ import android.os.Looper;
import android.os.Message;
import android.os.Process;
import android.os.RemoteException;
+import android.os.SystemClock;
import android.os.SystemProperties;
import android.os.UserHandle;
import android.os.UserManager;
@@ -100,6 +101,7 @@ import android.util.Log;
import android.util.LruCache;
import android.util.Slog;
import android.util.SparseIntArray;
+import android.util.TimeUtils;
import android.util.Xml;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityManager;
@@ -302,6 +304,7 @@ public class NotificationManagerService extends SystemService {
new ArrayMap<String, NotificationRecord>();
final ArrayList<ToastRecord> mToastQueue = new ArrayList<ToastRecord>();
final ArrayMap<String, NotificationRecord> mSummaryByGroupKey = new ArrayMap<>();
+ final ArrayMap<String, Long> mLastSoundTimestamps = new ArrayMap<>();
final PolicyAccess mPolicyAccess = new PolicyAccess();
// The last key in this list owns the hardware.
@@ -1595,6 +1598,19 @@ public class NotificationManagerService extends SystemService {
return mRankingHelper.getShowNotificationForPackageOnKeyguard(pkg, uid);
}
+ @Override
+ public void setPackageNotificationSoundTimeout(String pkg, int uid, long timeout) {
+ checkCallerIsSystem();
+ mRankingHelper.setPackageNotificationSoundTimeout(pkg, uid, timeout);
+ savePolicyFile();
+ }
+
+ @Override
+ public long getPackageNotificationSoundTimeout(String pkg, int uid) {
+ checkCallerIsSystem();
+ return mRankingHelper.getPackageNotificationSoundTimeout(pkg, uid);
+ }
+
/**
* System-only API for getting a list of current (i.e. not cleared) notifications.
*
@@ -2317,6 +2333,14 @@ public class NotificationManagerService extends SystemService {
} catch (NameNotFoundException e) {
// pass
}
+
+ long now = SystemClock.elapsedRealtime();
+ pw.println("\n Last notification sound timestamps:");
+ for (Map.Entry<String, Long> entry: mLastSoundTimestamps.entrySet()) {
+ pw.print(" " + entry.getKey() + " -> ");
+ TimeUtils.formatDuration(entry.getValue(), now, pw);
+ pw.println(" ago");
+ }
}
}
@@ -2705,6 +2729,7 @@ public class NotificationManagerService extends SystemService {
&& (record.getUserId() == UserHandle.USER_ALL ||
record.getUserId() == currentUser ||
mUserProfiles.isCurrentProfile(record.getUserId()))
+ && !isInSoundTimeoutPeriod(record)
&& mSystemReady
&& mAudioManager != null;
@@ -2835,6 +2860,10 @@ public class NotificationManagerService extends SystemService {
} else if (wasShowLights) {
updateLightsLocked();
}
+ if (buzz || beep) {
+ mLastSoundTimestamps.put(generateLastSoundTimeoutKey(record),
+ SystemClock.elapsedRealtime());
+ }
if (buzz || beep || blink) {
EventLogTags.writeNotificationAlert(record.getKey(),
buzz ? 1 : 0, beep ? 1 : 0, blink ? 1 : 0);
@@ -2842,6 +2871,24 @@ public class NotificationManagerService extends SystemService {
}
}
+ private boolean isInSoundTimeoutPeriod(NotificationRecord record) {
+ long timeoutMillis = mRankingHelper.getPackageNotificationSoundTimeout(
+ record.sbn.getPackageName(), record.sbn.getUid());
+ if (timeoutMillis == 0) {
+ return false;
+ }
+
+ Long value = mLastSoundTimestamps.get(generateLastSoundTimeoutKey(record));
+ if (value == null) {
+ return false;
+ }
+ return SystemClock.elapsedRealtime() - value < timeoutMillis;
+ }
+
+ private String generateLastSoundTimeoutKey(NotificationRecord record) {
+ return record.sbn.getPackageName() + "|" + record.sbn.getUid();
+ }
+
private static AudioAttributes audioAttributesForNotification(Notification n) {
if (n.audioAttributes != null
&& !Notification.AUDIO_ATTRIBUTES_DEFAULT.equals(n.audioAttributes)) {
diff --git a/services/core/java/com/android/server/notification/RankingHelper.java b/services/core/java/com/android/server/notification/RankingHelper.java
index 5112370..233eb0a 100644
--- a/services/core/java/com/android/server/notification/RankingHelper.java
+++ b/services/core/java/com/android/server/notification/RankingHelper.java
@@ -52,6 +52,7 @@ public class RankingHelper implements RankingConfig {
private static final String ATT_PEEKABLE = "peekable";
private static final String ATT_VISIBILITY = "visibility";
private static final String ATT_KEYGUARD = "keyguard";
+ private static final String ATT_SOUND_TIMEOUT = "sound-timeout";
private static final int DEFAULT_PRIORITY = Notification.PRIORITY_DEFAULT;
private static final boolean DEFAULT_PEEKABLE = true;
@@ -146,6 +147,7 @@ public class RankingHelper implements RankingConfig {
int vis = safeInt(parser, ATT_VISIBILITY, DEFAULT_VISIBILITY);
int keyguard = safeInt(parser, ATT_KEYGUARD,
Notification.SHOW_ALL_NOTI_ON_KEYGUARD);
+ long soundTimeout = safeInt(parser, ATT_SOUND_TIMEOUT, 0);
String name = parser.getAttributeValue(null, ATT_NAME);
if (!TextUtils.isEmpty(name)) {
@@ -178,6 +180,9 @@ public class RankingHelper implements RankingConfig {
if (keyguard != Notification.SHOW_ALL_NOTI_ON_KEYGUARD) {
r.keyguard = keyguard;
}
+ if (soundTimeout != 0) {
+ r.notificationSoundTimeout = soundTimeout;
+ }
}
}
}
@@ -207,7 +212,8 @@ public class RankingHelper implements RankingConfig {
final Record r = mRecords.valueAt(i);
if (r.priority == DEFAULT_PRIORITY && r.peekable == DEFAULT_PEEKABLE
&& r.visibility == DEFAULT_VISIBILITY
- && r.keyguard == Notification.SHOW_ALL_NOTI_ON_KEYGUARD) {
+ && r.keyguard == Notification.SHOW_ALL_NOTI_ON_KEYGUARD
+ && r.notificationSoundTimeout == 0) {
mRecords.removeAt(i);
}
}
@@ -237,6 +243,9 @@ public class RankingHelper implements RankingConfig {
if (r.keyguard != Notification.SHOW_ALL_NOTI_ON_KEYGUARD) {
out.attribute(null, ATT_KEYGUARD, Integer.toBinaryString(r.keyguard));
}
+ if (r.notificationSoundTimeout != 0) {
+ out.attribute(null, ATT_SOUND_TIMEOUT, Long.toString(r.notificationSoundTimeout));
+ }
if (!forBackup) {
out.attribute(null, ATT_UID, Integer.toString(r.uid));
}
@@ -404,6 +413,19 @@ public class RankingHelper implements RankingConfig {
updateConfig();
}
+ public long getPackageNotificationSoundTimeout(String packageName, int uid) {
+ final Record r = mRecords.get(recordKey(packageName, uid));
+ return r != null ? r.notificationSoundTimeout : 0;
+ }
+
+ public void setPackageNotificationSoundTimeout(String packageName, int uid, long timeout) {
+ if (timeout == getPackageNotificationSoundTimeout(packageName, uid)) {
+ return;
+ }
+ getOrCreateRecord(packageName, uid).notificationSoundTimeout = timeout;
+ removeDefaultRecords();
+ }
+
public void dump(PrintWriter pw, String prefix, NotificationManagerService.DumpFilter filter) {
if (filter == null) {
final int N = mSignalExtractors.length;
@@ -487,6 +509,7 @@ public class RankingHelper implements RankingConfig {
boolean peekable = DEFAULT_PEEKABLE;
int visibility = DEFAULT_VISIBILITY;
int keyguard = Notification.SHOW_ALL_NOTI_ON_KEYGUARD;
+ long notificationSoundTimeout = 0;
}
}