Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 58774b9c authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Automerger Merge Worker
Browse files

Merge "Fix usage filter over UNKNOWN vibration" into sc-dev am: c100aeab

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/14980865

Change-Id: If137ddaf28c2760c3fec8ff6ae0297e206484f16
parents 315683c1 c100aeab
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -146,7 +146,7 @@ public class SystemVibratorManager extends VibratorManager {

    @Override
    public void cancel() {
        cancelVibration(/* usageFilter= */ -1);
        cancelVibration(VibrationAttributes.USAGE_FILTER_MATCH_ALL);
    }

    @Override
+5 −0
Original line number Diff line number Diff line
@@ -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.
     */
+7 −1
Original line number Diff line number Diff line
@@ -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();
    }

@@ -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;
        }

+36 −3
Original line number Diff line number Diff line
@@ -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));

@@ -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));
    }

@@ -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));