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

Commit acf4f789 authored by Valentin Iftime's avatar Valentin Iftime
Browse files

Re-add scale and resolve to VibrationEffect

Test: atest VibrationEffectTest

Bug: 275032416
Bug: 270456865
Change-Id: If301f0042f141460f65ec59bd1614e863779c672
parent b4a023c6
Loading
Loading
Loading
Loading
+58 −0
Original line number Diff line number Diff line
@@ -546,6 +546,30 @@ public abstract class VibrationEffect implements Parcelable {
        return false;
    }

    /**
     * Resolve default values into integer amplitude numbers.
     *
     * @param defaultAmplitude the default amplitude to apply, must be between 0 and
     *                         MAX_AMPLITUDE
     * @return this if amplitude value is already set, or a copy of this effect with given default
     *         amplitude otherwise
     *
     * @hide
     */
    public abstract <T extends VibrationEffect> T resolve(int defaultAmplitude);

    /**
     * Scale the vibration effect intensity with the given constraints.
     *
     * @param scaleFactor scale factor to be applied to the intensity. Values within [0,1) will
     *                    scale down the intensity, values larger than 1 will scale up
     * @return this if there is no scaling to be done, or a copy of this effect with scaled
     *         vibration intensity otherwise
     *
     * @hide
     */
    public abstract <T extends VibrationEffect> T scale(float scaleFactor);

    /**
     * Ensures that the effect is repeating indefinitely or not. This is a lossy operation and
     * should only be applied once to an original effect - it shouldn't be applied to the
@@ -819,6 +843,40 @@ public abstract class VibrationEffect implements Parcelable {
            return totalDuration <= MAX_HAPTIC_FEEDBACK_DURATION;
        }

        /** @hide */
        @NonNull
        @Override
        public Composed resolve(int defaultAmplitude) {
            int segmentCount = mSegments.size();
            ArrayList<VibrationEffectSegment> resolvedSegments = new ArrayList<>(segmentCount);
            for (int i = 0; i < segmentCount; i++) {
                resolvedSegments.add(mSegments.get(i).resolve(defaultAmplitude));
            }
            if (resolvedSegments.equals(mSegments)) {
                return this;
            }
            Composed resolved = new Composed(resolvedSegments, mRepeatIndex);
            resolved.validate();
            return resolved;
        }

        /** @hide */
        @NonNull
        @Override
        public Composed scale(float scaleFactor) {
            int segmentCount = mSegments.size();
            ArrayList<VibrationEffectSegment> scaledSegments = new ArrayList<>(segmentCount);
            for (int i = 0; i < segmentCount; i++) {
                scaledSegments.add(mSegments.get(i).scale(scaleFactor));
            }
            if (scaledSegments.equals(mSegments)) {
                return this;
            }
            Composed scaled = new Composed(scaledSegments, mRepeatIndex);
            scaled.validate();
            return scaled;
        }

        /** @hide */
        @NonNull
        @Override
+84 −0
Original line number Diff line number Diff line
@@ -38,6 +38,8 @@ import android.content.res.Resources;
import android.hardware.vibrator.IVibrator;
import android.net.Uri;
import android.os.VibrationEffect.Composition.UnreachableAfterRepeatingIndefinitelyException;
import android.os.vibrator.PrimitiveSegment;
import android.os.vibrator.StepSegment;
import android.platform.test.annotations.Presubmit;

import androidx.test.InstrumentationRegistry;
@@ -634,6 +636,88 @@ public class VibrationEffectTest {
                        .validate());
    }

    @Test
    public void testResolveOneShot() {
        VibrationEffect.Composed resolved = DEFAULT_ONE_SHOT.resolve(51);
        assertEquals(0.2f, ((StepSegment) resolved.getSegments().get(0)).getAmplitude());

        assertThrows(IllegalArgumentException.class, () -> DEFAULT_ONE_SHOT.resolve(1000));
    }

    @Test
    public void testResolveWaveform() {
        VibrationEffect.Composed resolved = TEST_WAVEFORM.resolve(102);
        assertEquals(0.4f, ((StepSegment) resolved.getSegments().get(2)).getAmplitude());

        assertThrows(IllegalArgumentException.class, () -> TEST_WAVEFORM.resolve(1000));
    }

    @Test
    public void testResolvePrebaked() {
        VibrationEffect effect = VibrationEffect.get(VibrationEffect.EFFECT_CLICK);
        assertEquals(effect, effect.resolve(51));
    }

    @Test
    public void testResolveComposed() {
        VibrationEffect effect = VibrationEffect.startComposition()
                .addPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK, 1f, 1)
                .compose();
        assertEquals(effect, effect.resolve(51));

        VibrationEffect.Composed resolved = VibrationEffect.startComposition()
                .addEffect(DEFAULT_ONE_SHOT)
                .compose()
                .resolve(51);
        assertEquals(0.2f, ((StepSegment) resolved.getSegments().get(0)).getAmplitude());
    }

    @Test
    public void testScaleOneShot() {
        VibrationEffect.Composed scaledUp = TEST_ONE_SHOT.scale(1.5f);
        assertTrue(100 / 255f < ((StepSegment) scaledUp.getSegments().get(0)).getAmplitude());

        VibrationEffect.Composed scaledDown = TEST_ONE_SHOT.scale(0.5f);
        assertTrue(100 / 255f > ((StepSegment) scaledDown.getSegments().get(0)).getAmplitude());
    }

    @Test
    public void testScaleWaveform() {
        VibrationEffect.Composed scaledUp = TEST_WAVEFORM.scale(1.5f);
        assertEquals(1f, ((StepSegment) scaledUp.getSegments().get(0)).getAmplitude(), 1e-5f);

        VibrationEffect.Composed scaledDown = TEST_WAVEFORM.scale(0.5f);
        assertTrue(1f > ((StepSegment) scaledDown.getSegments().get(0)).getAmplitude());
    }

    @Test
    public void testScalePrebaked() {
        VibrationEffect effect = VibrationEffect.get(VibrationEffect.EFFECT_CLICK);

        VibrationEffect.Composed scaledUp = effect.scale(1.5f);
        assertEquals(effect, scaledUp);

        VibrationEffect.Composed scaledDown = effect.scale(0.5f);
        assertEquals(effect, scaledDown);
    }

    @Test
    public void testScaleComposed() {
        VibrationEffect.Composed effect =
                (VibrationEffect.Composed) VibrationEffect.startComposition()
                    .addPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK, 0.5f, 1)
                    .addEffect(TEST_ONE_SHOT)
                    .compose();

        VibrationEffect.Composed scaledUp = effect.scale(1.5f);
        assertTrue(0.5f < ((PrimitiveSegment) scaledUp.getSegments().get(0)).getScale());
        assertTrue(100 / 255f < ((StepSegment) scaledUp.getSegments().get(1)).getAmplitude());

        VibrationEffect.Composed scaledDown = effect.scale(0.5f);
        assertTrue(0.5f > ((PrimitiveSegment) scaledDown.getSegments().get(0)).getScale());
        assertTrue(100 / 255f > ((StepSegment) scaledDown.getSegments().get(1)).getAmplitude());
    }

    private void doTestApplyRepeatingWithNonRepeatingOriginal(@NotNull VibrationEffect original) {
        assertTrue(original.getDuration() != Long.MAX_VALUE);
        int loopDelayMs = 123;