Loading services/core/java/com/android/server/notification/NotificationManagerService.java +14 −3 Original line number Diff line number Diff line Loading @@ -7699,7 +7699,10 @@ public class NotificationManagerService extends SystemService { final int waitMs = mAudioManager.getFocusRampTimeMs( AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK, record.getAudioAttributes()); if (DBG) Slog.v(TAG, "Delaying vibration by " + waitMs + "ms"); if (DBG) { Slog.v(TAG, "Delaying vibration for notification " + record.getKey() + " by " + waitMs + "ms"); } try { Thread.sleep(waitMs); } catch (InterruptedException e) { } Loading @@ -7707,9 +7710,17 @@ public class NotificationManagerService extends SystemService { // so need to check the notification still valide for vibrate. synchronized (mNotificationLock) { if (mNotificationsByKey.get(record.getKey()) != null) { if (record.getKey().equals(mVibrateNotificationKey)) { vibrate(record, effect, true); } else { Slog.e(TAG, "No vibration for canceled notification : " if (DBG) { Slog.v(TAG, "No vibration for notification " + record.getKey() + ": a new notification is " + "vibrating, or effects were cleared while waiting"); } } } else { Slog.w(TAG, "No vibration for canceled notification " + record.getKey()); } } Loading services/tests/uiservicestests/src/com/android/server/notification/BuzzBeepBlinkTest.java +54 −4 Original line number Diff line number Diff line Loading @@ -32,7 +32,6 @@ 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; Loading @@ -40,6 +39,7 @@ import static org.mockito.Matchers.anyObject; import static org.mockito.Matchers.anyString; import static org.mockito.Matchers.argThat; import static org.mockito.Matchers.eq; import static org.mockito.Mockito.after; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.spy; Loading @@ -48,6 +48,7 @@ import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.annotation.SuppressLint; import android.app.ActivityManager; import android.app.KeyguardManager; import android.app.Notification; Loading @@ -73,7 +74,6 @@ 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; Loading Loading @@ -102,6 +102,7 @@ import java.util.Objects; @SmallTest @RunWith(AndroidJUnit4.class) @SuppressLint("GuardedBy") // It's ok for this test to access guarded methods from the service. public class BuzzBeepBlinkTest extends UiServiceTestCase { @Mock AudioManager mAudioManager; Loading Loading @@ -156,6 +157,7 @@ public class BuzzBeepBlinkTest extends UiServiceTestCase { when(mAudioManager.getRingtonePlayer()).thenReturn(mRingtonePlayer); when(mAudioManager.getStreamVolume(anyInt())).thenReturn(10); when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_NORMAL); when(mAudioManager.getFocusRampTimeMs(anyInt(), any(AudioAttributes.class))).thenReturn(50); when(mUsageStats.isAlertRateLimited(any())).thenReturn(false); when(mVibrator.hasFrequencyControl()).thenReturn(false); when(mKeyguardManager.isDeviceLocked(anyInt())).thenReturn(false); Loading Loading @@ -444,6 +446,11 @@ public class BuzzBeepBlinkTest extends UiServiceTestCase { timeout(MAX_VIBRATION_DELAY).times(1)); } private void verifyDelayedNeverVibrate() { verify(mVibrator, after(MAX_VIBRATION_DELAY).never()).vibrate(anyInt(), anyString(), any(), anyString(), any(AudioAttributes.class)); } private void verifyVibrate(ArgumentMatcher<VibrationEffect> effectMatcher, VerificationMode verification) { ArgumentCaptor<AudioAttributes> captor = ArgumentCaptor.forClass(AudioAttributes.class); Loading Loading @@ -1588,8 +1595,51 @@ public class BuzzBeepBlinkTest extends UiServiceTestCase { // beep wasn't reset verifyNeverBeep(); verifyNeverVibrate(); verify(mRingtonePlayer, never()).stopAsync(); verify(mVibrator, never()).cancel(); verifyNeverStopAudio(); verifyNeverStopVibrate(); } @Test public void testRingtoneInsistentBeep_clearEffectsStopsSoundAndVibration() 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(); mService.clearSoundLocked(); mService.clearVibrateLocked(); verifyStopAudio(); verifyStopVibrate(); } @Test public void testRingtoneInsistentBeep_neverVibratesWhenEffectsClearedBeforeDelay() 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(); verifyNeverVibrate(); mService.clearSoundLocked(); mService.clearVibrateLocked(); verifyStopAudio(); verifyDelayedNeverVibrate(); } @Test Loading Loading
services/core/java/com/android/server/notification/NotificationManagerService.java +14 −3 Original line number Diff line number Diff line Loading @@ -7699,7 +7699,10 @@ public class NotificationManagerService extends SystemService { final int waitMs = mAudioManager.getFocusRampTimeMs( AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK, record.getAudioAttributes()); if (DBG) Slog.v(TAG, "Delaying vibration by " + waitMs + "ms"); if (DBG) { Slog.v(TAG, "Delaying vibration for notification " + record.getKey() + " by " + waitMs + "ms"); } try { Thread.sleep(waitMs); } catch (InterruptedException e) { } Loading @@ -7707,9 +7710,17 @@ public class NotificationManagerService extends SystemService { // so need to check the notification still valide for vibrate. synchronized (mNotificationLock) { if (mNotificationsByKey.get(record.getKey()) != null) { if (record.getKey().equals(mVibrateNotificationKey)) { vibrate(record, effect, true); } else { Slog.e(TAG, "No vibration for canceled notification : " if (DBG) { Slog.v(TAG, "No vibration for notification " + record.getKey() + ": a new notification is " + "vibrating, or effects were cleared while waiting"); } } } else { Slog.w(TAG, "No vibration for canceled notification " + record.getKey()); } } Loading
services/tests/uiservicestests/src/com/android/server/notification/BuzzBeepBlinkTest.java +54 −4 Original line number Diff line number Diff line Loading @@ -32,7 +32,6 @@ 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; Loading @@ -40,6 +39,7 @@ import static org.mockito.Matchers.anyObject; import static org.mockito.Matchers.anyString; import static org.mockito.Matchers.argThat; import static org.mockito.Matchers.eq; import static org.mockito.Mockito.after; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.spy; Loading @@ -48,6 +48,7 @@ import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.annotation.SuppressLint; import android.app.ActivityManager; import android.app.KeyguardManager; import android.app.Notification; Loading @@ -73,7 +74,6 @@ 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; Loading Loading @@ -102,6 +102,7 @@ import java.util.Objects; @SmallTest @RunWith(AndroidJUnit4.class) @SuppressLint("GuardedBy") // It's ok for this test to access guarded methods from the service. public class BuzzBeepBlinkTest extends UiServiceTestCase { @Mock AudioManager mAudioManager; Loading Loading @@ -156,6 +157,7 @@ public class BuzzBeepBlinkTest extends UiServiceTestCase { when(mAudioManager.getRingtonePlayer()).thenReturn(mRingtonePlayer); when(mAudioManager.getStreamVolume(anyInt())).thenReturn(10); when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_NORMAL); when(mAudioManager.getFocusRampTimeMs(anyInt(), any(AudioAttributes.class))).thenReturn(50); when(mUsageStats.isAlertRateLimited(any())).thenReturn(false); when(mVibrator.hasFrequencyControl()).thenReturn(false); when(mKeyguardManager.isDeviceLocked(anyInt())).thenReturn(false); Loading Loading @@ -444,6 +446,11 @@ public class BuzzBeepBlinkTest extends UiServiceTestCase { timeout(MAX_VIBRATION_DELAY).times(1)); } private void verifyDelayedNeverVibrate() { verify(mVibrator, after(MAX_VIBRATION_DELAY).never()).vibrate(anyInt(), anyString(), any(), anyString(), any(AudioAttributes.class)); } private void verifyVibrate(ArgumentMatcher<VibrationEffect> effectMatcher, VerificationMode verification) { ArgumentCaptor<AudioAttributes> captor = ArgumentCaptor.forClass(AudioAttributes.class); Loading Loading @@ -1588,8 +1595,51 @@ public class BuzzBeepBlinkTest extends UiServiceTestCase { // beep wasn't reset verifyNeverBeep(); verifyNeverVibrate(); verify(mRingtonePlayer, never()).stopAsync(); verify(mVibrator, never()).cancel(); verifyNeverStopAudio(); verifyNeverStopVibrate(); } @Test public void testRingtoneInsistentBeep_clearEffectsStopsSoundAndVibration() 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(); mService.clearSoundLocked(); mService.clearVibrateLocked(); verifyStopAudio(); verifyStopVibrate(); } @Test public void testRingtoneInsistentBeep_neverVibratesWhenEffectsClearedBeforeDelay() 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(); verifyNeverVibrate(); mService.clearSoundLocked(); mService.clearVibrateLocked(); verifyStopAudio(); verifyDelayedNeverVibrate(); } @Test Loading