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

Commit eb8decbc authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Resolve vibration effect default amplitude when scale is bypassed" into main

parents d36e965b 88e4be4d
Loading
Loading
Loading
Loading
+17 −0
Original line number Diff line number Diff line
@@ -101,6 +101,23 @@ final class HalVibration extends Vibration {
        mFallbacks.put(effectId, effect);
    }

    /**
     * Resolves the default vibration amplitude of {@link #getEffectToPlay()} and each fallback.
     *
     * @param defaultAmplitude An integer in [1,255] representing the device default amplitude to
     *                        replace the {@link VibrationEffect#DEFAULT_AMPLITUDE}.
     */
    public void resolveEffects(int defaultAmplitude) {
        CombinedVibration newEffect =
                mEffectToPlay.transform(VibrationEffect::resolve, defaultAmplitude);
        if (!Objects.equals(mEffectToPlay, newEffect)) {
            mEffectToPlay = newEffect;
        }
        for (int i = 0; i < mFallbacks.size(); i++) {
            mFallbacks.setValueAt(i, mFallbacks.valueAt(i).resolve(defaultAmplitude));
        }
    }

    /**
     * Scales the {@link #getEffectToPlay()} and each fallback effect with a scaling transformation.
     *
+7 −0
Original line number Diff line number Diff line
@@ -72,6 +72,13 @@ final class VibrationScaler {
        mScaleLevels.put(SCALE_VERY_HIGH, new ScaleLevel(SCALE_FACTOR_VERY_HIGH));
    }

    /**
     * Returns the default vibration amplitude configured for this device, value in [1,255].
     */
    public int getDefaultVibrationAmplitude() {
        return mDefaultVibrationAmplitude;
    }

    /**
     * Calculates the scale to be applied to external vibration with given usage.
     *
+3 −0
Original line number Diff line number Diff line
@@ -160,7 +160,10 @@ final class VibrationStepConductor implements IBinder.DeathRecipient {
            if (Flags.adaptiveHapticsEnabled()) {
                waitForVibrationParamsIfRequired();
            }
            // Scale resolves the default amplitudes from the effect before scaling them.
            mVibration.scaleEffects(mVibrationScaler::scale);
        } else {
            mVibration.resolveEffects(mVibrationScaler.getDefaultVibrationAmplitude());
        }

        mVibration.adaptToDevice(mDeviceAdapter);
+3 −1
Original line number Diff line number Diff line
@@ -884,8 +884,10 @@ public class VibratorManagerService extends IVibratorManagerService.Stub {
    private Vibration.EndInfo startVibrationOnInputDevicesLocked(HalVibration vib) {
        if (!vib.callerInfo.attrs.isFlagSet(
                VibrationAttributes.FLAG_BYPASS_USER_VIBRATION_INTENSITY_SCALE)) {
            // Scale effect before dispatching it to the input devices.
            // Scale resolves the default amplitudes from the effect before scaling them.
            vib.scaleEffects(mVibrationScaler::scale);
        } else {
            vib.resolveEffects(mVibrationScaler.getDefaultVibrationAmplitude());
        }
        mInputDeviceDelegate.vibrateIfAvailable(vib.callerInfo, vib.getEffectToPlay());

+45 −5
Original line number Diff line number Diff line
@@ -1421,6 +1421,7 @@ public class VibratorManagerServiceTest {
    public void vibrate_withIntensitySettings_appliesSettingsToScaleVibrations() throws Exception {
        int defaultNotificationIntensity =
                mVibrator.getDefaultVibrationIntensity(VibrationAttributes.USAGE_NOTIFICATION);
        // This will scale up notification vibrations.
        setUserSetting(Settings.System.NOTIFICATION_VIBRATION_INTENSITY,
                defaultNotificationIntensity < Vibrator.VIBRATION_INTENSITY_HIGH
                        ? defaultNotificationIntensity + 1
@@ -1428,6 +1429,7 @@ public class VibratorManagerServiceTest {

        int defaultTouchIntensity =
                mVibrator.getDefaultVibrationIntensity(VibrationAttributes.USAGE_TOUCH);
        // This will scale down touch vibrations.
        setUserSetting(Settings.System.HAPTIC_FEEDBACK_INTENSITY,
                defaultTouchIntensity > Vibrator.VIBRATION_INTENSITY_LOW
                        ? defaultTouchIntensity - 1
@@ -1481,6 +1483,42 @@ public class VibratorManagerServiceTest {
        cancelVibrate(service); // Clean up long-ish effect.
    }

    @Test
    public void vibrate_withBypassScaleFlag_ignoresIntensitySettingsAndResolvesAmplitude()
            throws Exception {
        // Permission needed for bypassing user settings
        grantPermission(android.Manifest.permission.MODIFY_PHONE_STATE);

        int defaultTouchIntensity =
                mVibrator.getDefaultVibrationIntensity(VibrationAttributes.USAGE_TOUCH);
        // This will scale down touch vibrations.
        setUserSetting(Settings.System.HAPTIC_FEEDBACK_INTENSITY,
                defaultTouchIntensity > Vibrator.VIBRATION_INTENSITY_LOW
                        ? defaultTouchIntensity - 1
                        : defaultTouchIntensity);

        int defaultAmplitude = mContextSpy.getResources().getInteger(
                com.android.internal.R.integer.config_defaultVibrationAmplitude);

        mockVibrators(1);
        FakeVibratorControllerProvider fakeVibrator = mVibratorProviders.get(1);
        fakeVibrator.setCapabilities(IVibrator.CAP_AMPLITUDE_CONTROL);
        VibratorManagerService service = createSystemReadyService();

        vibrateAndWaitUntilFinished(service,
                VibrationEffect.createOneShot(100, VibrationEffect.DEFAULT_AMPLITUDE),
                new VibrationAttributes.Builder()
                        .setUsage(VibrationAttributes.USAGE_TOUCH)
                        .setFlags(VibrationAttributes.FLAG_BYPASS_USER_VIBRATION_INTENSITY_SCALE)
                        .build());

        assertEquals(1, fakeVibrator.getAllEffectSegments().size());

        assertEquals(defaultAmplitude / 255f, fakeVibrator.getAmplitudes().get(0), 1e-5);

        cancelVibrate(service); // Clean up long-ish effect.
    }

    @Test
    public void vibrate_withPowerModeChange_cancelVibrationIfNotAllowed() throws Exception {
        mockVibrators(1, 2);
@@ -1879,6 +1917,9 @@ public class VibratorManagerServiceTest {

    @Test
    public void onExternalVibration_withBypassMuteAudioFlag_ignoresUserSettings() {
        // Permission needed for bypassing user settings
        grantPermission(android.Manifest.permission.MODIFY_PHONE_STATE);

        mockVibrators(1);
        mVibratorProviders.get(1).setCapabilities(IVibrator.CAP_EXTERNAL_CONTROL);
        setUserSetting(Settings.System.ALARM_VIBRATION_INTENSITY,
@@ -1892,12 +1933,12 @@ public class VibratorManagerServiceTest {
                .build();
        createSystemReadyService();

        int scale = mExternalVibratorService.onExternalVibrationStart(
                new ExternalVibration(UID, PACKAGE_NAME, audioAttrs,
                        mock(IExternalVibrationController.class)));
        ExternalVibration vib = new ExternalVibration(UID, PACKAGE_NAME, audioAttrs,
                mock(IExternalVibrationController.class));
        int scale = mExternalVibratorService.onExternalVibrationStart(vib);
        assertEquals(IExternalVibratorService.SCALE_MUTE, scale);

        createSystemReadyService();
        mExternalVibratorService.onExternalVibrationStop(vib);
        scale = mExternalVibratorService.onExternalVibrationStart(
                new ExternalVibration(UID, PACKAGE_NAME, flaggedAudioAttrs,
                        mock(IExternalVibrationController.class)));
@@ -1912,7 +1953,6 @@ public class VibratorManagerServiceTest {
                Vibrator.VIBRATION_INTENSITY_OFF);
        AudioAttributes flaggedAudioAttrs = new AudioAttributes.Builder()
                .setUsage(AudioAttributes.USAGE_UNKNOWN)
                .setFlags(AudioAttributes.FLAG_BYPASS_MUTE)
                .build();
        createSystemReadyService();