Ignore new vibrations for ongoing alarm vibrations

The current check to ignore incoming vibrations in favor of ongoing
alarm vibrations is relying on the fact that the alarm vibration is
repeating.

This cl also adds a check for the vibration attributes usage.

Fix: 182369095
Test: atest VibratorManagerServiceTest
Change-Id: I07113ba2c7b1f8005c27466a80651f0f19699d68
This commit is contained in:
Lais Andrade
2021-03-29 17:01:46 +00:00
parent 80348b5baf
commit b72bec1869
2 changed files with 75 additions and 18 deletions

View File

@@ -603,11 +603,20 @@ public class VibratorManagerService extends IVibratorManagerService.Stub {
// Repeating vibrations always take precedence.
return null;
}
if (mCurrentVibration != null && mCurrentVibration.getVibration().isRepeating()) {
if (DEBUG) {
Slog.d(TAG, "Ignoring incoming vibration in favor of previous alarm vibration");
if (mCurrentVibration != null) {
if (mCurrentVibration.getVibration().attrs.getUsage()
== VibrationAttributes.USAGE_ALARM) {
if (DEBUG) {
Slog.d(TAG, "Ignoring incoming vibration in favor of alarm vibration");
}
return Vibration.Status.IGNORED_FOR_ALARM;
}
if (mCurrentVibration.getVibration().isRepeating()) {
if (DEBUG) {
Slog.d(TAG, "Ignoring incoming vibration in favor of repeating vibration");
}
return Vibration.Status.IGNORED_FOR_ONGOING;
}
return Vibration.Status.IGNORED_FOR_ALARM;
}
return null;
}

View File

@@ -565,6 +565,54 @@ public class VibratorManagerServiceTest {
eq(AudioAttributes.USAGE_UNKNOWN), anyInt(), anyString());
}
@Test
public void vibrate_withOngoingRepeatingVibration_ignoresEffect() throws Exception {
mockVibrators(1);
mVibratorProviders.get(1).setCapabilities(IVibrator.CAP_AMPLITUDE_CONTROL);
VibratorManagerService service = createSystemReadyService();
VibrationEffect repeatingEffect = VibrationEffect.createWaveform(
new long[]{10_000, 10_000}, new int[]{128, 255}, 1);
vibrate(service, repeatingEffect, new VibrationAttributes.Builder().setUsage(
VibrationAttributes.USAGE_UNKNOWN).build());
// VibrationThread will start this vibration async, so wait before checking it started.
assertTrue(waitUntil(s -> !mVibratorProviders.get(1).getEffectSegments().isEmpty(),
service, TEST_TIMEOUT_MILLIS));
vibrate(service, VibrationEffect.get(VibrationEffect.EFFECT_CLICK),
new VibrationAttributes.Builder().setUsage(
VibrationAttributes.USAGE_TOUCH).build());
// Wait before checking it never played a second effect.
assertFalse(waitUntil(s -> mVibratorProviders.get(1).getEffectSegments().size() > 1,
service, /* timeout= */ 50));
}
@Test
public void vibrate_withOngoingAlarmVibration_ignoresEffect() throws Exception {
mockVibrators(1);
mVibratorProviders.get(1).setCapabilities(IVibrator.CAP_AMPLITUDE_CONTROL);
VibratorManagerService service = createSystemReadyService();
VibrationEffect alarmEffect = VibrationEffect.createWaveform(
new long[]{10_000, 10_000}, new int[]{128, 255}, -1);
vibrate(service, alarmEffect, new VibrationAttributes.Builder().setUsage(
VibrationAttributes.USAGE_ALARM).build());
// VibrationThread will start this vibration async, so wait before checking it started.
assertTrue(waitUntil(s -> !mVibratorProviders.get(1).getEffectSegments().isEmpty(),
service, TEST_TIMEOUT_MILLIS));
vibrate(service, VibrationEffect.get(VibrationEffect.EFFECT_CLICK),
new VibrationAttributes.Builder().setUsage(
VibrationAttributes.USAGE_TOUCH).build());
// Wait before checking it never played a second effect.
assertFalse(waitUntil(s -> mVibratorProviders.get(1).getEffectSegments().size() > 1,
service, /* timeout= */ 50));
}
@Test
public void vibrate_withInputDevices_vibratesInputDevices() throws Exception {
mockVibrators(1);
@@ -761,22 +809,22 @@ public class VibratorManagerServiceTest {
fakeVibrator.setSupportedEffects(VibrationEffect.EFFECT_CLICK);
VibratorManagerService service = createSystemReadyService();
vibrate(service, CombinedVibrationEffect.startSynced()
.addVibrator(1, VibrationEffect.get(VibrationEffect.EFFECT_CLICK))
.combine(), ALARM_ATTRS);
assertTrue(waitUntil(s -> fakeVibrator.getEffectSegments().size() == 1,
service, TEST_TIMEOUT_MILLIS));
vibrate(service, CombinedVibrationEffect.startSequential()
.addNext(1, VibrationEffect.createOneShot(20, 100))
.combine(), NOTIFICATION_ATTRS);
assertTrue(waitUntil(s -> fakeVibrator.getEffectSegments().size() == 2,
assertTrue(waitUntil(s -> fakeVibrator.getEffectSegments().size() == 1,
service, TEST_TIMEOUT_MILLIS));
vibrate(service, VibrationEffect.startComposition()
.addPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK, 1f)
.addPrimitive(VibrationEffect.Composition.PRIMITIVE_TICK, 0.5f)
.compose(), HAPTIC_FEEDBACK_ATTRS);
assertTrue(waitUntil(s -> fakeVibrator.getEffectSegments().size() == 3,
service, TEST_TIMEOUT_MILLIS));
vibrate(service, CombinedVibrationEffect.startSynced()
.addVibrator(1, VibrationEffect.get(VibrationEffect.EFFECT_CLICK))
.combine(), ALARM_ATTRS);
assertTrue(waitUntil(s -> fakeVibrator.getEffectSegments().size() == 4,
service, TEST_TIMEOUT_MILLIS));
@@ -785,17 +833,17 @@ public class VibratorManagerServiceTest {
assertEquals(4, fakeVibrator.getEffectSegments().size());
assertEquals(1, fakeVibrator.getAmplitudes().size());
// Alarm vibration is always VIBRATION_INTENSITY_HIGH.
PrebakedSegment expected = new PrebakedSegment(
VibrationEffect.EFFECT_CLICK, false, VibrationEffect.EFFECT_STRENGTH_STRONG);
assertEquals(expected, fakeVibrator.getEffectSegments().get(0));
// Notification vibrations will be scaled with SCALE_VERY_HIGH.
assertTrue(0.6 < fakeVibrator.getAmplitudes().get(0));
// Haptic feedback vibrations will be scaled with SCALE_LOW.
assertTrue(0.5 < ((PrimitiveSegment) fakeVibrator.getEffectSegments().get(2)).getScale());
assertTrue(0.5 > ((PrimitiveSegment) fakeVibrator.getEffectSegments().get(3)).getScale());
assertTrue(0.5 < ((PrimitiveSegment) fakeVibrator.getEffectSegments().get(1)).getScale());
assertTrue(0.5 > ((PrimitiveSegment) fakeVibrator.getEffectSegments().get(2)).getScale());
// Alarm vibration is always VIBRATION_INTENSITY_HIGH.
PrebakedSegment expected = new PrebakedSegment(
VibrationEffect.EFFECT_CLICK, false, VibrationEffect.EFFECT_STRENGTH_STRONG);
assertEquals(expected, fakeVibrator.getEffectSegments().get(3));
// Ring vibrations have intensity OFF and are not played.
}