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:
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user