Loading services/core/java/com/android/server/notification/NotificationManagerService.java +31 −12 Original line number Diff line number Diff line Loading @@ -3714,7 +3714,7 @@ public class NotificationManagerService extends SystemService { if (!mInCall && hasValidVibrate && !ringerModeSilent) { mVibrateNotificationKey = key; buzz = playVibration(record, vibration); buzz = playVibration(record, vibration, hasValidSound); } } } Loading Loading @@ -3788,22 +3788,41 @@ public class NotificationManagerService extends SystemService { return false; } private boolean playVibration(final NotificationRecord record, long[] vibration) { private boolean playVibration(final NotificationRecord record, long[] vibration, boolean delayVibForSound) { // Escalate privileges so we can use the vibrator even if the // notifying app does not have the VIBRATE permission. long identity = Binder.clearCallingIdentity(); try { final VibrationEffect effect; try { final boolean insistent = (record.getNotification().flags & Notification.FLAG_INSISTENT) != 0; final VibrationEffect effect = VibrationEffect.createWaveform( effect = VibrationEffect.createWaveform( vibration, insistent ? 0 : -1 /*repeatIndex*/); mVibrator.vibrate(record.sbn.getUid(), record.sbn.getOpPkg(), effect, record.getAudioAttributes()); return true; } catch (IllegalArgumentException e) { Slog.e(TAG, "Error creating vibration waveform with pattern: " + Arrays.toString(vibration)); return false; } if (delayVibForSound) { new Thread(() -> { // delay the vibration by the same amount as the notification sound final int waitMs = mAudioManager.getFocusRampTimeMs( AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK, record.getAudioAttributes()); if (DBG) Slog.v(TAG, "Delaying vibration by " + waitMs + "ms"); try { Thread.sleep(waitMs); } catch (InterruptedException e) { } mVibrator.vibrate(record.sbn.getUid(), record.sbn.getOpPkg(), effect, record.getAudioAttributes()); }).start(); } else { mVibrator.vibrate(record.sbn.getUid(), record.sbn.getOpPkg(), effect, record.getAudioAttributes()); } return true; } finally{ Binder.restoreCallingIdentity(identity); } Loading services/tests/notification/src/com/android/server/notification/BuzzBeepBlinkTest.java +12 −5 Original line number Diff line number Diff line Loading @@ -61,6 +61,7 @@ import static org.mockito.Matchers.anyString; import static org.mockito.Matchers.argThat; import static org.mockito.Matchers.eq; import static org.mockito.Mockito.never; import static org.mockito.Mockito.timeout; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; Loading Loading @@ -102,6 +103,7 @@ public class BuzzBeepBlinkTest extends NotificationTestCase { private static final long[] FALLBACK_VIBRATION_PATTERN = new long[] {100, 100, 100}; private static final VibrationEffect FALLBACK_VIBRATION = VibrationEffect.createWaveform(FALLBACK_VIBRATION_PATTERN, -1); private static final int MAX_VIBRATION_DELAY = 1000; @Before public void setUp() { Loading Loading @@ -309,6 +311,11 @@ public class BuzzBeepBlinkTest extends NotificationTestCase { (AudioAttributes) anyObject()); } private void verifyDelayedVibrateLooped() { verify(mVibrator, timeout(MAX_VIBRATION_DELAY).times(1)).vibrate(anyInt(), anyString(), argThat(mVibrateLoopMatcher), (AudioAttributes) anyObject()); } private void verifyStopVibrate() { verify(mVibrator, times(1)).cancel(); } Loading Loading @@ -506,8 +513,8 @@ public class BuzzBeepBlinkTest extends NotificationTestCase { VibrationEffect effect = VibrationEffect.createWaveform(r.getVibration(), -1); verify(mVibrator, times(1)).vibrate(anyInt(), anyString(), eq(effect), (AudioAttributes) anyObject()); verify(mVibrator, timeout(MAX_VIBRATION_DELAY).times(1)).vibrate(anyInt(), anyString(), eq(effect), (AudioAttributes) anyObject()); } @Test Loading @@ -521,8 +528,8 @@ public class BuzzBeepBlinkTest extends NotificationTestCase { mService.buzzBeepBlinkLocked(r); verify(mVibrator, times(1)).vibrate(anyInt(), anyString(), eq(FALLBACK_VIBRATION), (AudioAttributes) anyObject()); verify(mVibrator, timeout(MAX_VIBRATION_DELAY).times(1)).vibrate(anyInt(), anyString(), eq(FALLBACK_VIBRATION), (AudioAttributes) anyObject()); verify(mRingtonePlayer, never()).playAsync (anyObject(), anyObject(), anyBoolean(), anyObject()); } Loading @@ -539,7 +546,7 @@ public class BuzzBeepBlinkTest extends NotificationTestCase { mService.buzzBeepBlinkLocked(r); verifyVibrateLooped(); verifyDelayedVibrateLooped(); } @Test Loading Loading
services/core/java/com/android/server/notification/NotificationManagerService.java +31 −12 Original line number Diff line number Diff line Loading @@ -3714,7 +3714,7 @@ public class NotificationManagerService extends SystemService { if (!mInCall && hasValidVibrate && !ringerModeSilent) { mVibrateNotificationKey = key; buzz = playVibration(record, vibration); buzz = playVibration(record, vibration, hasValidSound); } } } Loading Loading @@ -3788,22 +3788,41 @@ public class NotificationManagerService extends SystemService { return false; } private boolean playVibration(final NotificationRecord record, long[] vibration) { private boolean playVibration(final NotificationRecord record, long[] vibration, boolean delayVibForSound) { // Escalate privileges so we can use the vibrator even if the // notifying app does not have the VIBRATE permission. long identity = Binder.clearCallingIdentity(); try { final VibrationEffect effect; try { final boolean insistent = (record.getNotification().flags & Notification.FLAG_INSISTENT) != 0; final VibrationEffect effect = VibrationEffect.createWaveform( effect = VibrationEffect.createWaveform( vibration, insistent ? 0 : -1 /*repeatIndex*/); mVibrator.vibrate(record.sbn.getUid(), record.sbn.getOpPkg(), effect, record.getAudioAttributes()); return true; } catch (IllegalArgumentException e) { Slog.e(TAG, "Error creating vibration waveform with pattern: " + Arrays.toString(vibration)); return false; } if (delayVibForSound) { new Thread(() -> { // delay the vibration by the same amount as the notification sound final int waitMs = mAudioManager.getFocusRampTimeMs( AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK, record.getAudioAttributes()); if (DBG) Slog.v(TAG, "Delaying vibration by " + waitMs + "ms"); try { Thread.sleep(waitMs); } catch (InterruptedException e) { } mVibrator.vibrate(record.sbn.getUid(), record.sbn.getOpPkg(), effect, record.getAudioAttributes()); }).start(); } else { mVibrator.vibrate(record.sbn.getUid(), record.sbn.getOpPkg(), effect, record.getAudioAttributes()); } return true; } finally{ Binder.restoreCallingIdentity(identity); } Loading
services/tests/notification/src/com/android/server/notification/BuzzBeepBlinkTest.java +12 −5 Original line number Diff line number Diff line Loading @@ -61,6 +61,7 @@ import static org.mockito.Matchers.anyString; import static org.mockito.Matchers.argThat; import static org.mockito.Matchers.eq; import static org.mockito.Mockito.never; import static org.mockito.Mockito.timeout; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; Loading Loading @@ -102,6 +103,7 @@ public class BuzzBeepBlinkTest extends NotificationTestCase { private static final long[] FALLBACK_VIBRATION_PATTERN = new long[] {100, 100, 100}; private static final VibrationEffect FALLBACK_VIBRATION = VibrationEffect.createWaveform(FALLBACK_VIBRATION_PATTERN, -1); private static final int MAX_VIBRATION_DELAY = 1000; @Before public void setUp() { Loading Loading @@ -309,6 +311,11 @@ public class BuzzBeepBlinkTest extends NotificationTestCase { (AudioAttributes) anyObject()); } private void verifyDelayedVibrateLooped() { verify(mVibrator, timeout(MAX_VIBRATION_DELAY).times(1)).vibrate(anyInt(), anyString(), argThat(mVibrateLoopMatcher), (AudioAttributes) anyObject()); } private void verifyStopVibrate() { verify(mVibrator, times(1)).cancel(); } Loading Loading @@ -506,8 +513,8 @@ public class BuzzBeepBlinkTest extends NotificationTestCase { VibrationEffect effect = VibrationEffect.createWaveform(r.getVibration(), -1); verify(mVibrator, times(1)).vibrate(anyInt(), anyString(), eq(effect), (AudioAttributes) anyObject()); verify(mVibrator, timeout(MAX_VIBRATION_DELAY).times(1)).vibrate(anyInt(), anyString(), eq(effect), (AudioAttributes) anyObject()); } @Test Loading @@ -521,8 +528,8 @@ public class BuzzBeepBlinkTest extends NotificationTestCase { mService.buzzBeepBlinkLocked(r); verify(mVibrator, times(1)).vibrate(anyInt(), anyString(), eq(FALLBACK_VIBRATION), (AudioAttributes) anyObject()); verify(mVibrator, timeout(MAX_VIBRATION_DELAY).times(1)).vibrate(anyInt(), anyString(), eq(FALLBACK_VIBRATION), (AudioAttributes) anyObject()); verify(mRingtonePlayer, never()).playAsync (anyObject(), anyObject(), anyBoolean(), anyObject()); } Loading @@ -539,7 +546,7 @@ public class BuzzBeepBlinkTest extends NotificationTestCase { mService.buzzBeepBlinkLocked(r); verifyVibrateLooped(); verifyDelayedVibrateLooped(); } @Test Loading