Loading services/core/java/com/android/server/vibrator/ComposePwleV2VibratorStep.java +1 −1 Original line number Diff line number Diff line Loading @@ -94,7 +94,7 @@ final class ComposePwleV2VibratorStep extends AbstractComposedVibratorStep { // Loop once after reaching the limit to see if breaking it will really be necessary, then // apply the best break position found, otherwise return the full list as it fits the limit. for (int i = startIndex; pwlePoints.size() < limit; i++) { for (int i = startIndex; pwlePoints.size() <= limit; i++) { if (i == segmentCount) { if (repeatIndex >= 0) { i = repeatIndex; Loading services/core/java/com/android/server/vibrator/SplitPwleSegmentsAdapter.java +3 −1 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ package com.android.server.vibrator; import android.hardware.vibrator.IVibrator; import android.os.VibratorInfo; import android.os.vibrator.Flags; import android.os.vibrator.PwleSegment; import android.os.vibrator.VibrationEffectSegment; import android.util.MathUtils; Loading @@ -40,7 +41,8 @@ final class SplitPwleSegmentsAdapter implements VibrationSegmentsAdapter { @Override public int adaptToVibrator(VibratorInfo info, List<VibrationEffectSegment> segments, int repeatIndex) { if (!info.hasCapability(IVibrator.CAP_COMPOSE_PWLE_EFFECTS_V2)) { if (!Flags.normalizedPwleEffects() || !info.hasCapability(IVibrator.CAP_COMPOSE_PWLE_EFFECTS_V2)) { // The vibrator does not have PWLE v2 capability, so keep the segments unchanged. return repeatIndex; } Loading services/tests/vibrator/src/com/android/server/vibrator/SplitPwleSegmentsAdapterTest.java 0 → 100644 +150 −0 Original line number Diff line number Diff line /* * Copyright (C) 2024 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.server.vibrator; import static com.google.common.truth.Truth.assertThat; import android.hardware.vibrator.IVibrator; import android.os.VibratorInfo; import android.os.vibrator.Flags; import android.os.vibrator.PwleSegment; import android.os.vibrator.VibrationEffectSegment; import android.platform.test.annotations.DisableFlags; import android.platform.test.annotations.EnableFlags; import android.platform.test.flag.junit.SetFlagsRule; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.stream.IntStream; public class SplitPwleSegmentsAdapterTest { private static final float TEST_RESONANT_FREQUENCY = 150; private static final float[] TEST_FREQUENCIES = new float[]{90f, 120f, 150f, 60f, 30f, 210f, 270f, 300f, 240f, 180f}; private static final float[] TEST_OUTPUT_ACCELERATIONS = new float[]{1.2f, 1.8f, 2.4f, 0.6f, 0.1f, 2.2f, 1.0f, 0.5f, 1.9f, 3.0f}; private static final VibratorInfo.FrequencyProfile TEST_FREQUENCY_PROFILE = new VibratorInfo.FrequencyProfile(TEST_RESONANT_FREQUENCY, TEST_FREQUENCIES, TEST_OUTPUT_ACCELERATIONS); private SplitPwleSegmentsAdapter mAdapter; @Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(); @Before public void setUp() throws Exception { mAdapter = new SplitPwleSegmentsAdapter(); } @Test @DisableFlags(Flags.FLAG_NORMALIZED_PWLE_EFFECTS) public void testSplitPwleSegmentsAdapter_withFeatureFlagDisabled_returnsOriginalSegments() { List<VibrationEffectSegment> segments = new ArrayList<>(Arrays.asList( // startAmplitude, endAmplitude, startFrequencyHz, endFrequencyHz, duration new PwleSegment(0.0f, 1.0f, 300.0f, 300.0f, 5000))); List<VibrationEffectSegment> originalSegments = new ArrayList<>(segments); VibratorInfo vibratorInfo = createVibratorInfo( /*maxEnvelopeControlPointDuration=*/1000, TEST_FREQUENCY_PROFILE, IVibrator.CAP_COMPOSE_PWLE_EFFECTS_V2); assertThat(mAdapter.adaptToVibrator(vibratorInfo, segments, /*repeatIndex= */ -1)) .isEqualTo(-1); assertThat(mAdapter.adaptToVibrator(vibratorInfo, segments, /*repeatIndex= */ 1)) .isEqualTo(1); assertThat(segments).isEqualTo(originalSegments); } @Test @EnableFlags(Flags.FLAG_NORMALIZED_PWLE_EFFECTS) public void testSplitPwleSegmentsAdapter_noPwleCapability_returnsOriginalSegments() { List<VibrationEffectSegment> segments = new ArrayList<>(Arrays.asList( // startAmplitude, endAmplitude, startFrequencyHz, endFrequencyHz, duration new PwleSegment(0.0f, 1.0f, 300.0f, 300.0f, 5000))); List<VibrationEffectSegment> originalSegments = new ArrayList<>(segments); VibratorInfo vibratorInfo = createVibratorInfo( /*maxEnvelopeControlPointDuration=*/1000, TEST_FREQUENCY_PROFILE); assertThat(mAdapter.adaptToVibrator(vibratorInfo, segments, /*repeatIndex= */ -1)) .isEqualTo(-1); assertThat(mAdapter.adaptToVibrator(vibratorInfo, segments, /*repeatIndex= */ 1)) .isEqualTo(1); assertThat(segments).isEqualTo(originalSegments); } @Test @EnableFlags(Flags.FLAG_NORMALIZED_PWLE_EFFECTS) public void testSplitPwleSegmentsAdapter_noMaxEnvelopeEffectSize_returnsOriginalSegments() { List<VibrationEffectSegment> segments = new ArrayList<>(Arrays.asList( // startAmplitude, endAmplitude, startFrequencyHz, endFrequencyHz, duration new PwleSegment(0.0f, 1.0f, 300.0f, 300.0f, 5000))); List<VibrationEffectSegment> originalSegments = new ArrayList<>(segments); VibratorInfo vibratorInfo = createVibratorInfo(/*maxEnvelopeControlPointDuration=*/ 0, TEST_FREQUENCY_PROFILE, IVibrator.CAP_COMPOSE_PWLE_EFFECTS_V2); assertThat(mAdapter.adaptToVibrator(vibratorInfo, segments, /*repeatIndex= */ -1)) .isEqualTo(-1); assertThat(mAdapter.adaptToVibrator(vibratorInfo, segments, /*repeatIndex= */ 1)) .isEqualTo(1); assertThat(segments).isEqualTo(originalSegments); } @Test @EnableFlags(Flags.FLAG_NORMALIZED_PWLE_EFFECTS) public void testSplitPwleSegmentsAdapter_withPwleCapability_adaptSegmentsCorrectly() { List<VibrationEffectSegment> segments = new ArrayList<>(Arrays.asList( // startAmplitude, endAmplitude, startFrequencyHz, endFrequencyHz, duration new PwleSegment(0.0f, 1.0f, 200.0f, 200.0f, 1000), new PwleSegment(0.0f, 1.0f, 300.0f, 300.0f, 5000))); List<VibrationEffectSegment> expectedSegments = Arrays.asList( // startAmplitude, endAmplitude, startFrequencyHz, endFrequencyHz, duration new PwleSegment(0.0f, 1.0f, 200.0f, 200.0f, 1000), new PwleSegment(0.0f, 0.2f, 300.0f, 300.0f, 1000), new PwleSegment(0.2f, 0.4f, 300.0f, 300.0f, 1000), new PwleSegment(0.4f, 0.6f, 300.0f, 300.0f, 1000), new PwleSegment(0.6f, 0.8f, 300.0f, 300.0f, 1000), new PwleSegment(0.8f, 1.0f, 300.0f, 300.0f, 1000)); VibratorInfo vibratorInfo = createVibratorInfo( /*maxEnvelopeControlPointDuration=*/1000, TEST_FREQUENCY_PROFILE, IVibrator.CAP_COMPOSE_PWLE_EFFECTS_V2); assertThat(mAdapter.adaptToVibrator(vibratorInfo, segments, /*repeatIndex= */ 0)) .isEqualTo(0); assertThat(segments).isEqualTo(expectedSegments); } private static VibratorInfo createVibratorInfo(int maxEnvelopeControlPointDuration, VibratorInfo.FrequencyProfile frequencyProfile, int... capabilities) { return new VibratorInfo.Builder(0) .setCapabilities(IntStream.of(capabilities).reduce((a, b) -> a | b).orElse(0)) .setFrequencyProfile(frequencyProfile) .setMaxEnvelopeEffectSize(1) .setMaxEnvelopeEffectControlPointDurationMillis(maxEnvelopeControlPointDuration) .build(); } } services/tests/vibrator/src/com/android/server/vibrator/VibrationThreadTest.java +42 −0 Original line number Diff line number Diff line Loading @@ -1000,6 +1000,48 @@ public class VibrationThreadTest { } @Test @EnableFlags(android.os.vibrator.Flags.FLAG_NORMALIZED_PWLE_EFFECTS) public void vibrate_singleVibratorPwle_TooManyControlPoints_splitsAndRunsComposePwleV2() { FakeVibratorControllerProvider fakeVibrator = mVibratorProviders.get(VIBRATOR_ID); fakeVibrator.setCapabilities(IVibrator.CAP_COMPOSE_PWLE_EFFECTS_V2); fakeVibrator.setResonantFrequency(150); fakeVibrator.setFrequenciesHz(new float[]{30f, 50f, 100f, 120f, 150f}); fakeVibrator.setOutputAccelerationsGs(new float[]{0.3f, 0.5f, 1.0f, 0.8f, 0.6f}); fakeVibrator.setMaxEnvelopeEffectSize(3); fakeVibrator.setMinEnvelopeEffectControlPointDurationMillis(20); VibrationEffect effect = new VibrationEffect.WaveformEnvelopeBuilder() .addControlPoint(/*amplitude=*/ 0.8f, /*frequencyHz=*/ 100f, /*durationMillis=*/ 30) .addControlPoint(/*amplitude=*/ 0.0f, /*frequencyHz=*/ 100f, /*durationMillis=*/ 30) // Waveform will be split here, after vibration goes to zero amplitude .addControlPoint(/*amplitude=*/ 0.9f, /*frequencyHz=*/ 100f, /*durationMillis=*/ 30) .addControlPoint(/*amplitude=*/ 0.4f, /*frequencyHz=*/ 100f, /*durationMillis=*/ 30) // Waveform will be split here at lowest amplitude. .addControlPoint(/*amplitude=*/ 0.6f, /*frequencyHz=*/ 100f, /*durationMillis=*/ 30) .addControlPoint(/*amplitude=*/ 0.7f, /*frequencyHz=*/ 100f, /*durationMillis=*/ 30) .build(); HalVibration vibration = startThreadAndDispatcher(effect); waitForCompletion(); verifyCallbacksTriggered(vibration, Status.FINISHED); // Vibrator compose called 3 times with 2 segments instead of 2 times with 3 segments. // Using best split points instead of max-packing PWLEs. verify(mControllerCallbacks, times(3)).onComplete(eq(VIBRATOR_ID), eq(vibration.id)); assertFalse(mControllers.get(VIBRATOR_ID).isVibrating()); assertEquals(Arrays.asList( expectedPwle(/*amplitude=*/ 0.0f, /*frequencyHz=*/ 100f, /*timeMillis=*/ 0), expectedPwle(/*amplitude=*/ 0.8f, /*frequencyHz=*/ 100f, /*timeMillis=*/ 30), expectedPwle(/*amplitude=*/ 0.0f, /*frequencyHz=*/ 100f, /*timeMillis=*/ 30), expectedPwle(/*amplitude=*/ 0.9f, /*frequencyHz=*/ 100f, /*timeMillis=*/ 0), expectedPwle(/*amplitude=*/ 0.4f, /*frequencyHz=*/ 100f, /*timeMillis=*/ 30), expectedPwle(/*amplitude=*/ 0.6f, /*frequencyHz=*/ 100f, /*timeMillis=*/ 0), expectedPwle(/*amplitude=*/ 0.7f, /*frequencyHz=*/ 100f, /*timeMillis=*/ 30) ), fakeVibrator.getEffectPwlePoints(vibration.id)); } @Test @DisableFlags(android.os.vibrator.Flags.FLAG_NORMALIZED_PWLE_EFFECTS) public void vibrate_singleVibratorPwle_runsComposePwle() { Loading Loading
services/core/java/com/android/server/vibrator/ComposePwleV2VibratorStep.java +1 −1 Original line number Diff line number Diff line Loading @@ -94,7 +94,7 @@ final class ComposePwleV2VibratorStep extends AbstractComposedVibratorStep { // Loop once after reaching the limit to see if breaking it will really be necessary, then // apply the best break position found, otherwise return the full list as it fits the limit. for (int i = startIndex; pwlePoints.size() < limit; i++) { for (int i = startIndex; pwlePoints.size() <= limit; i++) { if (i == segmentCount) { if (repeatIndex >= 0) { i = repeatIndex; Loading
services/core/java/com/android/server/vibrator/SplitPwleSegmentsAdapter.java +3 −1 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ package com.android.server.vibrator; import android.hardware.vibrator.IVibrator; import android.os.VibratorInfo; import android.os.vibrator.Flags; import android.os.vibrator.PwleSegment; import android.os.vibrator.VibrationEffectSegment; import android.util.MathUtils; Loading @@ -40,7 +41,8 @@ final class SplitPwleSegmentsAdapter implements VibrationSegmentsAdapter { @Override public int adaptToVibrator(VibratorInfo info, List<VibrationEffectSegment> segments, int repeatIndex) { if (!info.hasCapability(IVibrator.CAP_COMPOSE_PWLE_EFFECTS_V2)) { if (!Flags.normalizedPwleEffects() || !info.hasCapability(IVibrator.CAP_COMPOSE_PWLE_EFFECTS_V2)) { // The vibrator does not have PWLE v2 capability, so keep the segments unchanged. return repeatIndex; } Loading
services/tests/vibrator/src/com/android/server/vibrator/SplitPwleSegmentsAdapterTest.java 0 → 100644 +150 −0 Original line number Diff line number Diff line /* * Copyright (C) 2024 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.server.vibrator; import static com.google.common.truth.Truth.assertThat; import android.hardware.vibrator.IVibrator; import android.os.VibratorInfo; import android.os.vibrator.Flags; import android.os.vibrator.PwleSegment; import android.os.vibrator.VibrationEffectSegment; import android.platform.test.annotations.DisableFlags; import android.platform.test.annotations.EnableFlags; import android.platform.test.flag.junit.SetFlagsRule; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.stream.IntStream; public class SplitPwleSegmentsAdapterTest { private static final float TEST_RESONANT_FREQUENCY = 150; private static final float[] TEST_FREQUENCIES = new float[]{90f, 120f, 150f, 60f, 30f, 210f, 270f, 300f, 240f, 180f}; private static final float[] TEST_OUTPUT_ACCELERATIONS = new float[]{1.2f, 1.8f, 2.4f, 0.6f, 0.1f, 2.2f, 1.0f, 0.5f, 1.9f, 3.0f}; private static final VibratorInfo.FrequencyProfile TEST_FREQUENCY_PROFILE = new VibratorInfo.FrequencyProfile(TEST_RESONANT_FREQUENCY, TEST_FREQUENCIES, TEST_OUTPUT_ACCELERATIONS); private SplitPwleSegmentsAdapter mAdapter; @Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(); @Before public void setUp() throws Exception { mAdapter = new SplitPwleSegmentsAdapter(); } @Test @DisableFlags(Flags.FLAG_NORMALIZED_PWLE_EFFECTS) public void testSplitPwleSegmentsAdapter_withFeatureFlagDisabled_returnsOriginalSegments() { List<VibrationEffectSegment> segments = new ArrayList<>(Arrays.asList( // startAmplitude, endAmplitude, startFrequencyHz, endFrequencyHz, duration new PwleSegment(0.0f, 1.0f, 300.0f, 300.0f, 5000))); List<VibrationEffectSegment> originalSegments = new ArrayList<>(segments); VibratorInfo vibratorInfo = createVibratorInfo( /*maxEnvelopeControlPointDuration=*/1000, TEST_FREQUENCY_PROFILE, IVibrator.CAP_COMPOSE_PWLE_EFFECTS_V2); assertThat(mAdapter.adaptToVibrator(vibratorInfo, segments, /*repeatIndex= */ -1)) .isEqualTo(-1); assertThat(mAdapter.adaptToVibrator(vibratorInfo, segments, /*repeatIndex= */ 1)) .isEqualTo(1); assertThat(segments).isEqualTo(originalSegments); } @Test @EnableFlags(Flags.FLAG_NORMALIZED_PWLE_EFFECTS) public void testSplitPwleSegmentsAdapter_noPwleCapability_returnsOriginalSegments() { List<VibrationEffectSegment> segments = new ArrayList<>(Arrays.asList( // startAmplitude, endAmplitude, startFrequencyHz, endFrequencyHz, duration new PwleSegment(0.0f, 1.0f, 300.0f, 300.0f, 5000))); List<VibrationEffectSegment> originalSegments = new ArrayList<>(segments); VibratorInfo vibratorInfo = createVibratorInfo( /*maxEnvelopeControlPointDuration=*/1000, TEST_FREQUENCY_PROFILE); assertThat(mAdapter.adaptToVibrator(vibratorInfo, segments, /*repeatIndex= */ -1)) .isEqualTo(-1); assertThat(mAdapter.adaptToVibrator(vibratorInfo, segments, /*repeatIndex= */ 1)) .isEqualTo(1); assertThat(segments).isEqualTo(originalSegments); } @Test @EnableFlags(Flags.FLAG_NORMALIZED_PWLE_EFFECTS) public void testSplitPwleSegmentsAdapter_noMaxEnvelopeEffectSize_returnsOriginalSegments() { List<VibrationEffectSegment> segments = new ArrayList<>(Arrays.asList( // startAmplitude, endAmplitude, startFrequencyHz, endFrequencyHz, duration new PwleSegment(0.0f, 1.0f, 300.0f, 300.0f, 5000))); List<VibrationEffectSegment> originalSegments = new ArrayList<>(segments); VibratorInfo vibratorInfo = createVibratorInfo(/*maxEnvelopeControlPointDuration=*/ 0, TEST_FREQUENCY_PROFILE, IVibrator.CAP_COMPOSE_PWLE_EFFECTS_V2); assertThat(mAdapter.adaptToVibrator(vibratorInfo, segments, /*repeatIndex= */ -1)) .isEqualTo(-1); assertThat(mAdapter.adaptToVibrator(vibratorInfo, segments, /*repeatIndex= */ 1)) .isEqualTo(1); assertThat(segments).isEqualTo(originalSegments); } @Test @EnableFlags(Flags.FLAG_NORMALIZED_PWLE_EFFECTS) public void testSplitPwleSegmentsAdapter_withPwleCapability_adaptSegmentsCorrectly() { List<VibrationEffectSegment> segments = new ArrayList<>(Arrays.asList( // startAmplitude, endAmplitude, startFrequencyHz, endFrequencyHz, duration new PwleSegment(0.0f, 1.0f, 200.0f, 200.0f, 1000), new PwleSegment(0.0f, 1.0f, 300.0f, 300.0f, 5000))); List<VibrationEffectSegment> expectedSegments = Arrays.asList( // startAmplitude, endAmplitude, startFrequencyHz, endFrequencyHz, duration new PwleSegment(0.0f, 1.0f, 200.0f, 200.0f, 1000), new PwleSegment(0.0f, 0.2f, 300.0f, 300.0f, 1000), new PwleSegment(0.2f, 0.4f, 300.0f, 300.0f, 1000), new PwleSegment(0.4f, 0.6f, 300.0f, 300.0f, 1000), new PwleSegment(0.6f, 0.8f, 300.0f, 300.0f, 1000), new PwleSegment(0.8f, 1.0f, 300.0f, 300.0f, 1000)); VibratorInfo vibratorInfo = createVibratorInfo( /*maxEnvelopeControlPointDuration=*/1000, TEST_FREQUENCY_PROFILE, IVibrator.CAP_COMPOSE_PWLE_EFFECTS_V2); assertThat(mAdapter.adaptToVibrator(vibratorInfo, segments, /*repeatIndex= */ 0)) .isEqualTo(0); assertThat(segments).isEqualTo(expectedSegments); } private static VibratorInfo createVibratorInfo(int maxEnvelopeControlPointDuration, VibratorInfo.FrequencyProfile frequencyProfile, int... capabilities) { return new VibratorInfo.Builder(0) .setCapabilities(IntStream.of(capabilities).reduce((a, b) -> a | b).orElse(0)) .setFrequencyProfile(frequencyProfile) .setMaxEnvelopeEffectSize(1) .setMaxEnvelopeEffectControlPointDurationMillis(maxEnvelopeControlPointDuration) .build(); } }
services/tests/vibrator/src/com/android/server/vibrator/VibrationThreadTest.java +42 −0 Original line number Diff line number Diff line Loading @@ -1000,6 +1000,48 @@ public class VibrationThreadTest { } @Test @EnableFlags(android.os.vibrator.Flags.FLAG_NORMALIZED_PWLE_EFFECTS) public void vibrate_singleVibratorPwle_TooManyControlPoints_splitsAndRunsComposePwleV2() { FakeVibratorControllerProvider fakeVibrator = mVibratorProviders.get(VIBRATOR_ID); fakeVibrator.setCapabilities(IVibrator.CAP_COMPOSE_PWLE_EFFECTS_V2); fakeVibrator.setResonantFrequency(150); fakeVibrator.setFrequenciesHz(new float[]{30f, 50f, 100f, 120f, 150f}); fakeVibrator.setOutputAccelerationsGs(new float[]{0.3f, 0.5f, 1.0f, 0.8f, 0.6f}); fakeVibrator.setMaxEnvelopeEffectSize(3); fakeVibrator.setMinEnvelopeEffectControlPointDurationMillis(20); VibrationEffect effect = new VibrationEffect.WaveformEnvelopeBuilder() .addControlPoint(/*amplitude=*/ 0.8f, /*frequencyHz=*/ 100f, /*durationMillis=*/ 30) .addControlPoint(/*amplitude=*/ 0.0f, /*frequencyHz=*/ 100f, /*durationMillis=*/ 30) // Waveform will be split here, after vibration goes to zero amplitude .addControlPoint(/*amplitude=*/ 0.9f, /*frequencyHz=*/ 100f, /*durationMillis=*/ 30) .addControlPoint(/*amplitude=*/ 0.4f, /*frequencyHz=*/ 100f, /*durationMillis=*/ 30) // Waveform will be split here at lowest amplitude. .addControlPoint(/*amplitude=*/ 0.6f, /*frequencyHz=*/ 100f, /*durationMillis=*/ 30) .addControlPoint(/*amplitude=*/ 0.7f, /*frequencyHz=*/ 100f, /*durationMillis=*/ 30) .build(); HalVibration vibration = startThreadAndDispatcher(effect); waitForCompletion(); verifyCallbacksTriggered(vibration, Status.FINISHED); // Vibrator compose called 3 times with 2 segments instead of 2 times with 3 segments. // Using best split points instead of max-packing PWLEs. verify(mControllerCallbacks, times(3)).onComplete(eq(VIBRATOR_ID), eq(vibration.id)); assertFalse(mControllers.get(VIBRATOR_ID).isVibrating()); assertEquals(Arrays.asList( expectedPwle(/*amplitude=*/ 0.0f, /*frequencyHz=*/ 100f, /*timeMillis=*/ 0), expectedPwle(/*amplitude=*/ 0.8f, /*frequencyHz=*/ 100f, /*timeMillis=*/ 30), expectedPwle(/*amplitude=*/ 0.0f, /*frequencyHz=*/ 100f, /*timeMillis=*/ 30), expectedPwle(/*amplitude=*/ 0.9f, /*frequencyHz=*/ 100f, /*timeMillis=*/ 0), expectedPwle(/*amplitude=*/ 0.4f, /*frequencyHz=*/ 100f, /*timeMillis=*/ 30), expectedPwle(/*amplitude=*/ 0.6f, /*frequencyHz=*/ 100f, /*timeMillis=*/ 0), expectedPwle(/*amplitude=*/ 0.7f, /*frequencyHz=*/ 100f, /*timeMillis=*/ 30) ), fakeVibrator.getEffectPwlePoints(vibration.id)); } @Test @DisableFlags(android.os.vibrator.Flags.FLAG_NORMALIZED_PWLE_EFFECTS) public void vibrate_singleVibratorPwle_runsComposePwle() { Loading