Skip to content

Commit cef13ca

Browse files
committed
fixup! Support forwarding notification
1 parent 32f3b7d commit cef13ca

File tree

4 files changed

+86
-27
lines changed

4 files changed

+86
-27
lines changed

services/core/java/com/android/server/notification/AlertRateLimiter.java

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,24 @@ public class AlertRateLimiter {
2424
static final long ALLOWED_ALERT_INTERVAL = 1000;
2525
private long mLastNotificationMillis = 0;
2626

27-
boolean shouldRateLimitAlert(long now) {
27+
boolean shouldRateLimitAlert(long now) {
28+
boolean isRateLimited = isAlertRateLimited(now);
29+
if (isRateLimited) {
30+
return true;
31+
}
32+
mLastNotificationMillis = now;
33+
return false;
34+
}
35+
36+
boolean wasAlertRateLimited() {
37+
return isAlertRateLimited(mLastNotificationMillis);
38+
}
39+
40+
boolean isAlertRateLimited(long now) {
2841
final long millisSinceLast = now - mLastNotificationMillis;
2942
if (millisSinceLast < 0 || millisSinceLast < ALLOWED_ALERT_INTERVAL) {
3043
return true;
3144
}
32-
mLastNotificationMillis = now;
3345
return false;
3446
}
3547
}

services/core/java/com/android/server/notification/NotificationAttentionHelper.java

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -636,8 +636,21 @@ boolean isCurrentlyInsistent() {
636636
mNMP.getNotificationByKey(mVibrateNotificationKey));
637637
}
638638

639+
record MuteReasonFetchingParam(boolean shouldGetMuteReasonOnly) {
640+
static MuteReasonFetchingParam of(boolean shouldGetMuteReasonOnly) {
641+
return new MuteReasonFetchingParam(shouldGetMuteReasonOnly);
642+
}
643+
}
644+
639645
@MuteReason int shouldMuteNotificationLocked(final NotificationRecord record,
640646
final Signals signals, boolean hasAudibleAlert) {
647+
return shouldMuteNotificationLocked(record, signals, hasAudibleAlert,
648+
MuteReasonFetchingParam.of(false));
649+
}
650+
651+
@MuteReason int shouldMuteNotificationLocked(
652+
final NotificationRecord record, final Signals signals, boolean hasAudibleAlert,
653+
final MuteReasonFetchingParam muteReasonFetchingParam) {
641654
// Suppressed because no audible alert
642655
if (!hasAudibleAlert) {
643656
return MUTE_REASON_NOT_AUDIBLE;
@@ -681,9 +694,16 @@ boolean isCurrentlyInsistent() {
681694

682695
// Suppressed for being too recently noisy
683696
final String pkg = record.getSbn().getPackageName();
684-
if (mUsageStats.isAlertRateLimited(pkg)) {
685-
Slog.e(TAG, "Muting recently noisy " + record.getKey());
686-
return MUTE_REASON_RATE_LIMIT;
697+
if (muteReasonFetchingParam.shouldGetMuteReasonOnly()) {
698+
if (mUsageStats.wasAlertRecentlyRateLimited(pkg)) {
699+
Slog.i(TAG, "Recently noisy: " + record.getKey() + ", reason: was muted");
700+
return MUTE_REASON_RATE_LIMIT;
701+
}
702+
} else {
703+
if (mUsageStats.isAlertRateLimited(pkg)) {
704+
Slog.e(TAG, "Muting recently noisy " + record.getKey());
705+
return MUTE_REASON_RATE_LIMIT;
706+
}
687707
}
688708

689709
// A different looping ringtone, such as an incoming call is playing
@@ -704,7 +724,9 @@ boolean isCurrentlyInsistent() {
704724
if (isPoliteNotificationFeatureEnabled(record)) {
705725
// Notify the politeness strategy that an alerting notification is posted
706726
if (!isInsistentUpdate(record)) {
707-
mStrategy.onNotificationPosted(record);
727+
if (!muteReasonFetchingParam.shouldGetMuteReasonOnly()) {
728+
mStrategy.onNotificationPosted(record);
729+
}
708730
}
709731

710732
// Suppress if politeness is muted and it's not an update for insistent
@@ -1027,7 +1049,7 @@ boolean canShowLightsLocked(final NotificationRecord record, final Signals signa
10271049
return true;
10281050
}
10291051

1030-
String disableNotificationEffects(NotificationRecord record, int listenerHints) {
1052+
private String disableNotificationEffects(NotificationRecord record, int listenerHints) {
10311053
if (mDisableNotificationEffects) {
10321054
return "booleanState";
10331055
}

services/core/java/com/android/server/notification/NotificationManagerService.java

Lines changed: 30 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -9731,29 +9731,35 @@ private CensoredSendState getCensoredSendStateForNotification(NotificationRecord
97319731
return CensoredSendState.DONT_SEND;
97329732
}
97339733

9734-
// Handles reoccurring update notifications (fixes issues like status update spamming).
9735-
if (record.isUpdate && (record.getNotification().flags & FLAG_ONLY_ALERT_ONCE) != 0) {
9736-
if (DBG) Slog.d(TAG, "not sending censored notif due to original being " +
9737-
"an update that only alerts once");
9738-
return CensoredSendState.DONT_SEND;
9739-
}
9740-
9741-
// Muted by listener
9742-
final String disableEffects = mAttentionHelper.disableNotificationEffects(record, mListenerHints);
9743-
if (disableEffects != null) {
9744-
if (DBG) Slog.d(TAG, "not sending censored notif due to disableEffects");
9734+
final var signals = new NotificationAttentionHelper.Signals(false, mListenerHints);
9735+
final Uri soundUri = record.getSound();
9736+
final boolean hasValidSound = soundUri != null && !Uri.EMPTY.equals(soundUri);
9737+
final boolean hasValidVibrate = record.getVibration() != null;
9738+
@NotificationAttentionHelper.MuteReason
9739+
final int muteReason = mAttentionHelper.shouldMuteNotificationLocked(record, signals,
9740+
hasValidSound || hasValidVibrate,
9741+
NotificationAttentionHelper.MuteReasonFetchingParam.of(true));
9742+
if (DBG) Slog.d(TAG, "acquired mute reason: " + muteReason +
9743+
" for querying most noisy censored send state possible");
9744+
final CensoredSendState mostNoisyCensoredSendStateAllowed = switch (muteReason) {
9745+
// Do Not Disturb checks is done separately, see later comments.
9746+
case NotificationAttentionHelper.MUTE_REASON_DND,
9747+
NotificationAttentionHelper.MUTE_REASON_NOT_MUTED
9748+
-> CensoredSendState.SEND_NORMAL;
9749+
case NotificationAttentionHelper.MUTE_REASON_SILENT_UPDATE,
9750+
NotificationAttentionHelper.MUTE_REASON_LISTENER_HINT,
9751+
NotificationAttentionHelper.MUTE_REASON_GROUP_ALERT
9752+
-> {
9753+
yield CensoredSendState.DONT_SEND;
9754+
}
9755+
default -> CensoredSendState.SEND_QUIET;
9756+
};
9757+
if (mostNoisyCensoredSendStateAllowed == CensoredSendState.DONT_SEND) {
9758+
if (DBG) Slog.d(TAG, "not sending censored notif: original notif is muted " +
9759+
"with reason ineligible for forwarding");
97459760
return CensoredSendState.DONT_SEND;
97469761
}
97479762

9748-
// Suppressed because another notification in its group handles alerting
9749-
if (record.getSbn().isGroup()) {
9750-
if (record.getNotification().suppressAlertingDueToGrouping()) {
9751-
if (DBG) Slog.d(TAG, "not sending censored notif due another" +
9752-
"notification in its group handles alerting");
9753-
return CensoredSendState.DONT_SEND;
9754-
}
9755-
}
9756-
97579763
// Check lock screen display settings.
97589764
if (!shouldShowNotificationOnKeyguardForUser(userId, record)) {
97599765
if (DBG) Slog.d(TAG, "not sending censored notif due lock screen settings");
@@ -9776,6 +9782,10 @@ private CensoredSendState getCensoredSendStateForNotification(NotificationRecord
97769782
if (DBG) Slog.d(TAG, "using SEND_QUIET");
97779783
return CensoredSendState.SEND_QUIET;
97789784
}
9785+
if (mostNoisyCensoredSendStateAllowed == CensoredSendState.SEND_QUIET) {
9786+
if (DBG) Slog.d(TAG, "using SEND_QUIET");
9787+
return CensoredSendState.SEND_QUIET;
9788+
}
97799789
return CensoredSendState.SEND_NORMAL;
97809790
case DONT_SEND: // fall through
97819791
default:

services/core/java/com/android/server/notification/NotificationUsageStats.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,17 @@ public synchronized boolean isAlertRateLimited(String packageName) {
110110
return stats.isAlertRateLimited();
111111
}
112112

113+
/**
114+
* Query when a notification wants to alert based on existing stats.
115+
*/
116+
public synchronized boolean wasAlertRecentlyRateLimited(String packageName) {
117+
AggregatedStats stats = mStats.get(packageName);
118+
if (stats == null) {
119+
return false;
120+
}
121+
return stats.wasAlertRateLimited();
122+
}
123+
113124
/**
114125
* Called when a notification is tentatively enqueued by an app, before rate checking.
115126
*/
@@ -615,6 +626,10 @@ public void updateInterarrivalEstimate(long now) {
615626
enqueueRate.update(now);
616627
}
617628

629+
public boolean wasAlertRateLimited() {
630+
return alertRate.wasAlertRateLimited();
631+
}
632+
618633
public boolean isAlertRateLimited() {
619634
boolean limited = alertRate.shouldRateLimitAlert(SystemClock.elapsedRealtime());
620635
if (limited) {

0 commit comments

Comments
 (0)