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

Commit b5ac8648 authored by Lais Andrade's avatar Lais Andrade Committed by Android (Google) Code Review
Browse files

Merge "Use linear interpolator in VibratorInfo bandwidth curve"

parents 0caffbfc 136ca7e3
Loading
Loading
Loading
Loading
+20 −12
Original line number Diff line number Diff line
@@ -573,21 +573,29 @@ public class VibratorInfo implements Parcelable {
         * supported frequency range is empty.
         */
        public float getMaxAmplitude(float frequencyHz) {
            if (isEmpty() || Float.isNaN(frequencyHz)) {
            if (isEmpty() || Float.isNaN(frequencyHz) || !mFrequencyRangeHz.contains(frequencyHz)) {
                // Unsupported frequency requested, vibrator cannot play at this frequency.
                return 0;
            }
            float position = (frequencyHz - mMinFrequencyHz) / mFrequencyResolutionHz;
            int floorIndex = (int) Math.floor(position);
            int ceilIndex = (int) Math.ceil(position);
            if (floorIndex < 0 || floorIndex >= mMaxAmplitudes.length) {
                return 0;
            }
            if (floorIndex != ceilIndex && ceilIndex < mMaxAmplitudes.length) {
                // Value in between two mapped frequency values, use the lowest supported one.
                return MathUtils.min(mMaxAmplitudes[floorIndex], mMaxAmplitudes[ceilIndex]);
            }
            return mMaxAmplitudes[floorIndex];

            // Subtract minFrequencyHz to simplify offset calculations.
            float mappingFreq = frequencyHz - mMinFrequencyHz;

            // Find the bucket to interpolate within.
            // Any calculated index should be safe, except exactly equal to max amplitude can be
            // one step too high, so constrain it to guarantee safety.
            int startIdx = MathUtils.constrain(
                    /* amount= */ (int) Math.floor(mappingFreq / mFrequencyResolutionHz),
                    /* low= */ 0, /* high= */ mMaxAmplitudes.length - 1);
            int nextIdx = MathUtils.constrain(
                    /* amount= */ startIdx + 1,
                    /* low= */ 0, /* high= */ mMaxAmplitudes.length - 1);

            // Linearly interpolate the amplitudes based on the frequency range of the bucket.
            return MathUtils.constrainedMap(
                    mMaxAmplitudes[startIdx], mMaxAmplitudes[nextIdx],
                    startIdx * mFrequencyResolutionHz, nextIdx * mFrequencyResolutionHz,
                    mappingFreq);
        }

        /** Returns the raw list of maximum relative output accelerations from the vibrator. */
+39 −5
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ package android.os;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;

import android.hardware.vibrator.Braking;
@@ -144,6 +145,7 @@ public class VibratorInfoTest {
        assertTrue(
                new VibratorInfo.Builder(TEST_VIBRATOR_ID).build().getFrequencyProfile().isEmpty());
    }

    @Test
    public void testFrequencyProfile_invalidValuesCreatesEmptyProfile() {
        // Invalid, contains NaN values or empty array.
@@ -172,6 +174,31 @@ public class VibratorInfoTest {
                150, 50, /* frequencyResolutionHz= */ 10, TEST_AMPLITUDE_MAP).isEmpty());
    }

    @Test
    public void testGetFrequencyRangeHz_emptyProfileReturnsNull() {
        assertNull(new VibratorInfo.FrequencyProfile(
                Float.NaN, 50, 25, TEST_AMPLITUDE_MAP).getFrequencyRangeHz());
        assertNull(new VibratorInfo.FrequencyProfile(
                150, Float.NaN, 25, TEST_AMPLITUDE_MAP).getFrequencyRangeHz());
        assertNull(new VibratorInfo.FrequencyProfile(
                150, 50, Float.NaN, TEST_AMPLITUDE_MAP).getFrequencyRangeHz());
        assertNull(new VibratorInfo.FrequencyProfile(150, 50, 25, null).getFrequencyRangeHz());
    }

    @Test
    public void testGetFrequencyRangeHz_validProfileReturnsMappedValues() {
        VibratorInfo.FrequencyProfile profile = new VibratorInfo.FrequencyProfile(
                /* resonantFrequencyHz= */ 150,
                /* minFrequencyHz= */ 50,
                /* frequencyResolutionHz= */ 25,
                /* maxAmplitudes= */ new float[]{
                /* 50Hz= */ 0.1f, 0.2f, 0.4f, 0.8f, /* 150Hz= */ 1f, 0.9f,
                /* 200Hz= */ 0.8f});

        assertEquals(50f, profile.getFrequencyRangeHz().getLower(), TEST_TOLERANCE);
        assertEquals(200f, profile.getFrequencyRangeHz().getUpper(), TEST_TOLERANCE);
    }

    @Test
    public void testGetMaxAmplitude_emptyProfileReturnsAlwaysZero() {
        VibratorInfo.FrequencyProfile profile = EMPTY_FREQUENCY_PROFILE;
@@ -191,7 +218,7 @@ public class VibratorInfoTest {
    }

    @Test
    public void testGetMaxAmplitude_validprofileReturnsMappedValues() {
    public void testGetMaxAmplitude_validProfileReturnsMappedValues() {
        VibratorInfo.FrequencyProfile profile = new VibratorInfo.FrequencyProfile(
                        /* resonantFrequencyHz= */ 150,
                        /* minFrequencyHz= */ 50,
@@ -200,16 +227,23 @@ public class VibratorInfoTest {
                                /* 50Hz= */ 0.1f, 0.2f, 0.4f, 0.8f, /* 150Hz= */ 1f, 0.9f,
                                /* 200Hz= */ 0.8f});

        // Values in the max amplitudes array should return exact measurement.
        assertEquals(1f, profile.getMaxAmplitude(150f), TEST_TOLERANCE);
        assertEquals(0.9f, profile.getMaxAmplitude(175f), TEST_TOLERANCE);
        assertEquals(0.8f, profile.getMaxAmplitude(125f), TEST_TOLERANCE);

        // Min and max frequencies should return exact measurement from array.
        assertEquals(0.8f, profile.getMaxAmplitude(200f), TEST_TOLERANCE);
        assertEquals(0.1f, profile.getMaxAmplitude(50f), TEST_TOLERANCE);

        // 145Hz maps to the max amplitude for 125Hz, which is lower.
        assertEquals(0.8f, profile.getMaxAmplitude(145f), TEST_TOLERANCE); // 145Hz
        // 185Hz maps to the max amplitude for 200Hz, which is lower.
        assertEquals(0.8f, profile.getMaxAmplitude(185f), TEST_TOLERANCE); // 185Hz
        // Values outside [50Hz, 200Hz] just return 0.
        assertEquals(0f, profile.getMaxAmplitude(49f), TEST_TOLERANCE);
        assertEquals(0f, profile.getMaxAmplitude(201f), TEST_TOLERANCE);

        // 145Hz maps to linear value between 125Hz and 150Hz max amplitudes 0.8 and 1.
        assertEquals(0.96f, profile.getMaxAmplitude(145f), TEST_TOLERANCE);
        // 185Hz maps to linear value between 175Hz and 200Hz max amplitudes 0.9 and 0.8.
        assertEquals(0.86f, profile.getMaxAmplitude(185f), TEST_TOLERANCE);
    }

    @Test