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

Commit 25312f0a authored by Chen Bai's avatar Chen Bai Committed by Android (Google) Code Review
Browse files

Merge "haptic: handle attrs for input source custmoized haptic feedback" into main

parents 257f7dcb 2ea8c01d
Loading
Loading
Loading
Loading
+45 −14
Original line number Diff line number Diff line
@@ -16,6 +16,8 @@

package com.android.server.vibrator;

import static android.os.vibrator.Flags.hapticFeedbackInputSourceCustomizationEnabled;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.res.Resources;
@@ -121,7 +123,6 @@ public final class HapticFeedbackVibrationProvider {
        return getVibrationForHapticFeedback(effectId);
    }

    // TODO(b/354049335): handle input source customized VibrationAttributes.
    /**
     * Provides the {@link VibrationAttributes} that should be used for a haptic feedback.
     *
@@ -131,7 +132,7 @@ public final class HapticFeedbackVibrationProvider {
     * @param privFlags Additional private flags as per {@link HapticFeedbackConstants}.
     * @return the {@link VibrationAttributes} that should be used for the provided haptic feedback.
     */
    public VibrationAttributes getVibrationAttributesForHapticFeedback(int effectId,
    public VibrationAttributes getVibrationAttributes(int effectId,
            @HapticFeedbackConstants.Flags int flags,
            @HapticFeedbackConstants.PrivateFlags int privFlags) {
        VibrationAttributes attrs;
@@ -142,10 +143,13 @@ public final class HapticFeedbackVibrationProvider {
                break;
            case HapticFeedbackConstants.ASSISTANT_BUTTON:
            case HapticFeedbackConstants.LONG_PRESS_POWER_BUTTON:
                attrs = HARDWARE_FEEDBACK_VIBRATION_ATTRIBUTES;
                break;
            case HapticFeedbackConstants.SCROLL_TICK:
            case HapticFeedbackConstants.SCROLL_ITEM_FOCUS:
            case HapticFeedbackConstants.SCROLL_LIMIT:
                attrs = HARDWARE_FEEDBACK_VIBRATION_ATTRIBUTES;
                attrs = hapticFeedbackInputSourceCustomizationEnabled() ? TOUCH_VIBRATION_ATTRIBUTES
                        : HARDWARE_FEEDBACK_VIBRATION_ATTRIBUTES;
                break;
            case HapticFeedbackConstants.KEYBOARD_TAP:
            case HapticFeedbackConstants.KEYBOARD_RELEASE:
@@ -158,19 +162,32 @@ public final class HapticFeedbackVibrationProvider {
            default:
                attrs = TOUCH_VIBRATION_ATTRIBUTES;
        }
        return getVibrationAttributesWithFlags(attrs, effectId, flags);
    }

        int vibFlags = 0;
        boolean bypassVibrationIntensitySetting =
                (flags & HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING) != 0;
        if (bypassVibrationIntensitySetting) {
            vibFlags |= VibrationAttributes.FLAG_BYPASS_USER_VIBRATION_INTENSITY_OFF;
    /**
     * Similar to {@link #getVibrationAttributes(int, int, int)} but also handles
     * input source customization.
     *
     * @param inputSource the {@link InputDevice.Source} that customizes the
     *                    {@link VibrationAttributes}.
     */
    public VibrationAttributes getVibrationAttributes(int effectId,
            int inputSource,
            @HapticFeedbackConstants.Flags int flags,
            @HapticFeedbackConstants.PrivateFlags int privFlags) {
        if (hapticFeedbackInputSourceCustomizationEnabled()
                && inputSource == InputDevice.SOURCE_ROTARY_ENCODER) {
            switch (effectId) {
                case HapticFeedbackConstants.SCROLL_TICK,
                        HapticFeedbackConstants.SCROLL_ITEM_FOCUS,
                        HapticFeedbackConstants.SCROLL_LIMIT -> {
                    return getVibrationAttributesWithFlags(HARDWARE_FEEDBACK_VIBRATION_ATTRIBUTES,
                            effectId, flags);
                }
        if (shouldBypassInterruptionPolicy(effectId)) {
            vibFlags |= VibrationAttributes.FLAG_BYPASS_INTERRUPTION_POLICY;
            }

        return vibFlags == 0 ? attrs : new VibrationAttributes.Builder(attrs)
                .setFlags(vibFlags).build();
        }
        return getVibrationAttributes(effectId, flags, privFlags);
    }

    /**
@@ -344,6 +361,20 @@ public final class HapticFeedbackVibrationProvider {
        return IME_FEEDBACK_VIBRATION_ATTRIBUTES;
    }

    private VibrationAttributes getVibrationAttributesWithFlags(VibrationAttributes attrs,
            int effectId, int flags) {
        int vibFlags = 0;
        if ((flags & HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING) != 0) {
            vibFlags |= VibrationAttributes.FLAG_BYPASS_USER_VIBRATION_INTENSITY_OFF;
        }
        if (shouldBypassInterruptionPolicy(effectId)) {
            vibFlags |= VibrationAttributes.FLAG_BYPASS_INTERRUPTION_POLICY;
        }

        return vibFlags == 0 ? attrs : new VibrationAttributes.Builder(attrs)
                .setFlags(vibFlags).build();
    }

    private static boolean shouldBypassInterruptionPolicy(int effectId) {
        switch (effectId) {
            case HapticFeedbackConstants.SCROLL_TICK:
+3 −3
Original line number Diff line number Diff line
@@ -509,7 +509,7 @@ public class VibratorManagerService extends IVibratorManagerService.Stub {
        }
        return performHapticFeedbackWithEffect(uid, deviceId, opPkg, constant, reason, token,
                hapticVibrationProvider.getVibration(constant),
                hapticVibrationProvider.getVibrationAttributesForHapticFeedback(
                hapticVibrationProvider.getVibrationAttributes(
                        constant, flags, privFlags));
    }

@@ -534,8 +534,8 @@ public class VibratorManagerService extends IVibratorManagerService.Stub {
        }
        return performHapticFeedbackWithEffect(uid, deviceId, opPkg, constant, reason, token,
                hapticVibrationProvider.getVibration(constant, inputSource),
                hapticVibrationProvider.getVibrationAttributesForHapticFeedback(
                        constant, flags, privFlags));
                hapticVibrationProvider.getVibrationAttributes(constant, inputSource, flags,
                        privFlags));
    }

    private HalVibration performHapticFeedbackWithEffect(int uid, int deviceId, String opPkg,
+62 −8
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ package com.android.server.vibrator;

import static android.os.VibrationAttributes.FLAG_BYPASS_INTERRUPTION_POLICY;
import static android.os.VibrationAttributes.FLAG_BYPASS_USER_VIBRATION_INTENSITY_OFF;
import static android.os.VibrationAttributes.USAGE_HARDWARE_FEEDBACK;
import static android.os.VibrationAttributes.USAGE_IME_FEEDBACK;
import static android.os.VibrationAttributes.USAGE_TOUCH;
import static android.os.VibrationEffect.Composition.PRIMITIVE_CLICK;
@@ -105,7 +106,7 @@ public class HapticFeedbackVibrationProviderTest {

    @Before
    public void setUp() {
        mSetFlagsRule.enableFlags(FLAG_HAPTIC_FEEDBACK_INPUT_SOURCE_CUSTOMIZATION_ENABLED);
        mSetFlagsRule.disableFlags(FLAG_HAPTIC_FEEDBACK_INPUT_SOURCE_CUSTOMIZATION_ENABLED);
    }

    @Test
@@ -398,7 +399,7 @@ public class HapticFeedbackVibrationProviderTest {
        HapticFeedbackVibrationProvider provider = createProviderWithoutCustomizations();

        for (int effectId : BIOMETRIC_FEEDBACK_CONSTANTS) {
            VibrationAttributes attrs = provider.getVibrationAttributesForHapticFeedback(
            VibrationAttributes attrs = provider.getVibrationAttributes(
                    effectId, /* flags */ 0, /* privFlags */ 0);
            assertThat(attrs.getUsage()).isEqualTo(VibrationAttributes.USAGE_COMMUNICATION_REQUEST);
        }
@@ -408,7 +409,7 @@ public class HapticFeedbackVibrationProviderTest {
    public void testVibrationAttribute_forNotBypassingIntensitySettings() {
        HapticFeedbackVibrationProvider provider = createProviderWithoutCustomizations();

        VibrationAttributes attrs = provider.getVibrationAttributesForHapticFeedback(
        VibrationAttributes attrs = provider.getVibrationAttributes(
                SAFE_MODE_ENABLED, /* flags */ 0, /* privFlags */ 0);

        assertThat(attrs.isFlagSet(FLAG_BYPASS_USER_VIBRATION_INTENSITY_OFF)).isFalse();
@@ -418,7 +419,7 @@ public class HapticFeedbackVibrationProviderTest {
    public void testVibrationAttribute_forByassingIntensitySettings() {
        HapticFeedbackVibrationProvider provider = createProviderWithoutCustomizations();

        VibrationAttributes attrs = provider.getVibrationAttributesForHapticFeedback(
        VibrationAttributes attrs = provider.getVibrationAttributes(
                SAFE_MODE_ENABLED,
                /* flags */ HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING, /* privFlags */ 0);

@@ -431,7 +432,7 @@ public class HapticFeedbackVibrationProviderTest {
        HapticFeedbackVibrationProvider provider = createProviderWithoutCustomizations();

        for (int effectId : SCROLL_FEEDBACK_CONSTANTS) {
            VibrationAttributes attrs = provider.getVibrationAttributesForHapticFeedback(
            VibrationAttributes attrs = provider.getVibrationAttributes(
                    effectId, /* flags */ 0, /* privFlags */ 0);
            assertWithMessage("Expected FLAG_BYPASS_INTERRUPTION_POLICY for effect " + effectId)
                   .that(attrs.isFlagSet(FLAG_BYPASS_INTERRUPTION_POLICY)).isTrue();
@@ -444,19 +445,72 @@ public class HapticFeedbackVibrationProviderTest {
        HapticFeedbackVibrationProvider provider = createProviderWithoutCustomizations();

        for (int effectId : SCROLL_FEEDBACK_CONSTANTS) {
            VibrationAttributes attrs = provider.getVibrationAttributesForHapticFeedback(
            VibrationAttributes attrs = provider.getVibrationAttributes(
                    effectId, /* flags */ 0, /* privFlags */ 0);
            assertWithMessage("Expected no FLAG_BYPASS_INTERRUPTION_POLICY for effect " + effectId)
                   .that(attrs.isFlagSet(FLAG_BYPASS_INTERRUPTION_POLICY)).isFalse();
        }
    }

    @Test
    public void testVibrationAttribute_scrollFeedback_inputCustomizedFlag_useTouchUsage() {
        mSetFlagsRule.enableFlags(FLAG_HAPTIC_FEEDBACK_INPUT_SOURCE_CUSTOMIZATION_ENABLED);
        HapticFeedbackVibrationProvider provider = createProviderWithoutCustomizations();

        for (int effectId : SCROLL_FEEDBACK_CONSTANTS) {
            VibrationAttributes attrs = provider.getVibrationAttributes(effectId, /* flags */
                    0, /* privFlags */ 0);
            assertWithMessage("Expected USAGE_TOUCH for scroll effect " + effectId
                    + ", if no input customization").that(attrs.getUsage()).isEqualTo(USAGE_TOUCH);
        }
    }

    @Test
    public void testVibrationAttribute_scrollFeedback_noInputCustomizedFlag_useHardwareFeedback() {
        HapticFeedbackVibrationProvider provider = createProviderWithoutCustomizations();

        for (int effectId : SCROLL_FEEDBACK_CONSTANTS) {
            VibrationAttributes attrs = provider.getVibrationAttributes(effectId, /* flags */
                    0, /* privFlags */ 0);
            assertWithMessage("Expected USAGE_HARDWARE_FEEDBACK for scroll effect " + effectId
                    + ", if no input customization").that(attrs.getUsage()).isEqualTo(
                    USAGE_HARDWARE_FEEDBACK);
        }
    }

    @Test
    public void testVibrationAttribute_scrollFeedback_rotaryInputSource_useHardwareFeedback() {
        mSetFlagsRule.enableFlags(FLAG_HAPTIC_FEEDBACK_INPUT_SOURCE_CUSTOMIZATION_ENABLED);
        HapticFeedbackVibrationProvider provider = createProviderWithoutCustomizations();

        for (int effectId : SCROLL_FEEDBACK_CONSTANTS) {
            VibrationAttributes attrs = provider.getVibrationAttributes(
                    effectId, InputDevice.SOURCE_ROTARY_ENCODER, /* flags */ 0, /* privFlags */ 0);
            assertWithMessage(
                    "Expected USAGE_HARDWARE_FEEDBACK for input source SOURCE_ROTARY_ENCODER").that(
                    attrs.getUsage()).isEqualTo(USAGE_HARDWARE_FEEDBACK);
        }
    }

    @Test
    public void testVibrationAttribute_scrollFeedback_touchInputSource_useTouchUsage() {
        mSetFlagsRule.enableFlags(FLAG_HAPTIC_FEEDBACK_INPUT_SOURCE_CUSTOMIZATION_ENABLED);
        HapticFeedbackVibrationProvider provider = createProviderWithoutCustomizations();

        for (int effectId : SCROLL_FEEDBACK_CONSTANTS) {
            VibrationAttributes attrs = provider.getVibrationAttributes(
                    effectId, InputDevice.SOURCE_TOUCHSCREEN, /* flags */ 0, /* privFlags */ 0);
            assertWithMessage("Expected USAGE_TOUCH for input source SOURCE_TOUCHSCREEN").that(
                    attrs.getUsage()).isEqualTo(USAGE_TOUCH);
        }
    }

    @Test
    public void testVibrationAttribute_notIme_useTouchUsage() {
        HapticFeedbackVibrationProvider provider = createProviderWithoutCustomizations();

        for (int effectId : KEYBOARD_FEEDBACK_CONSTANTS) {
            VibrationAttributes attrs = provider.getVibrationAttributesForHapticFeedback(
            VibrationAttributes attrs = provider.getVibrationAttributes(
                    effectId, /* flags */ 0, /* privFlags */ 0);
            assertWithMessage("Expected USAGE_TOUCH for effect " + effectId)
                    .that(attrs.getUsage()).isEqualTo(USAGE_TOUCH);
@@ -468,7 +522,7 @@ public class HapticFeedbackVibrationProviderTest {
        HapticFeedbackVibrationProvider provider = createProviderWithoutCustomizations();

        for (int effectId : KEYBOARD_FEEDBACK_CONSTANTS) {
            VibrationAttributes attrs = provider.getVibrationAttributesForHapticFeedback(
            VibrationAttributes attrs = provider.getVibrationAttributes(
                    effectId, /* flags */ 0,
                    HapticFeedbackConstants.PRIVATE_FLAG_APPLY_INPUT_METHOD_SETTINGS);
            assertWithMessage("Expected USAGE_IME_FEEDBACK for effect " + effectId)