Constrain scaled amplitude to valid values in [1,255]

Scaling down low amplitudes can lead to one-shot effects with amplitude
zero, which leads to an invalid VibrationEffect and causes
IllegalArgumentException to be thrown on an originally valid effect.

Bug: 179674498
Test: VibrationEffectTest
Change-Id: Ie653084d37f9bfed20aac25f8805ffdf40661e03
This commit is contained in:
Lais Andrade
2021-02-08 16:35:36 +00:00
parent 8a6a2bce6c
commit 2356453306
2 changed files with 26 additions and 4 deletions

View File

@@ -437,7 +437,11 @@ public abstract class VibrationEffect implements Parcelable {
* @hide
*/
protected static int scale(int amplitude, float scaleFactor) {
return (int) (scale((float) amplitude / MAX_AMPLITUDE, scaleFactor) * MAX_AMPLITUDE);
if (amplitude == 0) {
return 0;
}
int scaled = (int) (scale((float) amplitude / MAX_AMPLITUDE, scaleFactor) * MAX_AMPLITUDE);
return MathUtils.constrain(scaled, 1, MAX_AMPLITUDE);
}
/**
@@ -473,7 +477,7 @@ public abstract class VibrationEffect implements Parcelable {
float a = (expMaxX + 1f) / (expMaxX - 1f);
float fx = (expX - 1f) / (expX + 1f);
return a * fx;
return MathUtils.constrain(a * fx, 0f, 1f);
}
/** @hide */
@@ -536,9 +540,10 @@ public abstract class VibrationEffect implements Parcelable {
/** @hide */
@Override
public OneShot resolve(int defaultAmplitude) {
if (defaultAmplitude > MAX_AMPLITUDE || defaultAmplitude < 0) {
if (defaultAmplitude > MAX_AMPLITUDE || defaultAmplitude <= 0) {
throw new IllegalArgumentException(
"Amplitude is negative or greater than MAX_AMPLITUDE");
"amplitude must be between 1 and 255 inclusive (amplitude="
+ defaultAmplitude + ")");
}
if (mAmplitude == DEFAULT_AMPLITUDE) {
return new OneShot(mDuration, defaultAmplitude);

View File

@@ -220,6 +220,10 @@ public class VibrationEffectTest {
restored = scaledDown.scale(1.25f);
// Does not restore to the exact original value because scale up is a bit offset.
assertEquals(101, restored.getAmplitude(), AMPLITUDE_SCALE_TOLERANCE);
// Does not go below min amplitude while scaling down.
VibrationEffect.OneShot minAmplitude = new VibrationEffect.OneShot(TEST_TIMING, 1);
assertEquals(1, minAmplitude.scale(0.5f).getAmplitude());
}
@Test
@@ -244,6 +248,15 @@ public class VibrationEffectTest {
}
}
@Test
public void testResolveOneshotFailsWhenAmplitudeNonPositive() {
try {
TEST_ONE_SHOT.resolve(0);
fail("Amplitude is set to zero, should throw IllegalArgumentException");
} catch (IllegalArgumentException expected) {
}
}
@Test
public void testScaleWaveform() {
VibrationEffect.Waveform initial = (VibrationEffect.Waveform) TEST_WAVEFORM;
@@ -255,6 +268,10 @@ public class VibrationEffectTest {
assertEquals(216, scaled.getAmplitudes()[0], AMPLITUDE_SCALE_TOLERANCE);
assertEquals(0, scaled.getAmplitudes()[1]);
assertEquals(-1, scaled.getAmplitudes()[2]);
VibrationEffect.Waveform minAmplitude = new VibrationEffect.Waveform(
new long[]{100}, new int[] {1}, -1);
assertArrayEquals(new int[]{1}, minAmplitude.scale(0.5f).getAmplitudes());
}
@Test