Merge "Create API to Compute Vibration Pattern Equivalent to a VibrationEffect"
This commit is contained in:
committed by
Android (Google) Code Review
commit
c04d8de7c4
@@ -1908,6 +1908,7 @@ package android.os {
|
||||
}
|
||||
|
||||
public abstract class VibrationEffect implements android.os.Parcelable {
|
||||
method @Nullable public abstract long[] computeCreateWaveformOffOnTimingsOrNull();
|
||||
method public static android.os.VibrationEffect get(int);
|
||||
method public static android.os.VibrationEffect get(int, boolean);
|
||||
method @Nullable public static android.os.VibrationEffect get(android.net.Uri, android.content.Context);
|
||||
@@ -1922,6 +1923,7 @@ package android.os {
|
||||
}
|
||||
|
||||
public static final class VibrationEffect.Composed extends android.os.VibrationEffect {
|
||||
method @Nullable public long[] computeCreateWaveformOffOnTimingsOrNull();
|
||||
method public long getDuration();
|
||||
method public int getRepeatIndex();
|
||||
method @NonNull public java.util.List<android.os.vibrator.VibrationEffectSegment> getSegments();
|
||||
|
||||
@@ -226,6 +226,31 @@ public abstract class VibrationEffect implements Parcelable {
|
||||
return createWaveform(timings, amplitudes, repeat);
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes a legacy vibration pattern (i.e. a pattern with duration values for "off/on"
|
||||
* vibration components) that is equivalent to this VibrationEffect.
|
||||
*
|
||||
* <p>All non-repeating effects created with {@link #createWaveform(int[], int)} are convertible
|
||||
* into an equivalent vibration pattern with this method. It is not guaranteed that an effect
|
||||
* created with other means becomes converted into an equivalent legacy vibration pattern, even
|
||||
* if it has an equivalent vibration pattern. If this method is unable to create an equivalent
|
||||
* vibration pattern for such effects, it will return {@code null}.
|
||||
*
|
||||
* <p>Note that a valid equivalent long[] pattern cannot be created for an effect that has any
|
||||
* form of repeating behavior, regardless of how the effect was created. For repeating effects,
|
||||
* the method will always return {@code null}.
|
||||
*
|
||||
* @return a long array representing a vibration pattern equivalent to the VibrationEffect, if
|
||||
* the method successfully derived a vibration pattern equivalent to the effect
|
||||
* (this will always be the case if the effect was created via
|
||||
* {@link #createWaveform(int[], int)} and is non-repeating). Otherwise, returns
|
||||
* {@code null}.
|
||||
* @hide
|
||||
*/
|
||||
@TestApi
|
||||
@Nullable
|
||||
public abstract long[] computeCreateWaveformOffOnTimingsOrNull();
|
||||
|
||||
/**
|
||||
* Create a waveform vibration.
|
||||
*
|
||||
@@ -641,6 +666,51 @@ public abstract class VibrationEffect implements Parcelable {
|
||||
return mRepeatIndex;
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
@Override
|
||||
@Nullable
|
||||
public long[] computeCreateWaveformOffOnTimingsOrNull() {
|
||||
if (getRepeatIndex() >= 0) {
|
||||
// Repeating effects cannot be fully represented as a long[] legacy pattern.
|
||||
return null;
|
||||
}
|
||||
|
||||
List<VibrationEffectSegment> segments = getSegments();
|
||||
|
||||
// The maximum possible size of the final pattern is 1 plus the number of segments in
|
||||
// the original effect. This is because we will add an empty "off" segment at the
|
||||
// start of the pattern if the first segment of the original effect is an "on" segment.
|
||||
// (because the legacy patterns start with an "off" pattern). Other than this one case,
|
||||
// we will add the durations of back-to-back segments of similar amplitudes (amplitudes
|
||||
// that are all "on" or "off") and create a pattern entry for the total duration, which
|
||||
// will not take more number pattern entries than the number of segments processed.
|
||||
long[] patternBuffer = new long[segments.size() + 1];
|
||||
int patternIndex = 0;
|
||||
|
||||
for (int i = 0; i < segments.size(); i++) {
|
||||
StepSegment stepSegment =
|
||||
castToValidStepSegmentForOffOnTimingsOrNull(segments.get(i));
|
||||
if (stepSegment == null) {
|
||||
// This means that there is 1 or more segments of this effect that is/are not a
|
||||
// possible component of a legacy vibration pattern. Thus, the VibrationEffect
|
||||
// does not have any equivalent legacy vibration pattern.
|
||||
return null;
|
||||
}
|
||||
|
||||
boolean isSegmentOff = stepSegment.getAmplitude() == 0;
|
||||
// Even pattern indices are "off", and odd pattern indices are "on"
|
||||
boolean isCurrentPatternIndexOff = (patternIndex % 2) == 0;
|
||||
if (isSegmentOff != isCurrentPatternIndexOff) {
|
||||
// Move the pattern index one step ahead, so that the current segment's
|
||||
// "off"/"on" property matches that of the index's
|
||||
++patternIndex;
|
||||
}
|
||||
patternBuffer[patternIndex] += stepSegment.getDuration();
|
||||
}
|
||||
|
||||
return Arrays.copyOf(patternBuffer, patternIndex + 1);
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
@Override
|
||||
public void validate() {
|
||||
@@ -806,6 +876,31 @@ public abstract class VibrationEffect implements Parcelable {
|
||||
return new Composed[size];
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Casts a provided {@link VibrationEffectSegment} to a {@link StepSegment} and returns it,
|
||||
* only if it can possibly be a segment for an effect created via
|
||||
* {@link #createWaveform(int[], int)}. Otherwise, returns {@code null}.
|
||||
*/
|
||||
@Nullable
|
||||
private static StepSegment castToValidStepSegmentForOffOnTimingsOrNull(
|
||||
VibrationEffectSegment segment) {
|
||||
if (!(segment instanceof StepSegment)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
StepSegment stepSegment = (StepSegment) segment;
|
||||
if (stepSegment.getFrequencyHz() != 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
float amplitude = stepSegment.getAmplitude();
|
||||
if (amplitude != 0 && amplitude != DEFAULT_AMPLITUDE) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return stepSegment;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package android.os;
|
||||
|
||||
import static android.os.VibrationEffect.DEFAULT_AMPLITUDE;
|
||||
import static android.os.VibrationEffect.VibrationParameter.targetAmplitude;
|
||||
import static android.os.VibrationEffect.VibrationParameter.targetFrequency;
|
||||
|
||||
@@ -48,6 +49,7 @@ import org.junit.runner.RunWith;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.Arrays;
|
||||
|
||||
@Presubmit
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
@@ -62,15 +64,362 @@ public class VibrationEffectTest {
|
||||
private static final int TEST_AMPLITUDE = 100;
|
||||
private static final long[] TEST_TIMINGS = new long[] { 100, 100, 200 };
|
||||
private static final int[] TEST_AMPLITUDES =
|
||||
new int[] { 255, 0, VibrationEffect.DEFAULT_AMPLITUDE };
|
||||
new int[] { 255, 0, DEFAULT_AMPLITUDE };
|
||||
|
||||
private static final VibrationEffect TEST_ONE_SHOT =
|
||||
VibrationEffect.createOneShot(TEST_TIMING, TEST_AMPLITUDE);
|
||||
private static final VibrationEffect DEFAULT_ONE_SHOT =
|
||||
VibrationEffect.createOneShot(TEST_TIMING, VibrationEffect.DEFAULT_AMPLITUDE);
|
||||
VibrationEffect.createOneShot(TEST_TIMING, DEFAULT_AMPLITUDE);
|
||||
private static final VibrationEffect TEST_WAVEFORM =
|
||||
VibrationEffect.createWaveform(TEST_TIMINGS, TEST_AMPLITUDES, -1);
|
||||
|
||||
@Test
|
||||
public void computeLegacyPattern_timingsAndAmplitudes_zeroAmplitudesOnEvenIndices() {
|
||||
VibrationEffect effect = VibrationEffect.createWaveform(
|
||||
/* timings= */ new long[] {1, 2, 3, 4, 5},
|
||||
/* amplitudes= */ new int[] {0, DEFAULT_AMPLITUDE, 0, DEFAULT_AMPLITUDE, 0},
|
||||
/* repeatIndex= */ -1);
|
||||
long[] expectedPattern = new long[] {1, 2, 3, 4, 5};
|
||||
|
||||
assertArrayEq(expectedPattern, effect.computeCreateWaveformOffOnTimingsOrNull());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void computeLegacyPattern_timingsAndAmplitudes_zeroAmplitudesOnOddIndices() {
|
||||
VibrationEffect effect = VibrationEffect.createWaveform(
|
||||
/* timings= */ new long[] {1, 2, 3, 4, 5},
|
||||
/* amplitudes= */ new int[] {
|
||||
DEFAULT_AMPLITUDE, 0, DEFAULT_AMPLITUDE, 0, DEFAULT_AMPLITUDE},
|
||||
/* repeatIndex= */ -1);
|
||||
long[] expectedPattern = new long[] {0, 1, 2, 3, 4, 5};
|
||||
|
||||
assertArrayEq(expectedPattern, effect.computeCreateWaveformOffOnTimingsOrNull());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void computeLegacyPattern_timingsAndAmplitudes_zeroAmplitudesAtTheStart() {
|
||||
VibrationEffect effect = VibrationEffect.createWaveform(
|
||||
/* timings= */ new long[] {1, 2, 3},
|
||||
/* amplitudes= */ new int[] {0, 0, DEFAULT_AMPLITUDE},
|
||||
/* repeatIndex= */ -1);
|
||||
long[] expectedPattern = new long[] {3, 3};
|
||||
|
||||
assertArrayEq(expectedPattern, effect.computeCreateWaveformOffOnTimingsOrNull());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void computeLegacyPattern_timingsAndAmplitudes_zeroAmplitudesAtTheEnd() {
|
||||
VibrationEffect effect = VibrationEffect.createWaveform(
|
||||
/* timings= */ new long[] {1, 2, 3},
|
||||
/* amplitudes= */ new int[] {DEFAULT_AMPLITUDE, 0, 0},
|
||||
/* repeatIndex= */ -1);
|
||||
long[] expectedPattern = new long[] {0, 1, 5};
|
||||
|
||||
assertArrayEq(expectedPattern, effect.computeCreateWaveformOffOnTimingsOrNull());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void computeLegacyPattern_timingsAndAmplitudes_allDefaultAmplitudes() {
|
||||
VibrationEffect effect = VibrationEffect.createWaveform(
|
||||
/* timings= */ new long[] {1, 2, 3},
|
||||
/* amplitudes= */ new int[] {
|
||||
DEFAULT_AMPLITUDE, DEFAULT_AMPLITUDE, DEFAULT_AMPLITUDE},
|
||||
/* repeatIndex= */ -1);
|
||||
long[] expectedPattern = new long[] {0, 6};
|
||||
|
||||
assertArrayEq(expectedPattern, effect.computeCreateWaveformOffOnTimingsOrNull());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void computeLegacyPattern_timingsAndAmplitudes_allZeroAmplitudes() {
|
||||
VibrationEffect effect = VibrationEffect.createWaveform(
|
||||
/* timings= */ new long[] {1, 2, 3},
|
||||
/* amplitudes= */ new int[] {0, 0, 0},
|
||||
/* repeatIndex= */ -1);
|
||||
long[] expectedPattern = new long[] {6};
|
||||
|
||||
assertArrayEq(expectedPattern, effect.computeCreateWaveformOffOnTimingsOrNull());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void computeLegacyPattern_timingsAndAmplitudes_sparsedZeroAmplitudes() {
|
||||
VibrationEffect effect = VibrationEffect.createWaveform(
|
||||
/* timings= */ new long[] {1, 2, 3, 4, 5, 6, 7},
|
||||
/* amplitudes= */ new int[] {
|
||||
0, 0, DEFAULT_AMPLITUDE, 0, DEFAULT_AMPLITUDE, DEFAULT_AMPLITUDE, 0},
|
||||
/* repeatIndex= */ -1);
|
||||
long[] expectedPattern = new long[] {3, 3, 4, 11, 7};
|
||||
|
||||
assertArrayEq(expectedPattern, effect.computeCreateWaveformOffOnTimingsOrNull());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void computeLegacyPattern_timingsAndAmplitudes_oneTimingWithDefaultAmplitude() {
|
||||
VibrationEffect effect = VibrationEffect.createWaveform(
|
||||
/* timings= */ new long[] {1},
|
||||
/* amplitudes= */ new int[] {DEFAULT_AMPLITUDE},
|
||||
/* repeatIndex= */ -1);
|
||||
long[] expectedPattern = new long[] {0, 1};
|
||||
|
||||
assertArrayEq(expectedPattern, effect.computeCreateWaveformOffOnTimingsOrNull());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void computeLegacyPattern_timingsAndAmplitudes_oneTimingWithZeroAmplitude() {
|
||||
VibrationEffect effect = VibrationEffect.createWaveform(
|
||||
/* timings= */ new long[] {1},
|
||||
/* amplitudes= */ new int[] {0},
|
||||
/* repeatIndex= */ -1);
|
||||
long[] expectedPattern = new long[] {1};
|
||||
|
||||
assertArrayEq(expectedPattern, effect.computeCreateWaveformOffOnTimingsOrNull());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void computeLegacyPattern_timingsAndAmplitudes_repeating() {
|
||||
VibrationEffect effect = VibrationEffect.createWaveform(
|
||||
/* timings= */ new long[] {1, 2, 3, 4, 5},
|
||||
/* amplitudes= */ new int[] {0, DEFAULT_AMPLITUDE, 0, DEFAULT_AMPLITUDE, 0},
|
||||
/* repeatIndex= */ 0);
|
||||
|
||||
assertNull(effect.computeCreateWaveformOffOnTimingsOrNull());
|
||||
|
||||
effect = VibrationEffect.createWaveform(
|
||||
/* timings= */ new long[] {1, 2, 3, 4, 5},
|
||||
/* amplitudes= */ new int[] {0, DEFAULT_AMPLITUDE, 0, DEFAULT_AMPLITUDE, 0},
|
||||
/* repeatIndex= */ 3);
|
||||
|
||||
assertNull(effect.computeCreateWaveformOffOnTimingsOrNull());
|
||||
|
||||
effect = VibrationEffect.createWaveform(
|
||||
/* timings= */ new long[] {1, 2},
|
||||
/* amplitudes= */ new int[] {DEFAULT_AMPLITUDE, DEFAULT_AMPLITUDE},
|
||||
/* repeatIndex= */ 1);
|
||||
|
||||
assertNull(effect.computeCreateWaveformOffOnTimingsOrNull());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void computeLegacyPattern_timingsAndAmplitudes_badAmplitude() {
|
||||
VibrationEffect effect = VibrationEffect.createWaveform(
|
||||
/* timings= */ new long[] {1},
|
||||
/* amplitudes= */ new int[] {200},
|
||||
/* repeatIndex= */ -1);
|
||||
|
||||
assertNull(effect.computeCreateWaveformOffOnTimingsOrNull());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void computeLegacyPattern_timingsOnly_nonZeroTimings() {
|
||||
VibrationEffect effect = VibrationEffect.createWaveform(
|
||||
/* timings= */ new long[] {1, 2, 3},
|
||||
/* repeatIndex= */ -1);
|
||||
long[] expectedPattern = new long[] {1, 2, 3};
|
||||
|
||||
assertArrayEq(expectedPattern, effect.computeCreateWaveformOffOnTimingsOrNull());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void computeLegacyPattern_timingsOnly_oneValue() {
|
||||
VibrationEffect effect = VibrationEffect.createWaveform(
|
||||
/* timings= */ new long[] {5},
|
||||
/* repeatIndex= */ -1);
|
||||
long[] expectedPattern = new long[] {5};
|
||||
|
||||
assertArrayEq(expectedPattern, effect.computeCreateWaveformOffOnTimingsOrNull());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void computeLegacyPattern_timingsOnly_zeroesAtTheEnd() {
|
||||
VibrationEffect effect = VibrationEffect.createWaveform(
|
||||
/* timings= */ new long[] {1, 2, 3, 0, 0},
|
||||
/* repeatIndex= */ -1);
|
||||
long[] expectedPattern = new long[] {1, 2, 3, 0, 0};
|
||||
|
||||
assertArrayEq(expectedPattern, effect.computeCreateWaveformOffOnTimingsOrNull());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void computeLegacyPattern_timingsOnly_zeroesAtTheStart() {
|
||||
VibrationEffect effect = VibrationEffect.createWaveform(
|
||||
/* timings= */ new long[] {0, 0, 1, 2, 3},
|
||||
/* repeatIndex= */ -1);
|
||||
long[] expectedPattern = new long[] {0, 0, 1, 2, 3};
|
||||
|
||||
assertArrayEq(expectedPattern, effect.computeCreateWaveformOffOnTimingsOrNull());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void computeLegacyPattern_timingsOnly_zeroesAtTheMiddle() {
|
||||
VibrationEffect effect = VibrationEffect.createWaveform(
|
||||
/* timings= */ new long[] {1, 2, 0, 0, 3, 4, 5},
|
||||
/* repeatIndex= */ -1);
|
||||
long[] expectedPattern = new long[] {1, 2, 0, 0, 3, 4, 5};
|
||||
|
||||
assertArrayEq(expectedPattern, effect.computeCreateWaveformOffOnTimingsOrNull());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void computeLegacyPattern_timingsOnly_sparsedZeroes() {
|
||||
VibrationEffect effect = VibrationEffect.createWaveform(
|
||||
/* timings= */ new long[] {0, 1, 2, 0, 0, 3, 4, 5, 0},
|
||||
/* repeatIndex= */ -1);
|
||||
long[] expectedPattern = new long[] {0, 1, 2, 0, 0, 3, 4, 5, 0};
|
||||
|
||||
assertArrayEq(expectedPattern, effect.computeCreateWaveformOffOnTimingsOrNull());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void computeLegacyPattern_timingsOnly_repeating() {
|
||||
VibrationEffect effect = VibrationEffect.createWaveform(
|
||||
/* timings= */ new long[] {0, 1, 2, 0, 0, 3, 4, 5, 0},
|
||||
/* repeatIndex= */ 0);
|
||||
|
||||
assertNull(effect.computeCreateWaveformOffOnTimingsOrNull());
|
||||
|
||||
effect = VibrationEffect.createWaveform(
|
||||
/* timings= */ new long[] {1, 2, 3, 4},
|
||||
/* repeatIndex= */ 2);
|
||||
|
||||
assertNull(effect.computeCreateWaveformOffOnTimingsOrNull());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void computeLegacyPattern_notPatternPased() {
|
||||
VibrationEffect effect = VibrationEffect.createPredefined(VibrationEffect.EFFECT_CLICK);
|
||||
|
||||
assertNull(effect.computeCreateWaveformOffOnTimingsOrNull());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void computeLegacyPattern_oneShot_defaultAmplitude() {
|
||||
VibrationEffect effect = VibrationEffect.createOneShot(
|
||||
/* milliseconds= */ 5, /* ampliutde= */ DEFAULT_AMPLITUDE);
|
||||
long[] expectedPattern = new long[] {0, 5};
|
||||
|
||||
assertArrayEq(expectedPattern, effect.computeCreateWaveformOffOnTimingsOrNull());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void computeLegacyPattern_oneShot_badAmplitude() {
|
||||
VibrationEffect effect = VibrationEffect.createOneShot(
|
||||
/* milliseconds= */ 5, /* ampliutde= */ 50);
|
||||
|
||||
assertNull(effect.computeCreateWaveformOffOnTimingsOrNull());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void computeLegacyPattern_composition_noOffDuration() {
|
||||
VibrationEffect effect = VibrationEffect.startComposition()
|
||||
.addEffect(
|
||||
VibrationEffect.createWaveform(
|
||||
/* timings= */ new long[] {5},
|
||||
/* repeatIndex= */ -1))
|
||||
.addEffect(
|
||||
VibrationEffect.createWaveform(
|
||||
/* timings= */ new long[] {2, 3},
|
||||
/* repeatIndex= */ -1))
|
||||
.addEffect(
|
||||
VibrationEffect.createWaveform(
|
||||
/* timings= */ new long[] {10, 20},
|
||||
/* amplitudes= */ new int[] {DEFAULT_AMPLITUDE, DEFAULT_AMPLITUDE},
|
||||
/* repeatIndex= */ -1))
|
||||
.addEffect(
|
||||
VibrationEffect.createWaveform(
|
||||
/* timings= */ new long[] {4, 5},
|
||||
/* amplitudes= */ new int[] {0, DEFAULT_AMPLITUDE},
|
||||
/* repeatIndex= */ -1))
|
||||
.compose();
|
||||
long[] expectedPattern = new long[] {7, 33, 4, 5};
|
||||
|
||||
assertArrayEq(expectedPattern, effect.computeCreateWaveformOffOnTimingsOrNull());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void computeLegacyPattern_composition_withOffDuration() {
|
||||
VibrationEffect effect = VibrationEffect.startComposition()
|
||||
.addOffDuration(Duration.ofMillis(20))
|
||||
.addEffect(
|
||||
VibrationEffect.createWaveform(
|
||||
/* timings= */ new long[] {10, 20},
|
||||
/* amplitudes= */ new int[] {0, DEFAULT_AMPLITUDE},
|
||||
/* repeatIndex= */ -1))
|
||||
.addEffect(
|
||||
VibrationEffect.createWaveform(
|
||||
/* timings= */ new long[] {30, 40},
|
||||
/* amplitudes= */ new int[] {DEFAULT_AMPLITUDE, DEFAULT_AMPLITUDE},
|
||||
/* repeatIndex= */ -1))
|
||||
.addOffDuration(Duration.ofMillis(10))
|
||||
.addEffect(
|
||||
VibrationEffect.createWaveform(
|
||||
/* timings= */ new long[] {4, 5},
|
||||
/* repeatIndex= */ -1))
|
||||
.addOffDuration(Duration.ofMillis(5))
|
||||
.compose();
|
||||
long[] expectedPattern = new long[] {30, 90, 14, 5, 5};
|
||||
|
||||
assertArrayEq(expectedPattern, effect.computeCreateWaveformOffOnTimingsOrNull());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void computeLegacyPattern_composition_withPrimitives() {
|
||||
VibrationEffect effect = VibrationEffect.startComposition()
|
||||
.addPrimitive(VibrationEffect.Composition.PRIMITIVE_TICK)
|
||||
.addOffDuration(Duration.ofMillis(20))
|
||||
.addEffect(
|
||||
VibrationEffect.createWaveform(
|
||||
/* timings= */ new long[] {5},
|
||||
/* repeatIndex= */ -1))
|
||||
.compose();
|
||||
|
||||
assertNull(effect.computeCreateWaveformOffOnTimingsOrNull());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void computeLegacyPattern_composition_repeating() {
|
||||
VibrationEffect effect = VibrationEffect.startComposition()
|
||||
.addEffect(
|
||||
VibrationEffect.createWaveform(
|
||||
/* timings= */ new long[] {5},
|
||||
/* repeatIndex= */ -1))
|
||||
.repeatEffectIndefinitely(
|
||||
VibrationEffect.createWaveform(
|
||||
/* timings= */ new long[] {2, 3},
|
||||
/* repeatIndex= */ -1))
|
||||
.compose();
|
||||
|
||||
assertNull(effect.computeCreateWaveformOffOnTimingsOrNull());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void computeLegacyPattern_effectsViaStartWaveform() {
|
||||
// Effects created via startWaveform are not expected to be converted to long[] patterns, as
|
||||
// they are not configured to always play with the default amplitude.
|
||||
VibrationEffect effect = VibrationEffect.startWaveform(targetFrequency(60))
|
||||
.addTransition(Duration.ofMillis(100), targetAmplitude(1), targetFrequency(120))
|
||||
.addSustain(Duration.ofMillis(200))
|
||||
.addTransition(Duration.ofMillis(100), targetAmplitude(0), targetFrequency(60))
|
||||
.build();
|
||||
|
||||
assertNull(effect.computeCreateWaveformOffOnTimingsOrNull());
|
||||
|
||||
effect = VibrationEffect.startWaveform(targetFrequency(60))
|
||||
.addTransition(Duration.ofMillis(80), targetAmplitude(1))
|
||||
.addSustain(Duration.ofMillis(200))
|
||||
.addTransition(Duration.ofMillis(100), targetAmplitude(0))
|
||||
.build();
|
||||
|
||||
assertNull(effect.computeCreateWaveformOffOnTimingsOrNull());
|
||||
|
||||
effect = VibrationEffect.startWaveform(targetFrequency(60))
|
||||
.addTransition(Duration.ofMillis(100), targetFrequency(50))
|
||||
.addSustain(Duration.ofMillis(50))
|
||||
.addTransition(Duration.ofMillis(20), targetFrequency(75))
|
||||
.build();
|
||||
|
||||
assertNull(effect.computeCreateWaveformOffOnTimingsOrNull());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getRingtones_noPrebakedRingtones() {
|
||||
Resources r = mockRingtoneResources(new String[0]);
|
||||
@@ -100,7 +449,7 @@ public class VibrationEffectTest {
|
||||
@Test
|
||||
public void testValidateOneShot() {
|
||||
VibrationEffect.createOneShot(1, 255).validate();
|
||||
VibrationEffect.createOneShot(1, VibrationEffect.DEFAULT_AMPLITUDE).validate();
|
||||
VibrationEffect.createOneShot(1, DEFAULT_AMPLITUDE).validate();
|
||||
|
||||
assertThrows(IllegalArgumentException.class,
|
||||
() -> VibrationEffect.createOneShot(-1, 255).validate());
|
||||
@@ -501,6 +850,13 @@ public class VibrationEffectTest {
|
||||
assertTrue(VibrationEffect.get(VibrationEffect.EFFECT_TICK).isHapticFeedbackCandidate());
|
||||
}
|
||||
|
||||
private void assertArrayEq(long[] expected, long[] actual) {
|
||||
assertTrue(
|
||||
String.format("Expected pattern %s, but was %s",
|
||||
Arrays.toString(expected), Arrays.toString(actual)),
|
||||
Arrays.equals(expected, actual));
|
||||
}
|
||||
|
||||
private Resources mockRingtoneResources() {
|
||||
return mockRingtoneResources(new String[]{
|
||||
RINGTONE_URI_1,
|
||||
|
||||
Reference in New Issue
Block a user