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


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


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


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


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


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


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

        public float getAdaptiveScale() {
            return mAdaptiveScale;
        }
        }


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


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


        @Override
        @Override
        public int hashCode() {
        public int hashCode() {
            // PersistableBundle does not implement hashCode, so use its size as a shortcut.
            // 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
        @Override
        public String toString() {
        public String toString() {
            return String.format(Locale.ROOT,
            return String.format(Locale.ROOT,
                    "VendorEffect{vendorData=%s, strength=%s, scale=%.2f}",
                    "VendorEffect{vendorData=%s, strength=%s, scale=%.2f, adaptiveScale=%.2f}",
                    mVendorData, effectStrengthToString(mEffectStrength), mLinearScale);
                    mVendorData, effectStrengthToString(mEffectStrength), mScale, mAdaptiveScale);
        }
        }


        /** @hide */
        /** @hide */
        @Override
        @Override
        public String toDebugString() {
        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),
                    mVendorData.toShortString(), effectStrengthToString(mEffectStrength),
                    mLinearScale);
                    mScale, mAdaptiveScale);
        }
        }


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


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


@RunWith(MockitoJUnitRunner.class)
@RunWith(MockitoJUnitRunner.class)
public class VibrationEffectTest {
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_1 = "content://test/system/ringtone_1";
    private static final String RINGTONE_URI_2 = "content://test/system/ringtone_2";
    private static final String RINGTONE_URI_2 = "content://test/system/ringtone_2";
    private static final String RINGTONE_URI_3 = "content://test/system/ringtone_3";
    private static final String RINGTONE_URI_3 = "content://test/system/ringtone_3";
@@ -709,7 +709,7 @@ public class VibrationEffectTest {
    @Test
    @Test
    public void testScaleWaveform() {
    public void testScaleWaveform() {
        VibrationEffect scaledUp = TEST_WAVEFORM.scale(1.5f);
        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);
        VibrationEffect scaledDown = TEST_WAVEFORM.scale(0.5f);
        assertTrue(1f > getStepSegment(scaledDown, 0).getAmplitude());
        assertTrue(1f > getStepSegment(scaledDown, 0).getAmplitude());
@@ -731,11 +731,11 @@ public class VibrationEffectTest {
    public void testScaleVendorEffect() {
    public void testScaleVendorEffect() {
        VibrationEffect effect = VibrationEffect.createVendorEffect(createNonEmptyBundle());
        VibrationEffect effect = VibrationEffect.createVendorEffect(createNonEmptyBundle());


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


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


    @Test
    @Test
@@ -754,6 +754,70 @@ public class VibrationEffectTest {
        assertTrue(100 / 255f > getStepSegment(scaledDown, 1).getAmplitude());
        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
    @Test
    public void testApplyEffectStrengthToOneShotWaveformAndPrimitives() {
    public void testApplyEffectStrengthToOneShotWaveformAndPrimitives() {
        VibrationEffect oneShot = VibrationEffect.createOneShot(100, 100);
        VibrationEffect oneShot = VibrationEffect.createOneShot(100, 100);
+2 −1
Original line number Original line Diff line number Diff line
@@ -134,7 +134,8 @@ final class VibrationScaler {
        return effect.resolve(mDefaultVibrationAmplitude)
        return effect.resolve(mDefaultVibrationAmplitude)
                .applyEffectStrength(newEffectStrength)
                .applyEffectStrength(newEffectStrength)
                .scale(scaleFactor)
                .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 Original line Diff line number Diff line
@@ -279,8 +279,8 @@ final class VibratorController {
                vendorEffect.getVendorData().writeToParcel(vendorData, /* flags= */ 0);
                vendorEffect.getVendorData().writeToParcel(vendorData, /* flags= */ 0);
                vendorData.setDataPosition(0);
                vendorData.setDataPosition(0);
                long duration = mNativeWrapper.performVendorEffect(vendorData,
                long duration = mNativeWrapper.performVendorEffect(vendorData,
                        vendorEffect.getEffectStrength(), vendorEffect.getLinearScale(),
                        vendorEffect.getEffectStrength(), vendorEffect.getScale(),
                        vibrationId);
                        vendorEffect.getAdaptiveScale(), vibrationId);
                if (duration > 0) {
                if (duration > 0) {
                    mCurrentAmplitude = -1;
                    mCurrentAmplitude = -1;
                    notifyListenerOnVibrating(true);
                    notifyListenerOnVibrating(true);
@@ -459,7 +459,7 @@ final class VibratorController {
                long vibrationId);
                long vibrationId);


        private static native long performVendorEffect(long nativePtr, Parcel vendorData,
        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,
        private static native long performComposedEffect(long nativePtr, PrimitiveSegment[] effect,
                long vibrationId);
                long vibrationId);
@@ -518,8 +518,9 @@ final class VibratorController {


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


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