Merge "Re-add scale and resolve to VibrationEffect" into main

This commit is contained in:
Treehugger Robot
2023-07-12 20:43:21 +00:00
committed by Android (Google) Code Review
2 changed files with 142 additions and 0 deletions

View File

@@ -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

View File

@@ -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;