Loading core/java/android/os/SystemVibratorManager.java +1 −1 Original line number Diff line number Diff line Loading @@ -146,7 +146,7 @@ public class SystemVibratorManager extends VibratorManager { @Override public void cancel() { cancelVibration(/* usageFilter= */ -1); cancelVibration(VibrationAttributes.USAGE_FILTER_MATCH_ALL); } @Override Loading core/java/android/os/VibrationAttributes.java +5 −0 Original line number Diff line number Diff line Loading @@ -62,6 +62,11 @@ public final class VibrationAttributes implements Parcelable { @Retention(RetentionPolicy.SOURCE) public @interface Usage{} /** * Vibration usage filter value to match all usages. * @hide */ public static final int USAGE_FILTER_MATCH_ALL = -1; /** * Vibration usage class value to use when the vibration usage class is unknown. */ Loading services/core/java/com/android/server/vibrator/VibratorManagerService.java +7 −1 Original line number Diff line number Diff line Loading @@ -723,6 +723,12 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { * VibrationAttributes.USAGE_* values. */ private boolean shouldCancelVibration(VibrationAttributes attrs, int usageFilter) { if (attrs.getUsage() == VibrationAttributes.USAGE_UNKNOWN) { // Special case, usage UNKNOWN would match all filters. Instead it should only match if // it's cancelling that usage specifically, or if cancelling all usages. return usageFilter == VibrationAttributes.USAGE_UNKNOWN || usageFilter == VibrationAttributes.USAGE_FILTER_MATCH_ALL; } return (usageFilter & attrs.getUsage()) == attrs.getUsage(); } Loading Loading @@ -1535,7 +1541,7 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { } private int runCancel() { cancelVibrate(/* usageFilter= */ -1, mToken); cancelVibrate(VibrationAttributes.USAGE_FILTER_MATCH_ALL, mToken); return 0; } Loading services/tests/servicestests/src/com/android/server/vibrator/VibratorManagerServiceTest.java +36 −3 Original line number Diff line number Diff line Loading @@ -234,7 +234,7 @@ public class VibratorManagerServiceTest { CombinedVibration effect = CombinedVibration.createParallel( VibrationEffect.createPredefined(VibrationEffect.EFFECT_CLICK)); vibrate(service, effect, HAPTIC_FEEDBACK_ATTRS); service.cancelVibrate(/* usageFilter= */ -1, service); service.cancelVibrate(VibrationAttributes.USAGE_FILTER_MATCH_ALL, service); assertTrue(service.setAlwaysOnEffect(UID, PACKAGE_NAME, 1, effect, ALARM_ATTRS)); Loading Loading @@ -889,13 +889,13 @@ public class VibratorManagerServiceTest { mockVibrators(1); VibratorManagerService service = createSystemReadyService(); service.cancelVibrate(/* usageFilter= */ -1, service); service.cancelVibrate(VibrationAttributes.USAGE_FILTER_MATCH_ALL, service); assertFalse(service.isVibrating(1)); vibrate(service, VibrationEffect.createOneShot(10 * TEST_TIMEOUT_MILLIS, 100), ALARM_ATTRS); assertTrue(waitUntil(s -> s.isVibrating(1), service, TEST_TIMEOUT_MILLIS)); service.cancelVibrate(/* usageFilter= */ -1, service); service.cancelVibrate(VibrationAttributes.USAGE_FILTER_MATCH_ALL, service); assertTrue(waitUntil(s -> !s.isVibrating(1), service, TEST_TIMEOUT_MILLIS)); } Loading Loading @@ -924,6 +924,39 @@ public class VibratorManagerServiceTest { assertTrue(waitUntil(s -> !s.isVibrating(1), service, TEST_TIMEOUT_MILLIS)); } @Test public void cancelVibrate_withoutUnknownUsage_onlyStopsIfFilteringUnknownOrAllUsages() throws Exception { mockVibrators(1); VibrationAttributes attrs = new VibrationAttributes.Builder() .setUsage(VibrationAttributes.USAGE_UNKNOWN) .build(); VibratorManagerService service = createSystemReadyService(); vibrate(service, VibrationEffect.createOneShot(10 * TEST_TIMEOUT_MILLIS, 100), attrs); assertTrue(waitUntil(s -> s.isVibrating(1), service, TEST_TIMEOUT_MILLIS)); // Do not cancel UNKNOWN vibration when filter is being applied for other usages. service.cancelVibrate(VibrationAttributes.USAGE_RINGTONE, service); assertFalse(waitUntil(s -> !s.isVibrating(1), service, /* timeout= */ 50)); service.cancelVibrate( VibrationAttributes.USAGE_CLASS_ALARM | ~VibrationAttributes.USAGE_CLASS_MASK, service); assertFalse(waitUntil(s -> !s.isVibrating(1), service, /* timeout= */ 50)); // Cancel UNKNOWN vibration when filtered for that vibration specifically. service.cancelVibrate(VibrationAttributes.USAGE_UNKNOWN, service); assertTrue(waitUntil(s -> !s.isVibrating(1), service, TEST_TIMEOUT_MILLIS)); vibrate(service, VibrationEffect.createOneShot(10 * TEST_TIMEOUT_MILLIS, 100), attrs); assertTrue(waitUntil(s -> s.isVibrating(1), service, TEST_TIMEOUT_MILLIS)); // Cancel UNKNOWN vibration when all vibrations are being cancelled. service.cancelVibrate(VibrationAttributes.USAGE_FILTER_MATCH_ALL, service); assertTrue(waitUntil(s -> !s.isVibrating(1), service, TEST_TIMEOUT_MILLIS)); } private void mockCapabilities(long... capabilities) { when(mNativeWrapperMock.getCapabilities()).thenReturn( Arrays.stream(capabilities).reduce(0, (a, b) -> a | b)); Loading Loading
core/java/android/os/SystemVibratorManager.java +1 −1 Original line number Diff line number Diff line Loading @@ -146,7 +146,7 @@ public class SystemVibratorManager extends VibratorManager { @Override public void cancel() { cancelVibration(/* usageFilter= */ -1); cancelVibration(VibrationAttributes.USAGE_FILTER_MATCH_ALL); } @Override Loading
core/java/android/os/VibrationAttributes.java +5 −0 Original line number Diff line number Diff line Loading @@ -62,6 +62,11 @@ public final class VibrationAttributes implements Parcelable { @Retention(RetentionPolicy.SOURCE) public @interface Usage{} /** * Vibration usage filter value to match all usages. * @hide */ public static final int USAGE_FILTER_MATCH_ALL = -1; /** * Vibration usage class value to use when the vibration usage class is unknown. */ Loading
services/core/java/com/android/server/vibrator/VibratorManagerService.java +7 −1 Original line number Diff line number Diff line Loading @@ -723,6 +723,12 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { * VibrationAttributes.USAGE_* values. */ private boolean shouldCancelVibration(VibrationAttributes attrs, int usageFilter) { if (attrs.getUsage() == VibrationAttributes.USAGE_UNKNOWN) { // Special case, usage UNKNOWN would match all filters. Instead it should only match if // it's cancelling that usage specifically, or if cancelling all usages. return usageFilter == VibrationAttributes.USAGE_UNKNOWN || usageFilter == VibrationAttributes.USAGE_FILTER_MATCH_ALL; } return (usageFilter & attrs.getUsage()) == attrs.getUsage(); } Loading Loading @@ -1535,7 +1541,7 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { } private int runCancel() { cancelVibrate(/* usageFilter= */ -1, mToken); cancelVibrate(VibrationAttributes.USAGE_FILTER_MATCH_ALL, mToken); return 0; } Loading
services/tests/servicestests/src/com/android/server/vibrator/VibratorManagerServiceTest.java +36 −3 Original line number Diff line number Diff line Loading @@ -234,7 +234,7 @@ public class VibratorManagerServiceTest { CombinedVibration effect = CombinedVibration.createParallel( VibrationEffect.createPredefined(VibrationEffect.EFFECT_CLICK)); vibrate(service, effect, HAPTIC_FEEDBACK_ATTRS); service.cancelVibrate(/* usageFilter= */ -1, service); service.cancelVibrate(VibrationAttributes.USAGE_FILTER_MATCH_ALL, service); assertTrue(service.setAlwaysOnEffect(UID, PACKAGE_NAME, 1, effect, ALARM_ATTRS)); Loading Loading @@ -889,13 +889,13 @@ public class VibratorManagerServiceTest { mockVibrators(1); VibratorManagerService service = createSystemReadyService(); service.cancelVibrate(/* usageFilter= */ -1, service); service.cancelVibrate(VibrationAttributes.USAGE_FILTER_MATCH_ALL, service); assertFalse(service.isVibrating(1)); vibrate(service, VibrationEffect.createOneShot(10 * TEST_TIMEOUT_MILLIS, 100), ALARM_ATTRS); assertTrue(waitUntil(s -> s.isVibrating(1), service, TEST_TIMEOUT_MILLIS)); service.cancelVibrate(/* usageFilter= */ -1, service); service.cancelVibrate(VibrationAttributes.USAGE_FILTER_MATCH_ALL, service); assertTrue(waitUntil(s -> !s.isVibrating(1), service, TEST_TIMEOUT_MILLIS)); } Loading Loading @@ -924,6 +924,39 @@ public class VibratorManagerServiceTest { assertTrue(waitUntil(s -> !s.isVibrating(1), service, TEST_TIMEOUT_MILLIS)); } @Test public void cancelVibrate_withoutUnknownUsage_onlyStopsIfFilteringUnknownOrAllUsages() throws Exception { mockVibrators(1); VibrationAttributes attrs = new VibrationAttributes.Builder() .setUsage(VibrationAttributes.USAGE_UNKNOWN) .build(); VibratorManagerService service = createSystemReadyService(); vibrate(service, VibrationEffect.createOneShot(10 * TEST_TIMEOUT_MILLIS, 100), attrs); assertTrue(waitUntil(s -> s.isVibrating(1), service, TEST_TIMEOUT_MILLIS)); // Do not cancel UNKNOWN vibration when filter is being applied for other usages. service.cancelVibrate(VibrationAttributes.USAGE_RINGTONE, service); assertFalse(waitUntil(s -> !s.isVibrating(1), service, /* timeout= */ 50)); service.cancelVibrate( VibrationAttributes.USAGE_CLASS_ALARM | ~VibrationAttributes.USAGE_CLASS_MASK, service); assertFalse(waitUntil(s -> !s.isVibrating(1), service, /* timeout= */ 50)); // Cancel UNKNOWN vibration when filtered for that vibration specifically. service.cancelVibrate(VibrationAttributes.USAGE_UNKNOWN, service); assertTrue(waitUntil(s -> !s.isVibrating(1), service, TEST_TIMEOUT_MILLIS)); vibrate(service, VibrationEffect.createOneShot(10 * TEST_TIMEOUT_MILLIS, 100), attrs); assertTrue(waitUntil(s -> s.isVibrating(1), service, TEST_TIMEOUT_MILLIS)); // Cancel UNKNOWN vibration when all vibrations are being cancelled. service.cancelVibrate(VibrationAttributes.USAGE_FILTER_MATCH_ALL, service); assertTrue(waitUntil(s -> !s.isVibrating(1), service, TEST_TIMEOUT_MILLIS)); } private void mockCapabilities(long... capabilities) { when(mNativeWrapperMock.getCapabilities()).thenReturn( Arrays.stream(capabilities).reduce(0, (a, b) -> a | b)); Loading