Fix behavior of updates to insistent notifs

Do not cancel or restart the insistent ringtone,
but allow the original sound to continue playing.

Test: BuzzBeepBlinkTest
Fixes: 192071542
Change-Id: I8b988db82cbf3805fef389374fcadad36c7a062c
This commit is contained in:
Julia Reynolds
2021-08-25 09:35:31 -04:00
parent 0bacd2b473
commit dbdd55bab3
2 changed files with 63 additions and 13 deletions

View File

@@ -7449,15 +7449,21 @@ public class NotificationManagerService extends SystemService {
sentAccessibilityEvent = true;
}
if (DBG) Slog.v(TAG, "Interrupting!");
boolean isInsistentUpdate = isInsistentUpdate(record);
if (hasValidSound) {
if (isInCall()) {
playInCallNotification();
if (isInsistentUpdate) {
// don't reset insistent sound, it's jarring
beep = true;
} else {
beep = playSound(record, soundUri);
}
if(beep) {
mSoundNotificationKey = key;
if (isInCall()) {
playInCallNotification();
beep = true;
} else {
beep = playSound(record, soundUri);
}
if (beep) {
mSoundNotificationKey = key;
}
}
}
@@ -7465,9 +7471,13 @@ public class NotificationManagerService extends SystemService {
mAudioManager.getRingerModeInternal()
== AudioManager.RINGER_MODE_SILENT;
if (!isInCall() && hasValidVibrate && !ringerModeSilent) {
buzz = playVibration(record, vibration, hasValidSound);
if(buzz) {
mVibrateNotificationKey = key;
if (isInsistentUpdate) {
buzz = true;
} else {
buzz = playVibration(record, vibration, hasValidSound);
if (buzz) {
mVibrateNotificationKey = key;
}
}
}
} else if ((record.getFlags() & Notification.FLAG_INSISTENT) != 0) {
@@ -7570,6 +7580,19 @@ public class NotificationManagerService extends SystemService {
return true;
}
@GuardedBy("mNotificationLock")
boolean isInsistentUpdate(final NotificationRecord record) {
return (Objects.equals(record.getKey(), mSoundNotificationKey)
|| Objects.equals(record.getKey(), mVibrateNotificationKey))
&& isCurrentlyInsistent();
}
@GuardedBy("mNotificationLock")
boolean isCurrentlyInsistent() {
return isLoopingRingtoneNotification(mNotificationsByKey.get(mSoundNotificationKey))
|| isLoopingRingtoneNotification(mNotificationsByKey.get(mVibrateNotificationKey));
}
@GuardedBy("mNotificationLock")
boolean shouldMuteNotificationLocked(final NotificationRecord record) {
// Suppressed because it's a silent update
@@ -7609,10 +7632,8 @@ public class NotificationManagerService extends SystemService {
return true;
}
// A looping ringtone, such as an incoming call is playing
if (isLoopingRingtoneNotification(mNotificationsByKey.get(mSoundNotificationKey))
|| isLoopingRingtoneNotification(
mNotificationsByKey.get(mVibrateNotificationKey))) {
// A different looping ringtone, such as an incoming call is playing
if (isCurrentlyInsistent() && !isInsistentUpdate(record)) {
return true;
}

View File

@@ -32,6 +32,7 @@ import static junit.framework.Assert.assertTrue;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNotNull;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyBoolean;
import static org.mockito.Matchers.anyInt;
@@ -72,6 +73,7 @@ import android.provider.Settings;
import android.service.notification.NotificationListenerService;
import android.service.notification.StatusBarNotification;
import android.test.suitebuilder.annotation.SmallTest;
import android.util.Slog;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityManager;
import android.view.accessibility.IAccessibilityManager;
@@ -1182,6 +1184,7 @@ public class BuzzBeepBlinkTest extends UiServiceTestCase {
when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_VIBRATE);
mService.buzzBeepBlinkLocked(r);
verifyDelayedVibrate(mService.getVibratorHelper().createFallbackVibration(false));
// quiet update should stop making noise
mService.buzzBeepBlinkLocked(s);
@@ -1563,6 +1566,32 @@ public class BuzzBeepBlinkTest extends UiServiceTestCase {
assertEquals(-1, interrupter.getLastAudiblyAlertedMs());
}
@Test
public void testRingtoneInsistentBeep_canUpdate() throws Exception {
NotificationChannel ringtoneChannel =
new NotificationChannel("ringtone", "", IMPORTANCE_HIGH);
ringtoneChannel.setSound(Uri.fromParts("a", "b", "c"),
new AudioAttributes.Builder().setUsage(USAGE_NOTIFICATION_RINGTONE).build());
ringtoneChannel.enableVibration(true);
NotificationRecord ringtoneNotification = getCallRecord(1, ringtoneChannel, true);
mService.addNotification(ringtoneNotification);
assertFalse(mService.shouldMuteNotificationLocked(ringtoneNotification));
mService.buzzBeepBlinkLocked(ringtoneNotification);
verifyBeepLooped();
verifyDelayedVibrateLooped();
Mockito.reset(mVibrator);
Mockito.reset(mRingtonePlayer);
assertFalse(mService.shouldMuteNotificationLocked(ringtoneNotification));
mService.buzzBeepBlinkLocked(ringtoneNotification);
// beep wasn't reset
verifyNeverBeep();
verifyNeverVibrate();
verify(mRingtonePlayer, never()).stopAsync();
verify(mVibrator, never()).cancel();
}
@Test
public void testCannotInterruptRingtoneInsistentBuzz() {
NotificationChannel ringtoneChannel =