diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java index f70ecd54c711e..ff7a8b63de79c 100644 --- a/services/core/java/com/android/server/notification/NotificationManagerService.java +++ b/services/core/java/com/android/server/notification/NotificationManagerService.java @@ -5000,8 +5000,17 @@ public class NotificationManagerService extends SystemService { try { Thread.sleep(waitMs); } catch (InterruptedException e) { } - mVibrator.vibrate(record.sbn.getUid(), record.sbn.getOpPkg(), - effect, record.getAudioAttributes()); + + // Notifications might be canceled before it actually vibrates due to waitMs, + // so need to check the notification still valide for vibrate. + synchronized (mNotificationLock) { + if (mNotificationsByKey.get(record.getKey()) != null) { + mVibrator.vibrate(record.sbn.getUid(), record.sbn.getOpPkg(), + effect, record.getAudioAttributes()); + } else { + Slog.e(TAG, "No vibration for canceled notification : " + record.getKey()); + } + } }).start(); } else { mVibrator.vibrate(record.sbn.getUid(), record.sbn.getOpPkg(), diff --git a/services/tests/uiservicestests/src/com/android/server/notification/BuzzBeepBlinkTest.java b/services/tests/uiservicestests/src/com/android/server/notification/BuzzBeepBlinkTest.java index bdba3d5cd6779..99d2b87c7c25a 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/BuzzBeepBlinkTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/BuzzBeepBlinkTest.java @@ -917,6 +917,22 @@ public class BuzzBeepBlinkTest extends UiServiceTestCase { assertFalse(s.isInterruptive()); } + @Test + public void testCanceledNoisyNeverVibrate() throws Exception { + NotificationRecord r = getBuzzyBeepyNotification(); + + final int waitMs = mAudioManager.getFocusRampTimeMs( + AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK, + r.getAudioAttributes()); + + mService.buzzBeepBlinkLocked(r); + mService.clearNotifications(); + + verifyNeverVibrate(); + Thread.sleep(waitMs); + verifyNeverVibrate(); + } + @Test public void testEmptyUriSoundTreatedAsNoSound() throws Exception { NotificationChannel channel = new NotificationChannel("test", "test", IMPORTANCE_HIGH);