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

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

Merge "Update vendor VibrationEffect to support scale factor" into main

parents 7a39cc95 ab1a3505
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -2579,9 +2579,10 @@ package android.os {

  @FlaggedApi("android.os.vibrator.vendor_vibration_effects") public static final class VibrationEffect.VendorEffect extends android.os.VibrationEffect {
    method @Nullable public long[] computeCreateWaveformOffOnTimingsOrNull();
    method public float getAdaptiveScale();
    method public long getDuration();
    method public int getEffectStrength();
    method public float getLinearScale();
    method public float getScale();
    method @NonNull public android.os.PersistableBundle getVendorData();
    method public void writeToParcel(@NonNull android.os.Parcel, int);
    field @NonNull public static final android.os.Parcelable.Creator<android.os.VibrationEffect.VendorEffect> CREATOR;
+38 −22
Original line number Diff line number Diff line
@@ -346,7 +346,7 @@ public abstract class VibrationEffect implements Parcelable {
    @RequiresPermission(android.Manifest.permission.VIBRATE_VENDOR_EFFECTS)
    public static VibrationEffect createVendorEffect(@NonNull PersistableBundle effect) {
        VibrationEffect vendorEffect = new VendorEffect(effect, VendorEffect.DEFAULT_STRENGTH,
                VendorEffect.DEFAULT_SCALE);
                VendorEffect.DEFAULT_SCALE, VendorEffect.DEFAULT_SCALE);
        vendorEffect.validate();
        return vendorEffect;
    }
@@ -623,7 +623,7 @@ public abstract class VibrationEffect implements Parcelable {
     * @hide
     */
    @NonNull
    public abstract VibrationEffect scaleLinearly(float scaleFactor);
    public abstract VibrationEffect applyAdaptiveScale(float scaleFactor);

    /**
     * Ensures that the effect is repeating indefinitely or not. This is a lossy operation and
@@ -948,7 +948,7 @@ public abstract class VibrationEffect implements Parcelable {
        /** @hide */
        @NonNull
        @Override
        public Composed scaleLinearly(float scaleFactor) {
        public Composed applyAdaptiveScale(float scaleFactor) {
            return applyToSegments(VibrationEffectSegment::scaleLinearly, scaleFactor);
        }

@@ -1100,21 +1100,23 @@ public abstract class VibrationEffect implements Parcelable {

        private final PersistableBundle mVendorData;
        private final int mEffectStrength;
        private final float mLinearScale;
        private final float mScale;
        private final float mAdaptiveScale;

        /** @hide */
        VendorEffect(@NonNull Parcel in) {
            this(Objects.requireNonNull(
                    in.readPersistableBundle(VibrationEffect.class.getClassLoader())),
                    in.readInt(), in.readFloat());
                    in.readInt(), in.readFloat(), in.readFloat());
        }

        /** @hide */
        public VendorEffect(@NonNull PersistableBundle vendorData, int effectStrength,
                float linearScale) {
                float scale, float adaptiveScale) {
            mVendorData = vendorData;
            mEffectStrength = effectStrength;
            mLinearScale = linearScale;
            mScale = scale;
            mAdaptiveScale = adaptiveScale;
        }

        @NonNull
@@ -1126,8 +1128,12 @@ public abstract class VibrationEffect implements Parcelable {
            return mEffectStrength;
        }

        public float getLinearScale() {
            return mLinearScale;
        public float getScale() {
            return mScale;
        }

        public float getAdaptiveScale() {
            return mAdaptiveScale;
        }

        /** @hide */
@@ -1175,7 +1181,8 @@ public abstract class VibrationEffect implements Parcelable {
            if (mEffectStrength == effectStrength) {
                return this;
            }
            VendorEffect updated = new VendorEffect(mVendorData, effectStrength, mLinearScale);
            VendorEffect updated = new VendorEffect(mVendorData, effectStrength, mScale,
                    mAdaptiveScale);
            updated.validate();
            return updated;
        }
@@ -1184,18 +1191,24 @@ public abstract class VibrationEffect implements Parcelable {
        @NonNull
        @Override
        public VendorEffect scale(float scaleFactor) {
            // Vendor effect strength cannot be scaled with this method.
            if (Float.compare(mScale, scaleFactor) == 0) {
                return this;
            }
            VendorEffect updated = new VendorEffect(mVendorData, mEffectStrength, scaleFactor,
                    mAdaptiveScale);
            updated.validate();
            return updated;
        }

        /** @hide */
        @NonNull
        @Override
        public VibrationEffect scaleLinearly(float scaleFactor) {
            if (Float.compare(mLinearScale, scaleFactor) == 0) {
        public VibrationEffect applyAdaptiveScale(float scaleFactor) {
            if (Float.compare(mAdaptiveScale, scaleFactor) == 0) {
                return this;
            }
            VendorEffect updated = new VendorEffect(mVendorData, mEffectStrength, scaleFactor);
            VendorEffect updated = new VendorEffect(mVendorData, mEffectStrength, mScale,
                    scaleFactor);
            updated.validate();
            return updated;
        }
@@ -1216,29 +1229,31 @@ public abstract class VibrationEffect implements Parcelable {
                return false;
            }
            return mEffectStrength == other.mEffectStrength
                    && (Float.compare(mLinearScale, other.mLinearScale) == 0)
                    && (Float.compare(mScale, other.mScale) == 0)
                    && (Float.compare(mAdaptiveScale, other.mAdaptiveScale) == 0)
                    && isPersistableBundleEquals(mVendorData, other.mVendorData);
        }

        @Override
        public int hashCode() {
            // PersistableBundle does not implement hashCode, so use its size as a shortcut.
            return Objects.hash(mVendorData.size(), mEffectStrength, mLinearScale);
            return Objects.hash(mVendorData.size(), mEffectStrength, mScale, mAdaptiveScale);
        }

        @Override
        public String toString() {
            return String.format(Locale.ROOT,
                    "VendorEffect{vendorData=%s, strength=%s, scale=%.2f}",
                    mVendorData, effectStrengthToString(mEffectStrength), mLinearScale);
                    "VendorEffect{vendorData=%s, strength=%s, scale=%.2f, adaptiveScale=%.2f}",
                    mVendorData, effectStrengthToString(mEffectStrength), mScale, mAdaptiveScale);
        }

        /** @hide */
        @Override
        public String toDebugString() {
            return String.format(Locale.ROOT, "vendorEffect=%s, strength=%s, scale=%.2f",
            return String.format(Locale.ROOT,
                    "vendorEffect=%s, strength=%s, scale=%.2f, adaptiveScale=%.2f",
                    mVendorData.toShortString(), effectStrengthToString(mEffectStrength),
                    mLinearScale);
                    mScale, mAdaptiveScale);
        }

        @Override
@@ -1251,7 +1266,8 @@ public abstract class VibrationEffect implements Parcelable {
            out.writeInt(PARCEL_TOKEN_VENDOR_EFFECT);
            out.writePersistableBundle(mVendorData);
            out.writeInt(mEffectStrength);
            out.writeFloat(mLinearScale);
            out.writeFloat(mScale);
            out.writeFloat(mAdaptiveScale);
        }

        /**
+70 −6
Original line number Diff line number Diff line
@@ -60,7 +60,7 @@ import java.util.Arrays;

@RunWith(MockitoJUnitRunner.class)
public class VibrationEffectTest {

    private static final float TOLERANCE = 1e-2f;
    private static final String RINGTONE_URI_1 = "content://test/system/ringtone_1";
    private static final String RINGTONE_URI_2 = "content://test/system/ringtone_2";
    private static final String RINGTONE_URI_3 = "content://test/system/ringtone_3";
@@ -709,7 +709,7 @@ public class VibrationEffectTest {
    @Test
    public void testScaleWaveform() {
        VibrationEffect scaledUp = TEST_WAVEFORM.scale(1.5f);
        assertEquals(1f, getStepSegment(scaledUp, 0).getAmplitude(), 1e-5f);
        assertEquals(1f, getStepSegment(scaledUp, 0).getAmplitude(), TOLERANCE);

        VibrationEffect scaledDown = TEST_WAVEFORM.scale(0.5f);
        assertTrue(1f > getStepSegment(scaledDown, 0).getAmplitude());
@@ -731,11 +731,11 @@ public class VibrationEffectTest {
    public void testScaleVendorEffect() {
        VibrationEffect effect = VibrationEffect.createVendorEffect(createNonEmptyBundle());

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

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

    @Test
@@ -754,6 +754,70 @@ public class VibrationEffectTest {
        assertTrue(100 / 255f > getStepSegment(scaledDown, 1).getAmplitude());
    }

    @Test
    public void testApplyAdaptiveScaleOneShot() {
        VibrationEffect oneShot = VibrationEffect.createOneShot(TEST_TIMING, /* amplitude= */ 100);

        VibrationEffect scaledUp = oneShot.applyAdaptiveScale(1.5f);
        assertThat(getStepSegment(scaledUp, 0).getAmplitude()).isWithin(TOLERANCE).of(150 / 255f);

        VibrationEffect scaledDown = oneShot.applyAdaptiveScale(0.5f);
        assertThat(getStepSegment(scaledDown, 0).getAmplitude()).isWithin(TOLERANCE).of(50 / 255f);
    }

    @Test
    public void testApplyAdaptiveScaleWaveform() {
        VibrationEffect waveform = VibrationEffect.createWaveform(
                new long[] { 100, 100 }, new int[] { 10, 0 }, -1);

        VibrationEffect scaledUp = waveform.applyAdaptiveScale(1.5f);
        assertThat(getStepSegment(scaledUp, 0).getAmplitude()).isWithin(TOLERANCE).of(15 / 255f);

        VibrationEffect scaledDown = waveform.applyAdaptiveScale(0.5f);
        assertThat(getStepSegment(scaledDown, 0).getAmplitude()).isWithin(TOLERANCE).of(5 / 255f);
    }

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

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

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

    @Test
    @RequiresFlagsEnabled(android.os.vibrator.Flags.FLAG_VENDOR_VIBRATION_EFFECTS)
    public void testApplyAdaptiveScaleVendorEffect() {
        VibrationEffect effect = VibrationEffect.createVendorEffect(createNonEmptyBundle());

        VibrationEffect.VendorEffect scaledUp =
                (VibrationEffect.VendorEffect) effect.applyAdaptiveScale(1.5f);
        assertEquals(1.5f, scaledUp.getAdaptiveScale());

        VibrationEffect.VendorEffect scaledDown =
                (VibrationEffect.VendorEffect) effect.applyAdaptiveScale(0.5f);
        assertEquals(0.5f, scaledDown.getAdaptiveScale());
    }

    @Test
    public void testApplyAdaptiveScaleComposed() {
        VibrationEffect effect = VibrationEffect.startComposition()
                .addPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK, 0.5f, 1)
                .addEffect(VibrationEffect.createOneShot(TEST_TIMING, /* amplitude= */ 100))
                .compose();

        VibrationEffect scaledUp = effect.applyAdaptiveScale(1.5f);
        assertThat(getPrimitiveSegment(scaledUp, 0).getScale()).isWithin(TOLERANCE).of(0.75f);
        assertThat(getStepSegment(scaledUp, 1).getAmplitude()).isWithin(TOLERANCE).of(150 / 255f);

        VibrationEffect scaledDown = effect.applyAdaptiveScale(0.5f);
        assertThat(getPrimitiveSegment(scaledDown, 0).getScale()).isWithin(TOLERANCE).of(0.25f);
        assertThat(getStepSegment(scaledDown, 1).getAmplitude()).isWithin(TOLERANCE).of(50 / 255f);
    }

    @Test
    public void testApplyEffectStrengthToOneShotWaveformAndPrimitives() {
        VibrationEffect oneShot = VibrationEffect.createOneShot(100, 100);
+2 −1
Original line number Diff line number Diff line
@@ -134,7 +134,8 @@ final class VibrationScaler {
        return effect.resolve(mDefaultVibrationAmplitude)
                .applyEffectStrength(newEffectStrength)
                .scale(scaleFactor)
                .scaleLinearly(adaptiveScale);
                // Make sure this is the last one so it is applied on top of the settings scaling.
                .applyAdaptiveScale(adaptiveScale);
    }

    /**
+6 −5
Original line number Diff line number Diff line
@@ -279,8 +279,8 @@ final class VibratorController {
                vendorEffect.getVendorData().writeToParcel(vendorData, /* flags= */ 0);
                vendorData.setDataPosition(0);
                long duration = mNativeWrapper.performVendorEffect(vendorData,
                        vendorEffect.getEffectStrength(), vendorEffect.getLinearScale(),
                        vibrationId);
                        vendorEffect.getEffectStrength(), vendorEffect.getScale(),
                        vendorEffect.getAdaptiveScale(), vibrationId);
                if (duration > 0) {
                    mCurrentAmplitude = -1;
                    notifyListenerOnVibrating(true);
@@ -459,7 +459,7 @@ final class VibratorController {
                long vibrationId);

        private static native long performVendorEffect(long nativePtr, Parcel vendorData,
                long strength, float scale, long vibrationId);
                long strength, float scale, float adaptiveScale, long vibrationId);

        private static native long performComposedEffect(long nativePtr, PrimitiveSegment[] effect,
                long vibrationId);
@@ -518,8 +518,9 @@ final class VibratorController {

        /** Turns vibrator on to perform a vendor-specific effect. */
        public long performVendorEffect(Parcel vendorData, long strength, float scale,
                long vibrationId) {
            return performVendorEffect(mNativePtr, vendorData, strength, scale, vibrationId);
                float adaptiveScale, long vibrationId) {
            return performVendorEffect(mNativePtr, vendorData, strength, scale, adaptiveScale,
                    vibrationId);
        }

        /** Turns vibrator on to perform effect composed of give primitives effect. */
Loading