Introduce public api for CombinedVibrationEffect
Introducing stereo effects and synced waveform effects. More at go/android-s-vibratormanager Fix: 166586119 Test: atest FrameworksCoreTest:CombinedVibrationEffectTest Change-Id: Ic567b6470b967474066e6d087c619148af9cc72d
This commit is contained in:
@@ -17,7 +17,12 @@
|
||||
package android.os;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.util.SparseArray;
|
||||
|
||||
import com.android.internal.util.Preconditions;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
@@ -31,6 +36,8 @@ import java.util.Objects;
|
||||
*/
|
||||
public abstract class CombinedVibrationEffect implements Parcelable {
|
||||
private static final int PARCEL_TOKEN_MONO = 1;
|
||||
private static final int PARCEL_TOKEN_STEREO = 2;
|
||||
private static final int PARCEL_TOKEN_SEQUENTIAL = 3;
|
||||
|
||||
/** @hide to prevent subclassing from outside of the framework */
|
||||
public CombinedVibrationEffect() {
|
||||
@@ -41,8 +48,8 @@ public abstract class CombinedVibrationEffect implements Parcelable {
|
||||
*
|
||||
* A synced vibration effect should be performed by multiple vibrators at the same time.
|
||||
*
|
||||
* @param effect The {@link VibrationEffect} to perform
|
||||
* @return The desired combined effect.
|
||||
* @param effect The {@link VibrationEffect} to perform.
|
||||
* @return The synced effect.
|
||||
*/
|
||||
@NonNull
|
||||
public static CombinedVibrationEffect createSynced(@NonNull VibrationEffect effect) {
|
||||
@@ -51,6 +58,30 @@ public abstract class CombinedVibrationEffect implements Parcelable {
|
||||
return combined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Start creating a synced vibration effect.
|
||||
*
|
||||
* A synced vibration effect should be performed by multiple vibrators at the same time.
|
||||
*
|
||||
* @see CombinedVibrationEffect.SyncedCombination
|
||||
*/
|
||||
@NonNull
|
||||
public static SyncedCombination startSynced() {
|
||||
return new SyncedCombination();
|
||||
}
|
||||
|
||||
/**
|
||||
* Start creating a sequential vibration effect.
|
||||
*
|
||||
* A sequential vibration effect should be performed by multiple vibrators in order.
|
||||
*
|
||||
* @see CombinedVibrationEffect.SequentialCombination
|
||||
*/
|
||||
@NonNull
|
||||
public static SequentialCombination startSequential() {
|
||||
return new SequentialCombination();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
@@ -59,6 +90,164 @@ public abstract class CombinedVibrationEffect implements Parcelable {
|
||||
/** @hide */
|
||||
public abstract void validate();
|
||||
|
||||
/**
|
||||
* A combination of haptic effects that should be played in multiple vibrators in sync.
|
||||
*
|
||||
* @hide
|
||||
* @see CombinedVibrationEffect#startSynced()
|
||||
*/
|
||||
public static final class SyncedCombination {
|
||||
|
||||
private final SparseArray<VibrationEffect> mEffects = new SparseArray<>();
|
||||
|
||||
SyncedCombination() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Add or replace a one shot vibration effect to be performed by the specified vibrator.
|
||||
*
|
||||
* @param vibratorId The id of the vibrator that should perform this effect.
|
||||
* @param effect The effect this vibrator should play.
|
||||
* @return The {@link CombinedVibrationEffect.SyncedCombination} object to enable adding
|
||||
* multiple effects in one chain.
|
||||
* @see VibrationEffect#createOneShot(long, int)
|
||||
*/
|
||||
@NonNull
|
||||
public SyncedCombination addVibrator(int vibratorId, VibrationEffect effect) {
|
||||
mEffects.put(vibratorId, effect);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Combine all of the added effects into a combined effect.
|
||||
*
|
||||
* The {@link CombinedVibrationEffect.SyncedCombination} object is still valid after this
|
||||
* call, so you can continue adding more effects to it and generating more
|
||||
* {@link CombinedVibrationEffect}s by calling this method again.
|
||||
*
|
||||
* @return The {@link CombinedVibrationEffect} resulting from combining the added effects to
|
||||
* be played in sync.
|
||||
*/
|
||||
@NonNull
|
||||
public CombinedVibrationEffect combine() {
|
||||
if (mEffects.size() == 0) {
|
||||
throw new IllegalStateException(
|
||||
"Combination must have at least one element to combine.");
|
||||
}
|
||||
CombinedVibrationEffect combined = new Stereo(mEffects);
|
||||
combined.validate();
|
||||
return combined;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A combination of haptic effects that should be played in multiple vibrators in sequence.
|
||||
*
|
||||
* @hide
|
||||
* @see CombinedVibrationEffect#startSequential()
|
||||
*/
|
||||
public static final class SequentialCombination {
|
||||
|
||||
private final ArrayList<CombinedVibrationEffect> mEffects = new ArrayList<>();
|
||||
private final ArrayList<Integer> mDelays = new ArrayList<>();
|
||||
|
||||
SequentialCombination() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a single vibration effect to be performed next.
|
||||
*
|
||||
* Similar to {@link #addNext(int, VibrationEffect, int)}, but with no delay.
|
||||
*
|
||||
* @param vibratorId The id of the vibrator that should perform this effect.
|
||||
* @param effect The effect this vibrator should play.
|
||||
* @return The {@link CombinedVibrationEffect.SequentialCombination} object to enable adding
|
||||
* multiple effects in one chain.
|
||||
*/
|
||||
@NonNull
|
||||
public SequentialCombination addNext(int vibratorId, @NonNull VibrationEffect effect) {
|
||||
return addNext(vibratorId, effect, /* delay= */ 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a single vibration effect to be performed next.
|
||||
*
|
||||
* @param vibratorId The id of the vibrator that should perform this effect.
|
||||
* @param effect The effect this vibrator should play.
|
||||
* @param delay The amount of time, in milliseconds, to wait between playing the prior
|
||||
* effect and this one.
|
||||
* @return The {@link CombinedVibrationEffect.SequentialCombination} object to enable adding
|
||||
* multiple effects in one chain.
|
||||
*/
|
||||
@NonNull
|
||||
public SequentialCombination addNext(int vibratorId, @NonNull VibrationEffect effect,
|
||||
int delay) {
|
||||
return addNext(
|
||||
CombinedVibrationEffect.startSynced().addVibrator(vibratorId, effect).combine(),
|
||||
delay);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a combined vibration effect to be performed next.
|
||||
*
|
||||
* Similar to {@link #addNext(CombinedVibrationEffect, int)}, but with no delay.
|
||||
*
|
||||
* @param effect The combined effect to be performed next.
|
||||
* @return The {@link CombinedVibrationEffect.SequentialCombination} object to enable adding
|
||||
* multiple effects in one chain.
|
||||
* @see VibrationEffect#createOneShot(long, int)
|
||||
*/
|
||||
@NonNull
|
||||
public SequentialCombination addNext(@NonNull CombinedVibrationEffect effect) {
|
||||
return addNext(effect, /* delay= */ 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a one shot vibration effect to be performed by the specified vibrator.
|
||||
*
|
||||
* @param effect The combined effect to be performed next.
|
||||
* @param delay The amount of time, in milliseconds, to wait between playing the prior
|
||||
* effect and this one.
|
||||
* @return The {@link CombinedVibrationEffect.SequentialCombination} object to enable adding
|
||||
* multiple effects in one chain.
|
||||
*/
|
||||
@NonNull
|
||||
public SequentialCombination addNext(@NonNull CombinedVibrationEffect effect, int delay) {
|
||||
if (effect instanceof Sequential) {
|
||||
Sequential sequentialEffect = (Sequential) effect;
|
||||
int firstEffectIndex = mDelays.size();
|
||||
mEffects.addAll(sequentialEffect.getEffects());
|
||||
mDelays.addAll(sequentialEffect.getDelays());
|
||||
mDelays.set(firstEffectIndex, delay + mDelays.get(firstEffectIndex));
|
||||
} else {
|
||||
mEffects.add(effect);
|
||||
mDelays.add(delay);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Combine all of the added effects in sequence.
|
||||
*
|
||||
* The {@link CombinedVibrationEffect.SequentialCombination} object is still valid after
|
||||
* this call, so you can continue adding more effects to it and generating more {@link
|
||||
* CombinedVibrationEffect}s by calling this method again.
|
||||
*
|
||||
* @return The {@link CombinedVibrationEffect} resulting from combining the added effects to
|
||||
* be played in sequence.
|
||||
*/
|
||||
@NonNull
|
||||
public CombinedVibrationEffect combine() {
|
||||
if (mEffects.size() == 0) {
|
||||
throw new IllegalStateException(
|
||||
"Combination must have at least one element to combine.");
|
||||
}
|
||||
CombinedVibrationEffect combined = new Sequential(mEffects, mDelays);
|
||||
combined.validate();
|
||||
return combined;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a single {@link VibrationEffect} that should be executed in all vibrators in sync.
|
||||
*
|
||||
@@ -87,10 +276,10 @@ public abstract class CombinedVibrationEffect implements Parcelable {
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (!(o instanceof CombinedVibrationEffect.Mono)) {
|
||||
if (!(o instanceof Mono)) {
|
||||
return false;
|
||||
}
|
||||
CombinedVibrationEffect.Mono other = (CombinedVibrationEffect.Mono) o;
|
||||
Mono other = (Mono) o;
|
||||
return other.mEffect.equals(other.mEffect);
|
||||
}
|
||||
|
||||
@@ -128,6 +317,206 @@ public abstract class CombinedVibrationEffect implements Parcelable {
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a list of {@link VibrationEffect}s that should be executed in sync.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public static final class Stereo extends CombinedVibrationEffect {
|
||||
|
||||
/** Mapping vibrator ids to effects. */
|
||||
private final SparseArray<VibrationEffect> mEffects;
|
||||
|
||||
public Stereo(Parcel in) {
|
||||
int size = in.readInt();
|
||||
mEffects = new SparseArray<>(size);
|
||||
for (int i = 0; i < size; i++) {
|
||||
int vibratorId = in.readInt();
|
||||
mEffects.put(vibratorId, VibrationEffect.CREATOR.createFromParcel(in));
|
||||
}
|
||||
}
|
||||
|
||||
public Stereo(@NonNull SparseArray<VibrationEffect> effects) {
|
||||
mEffects = new SparseArray<>(effects.size());
|
||||
for (int i = 0; i < effects.size(); i++) {
|
||||
mEffects.put(effects.keyAt(i), effects.valueAt(i));
|
||||
}
|
||||
}
|
||||
|
||||
/** Effects to be performed in sync, where each key represents the vibrator id. */
|
||||
public SparseArray<VibrationEffect> getEffects() {
|
||||
return mEffects;
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
@Override
|
||||
public void validate() {
|
||||
Preconditions.checkArgument(mEffects.size() > 0,
|
||||
"There should be at least one effect set for a combined effect");
|
||||
for (int i = 0; i < mEffects.size(); i++) {
|
||||
mEffects.valueAt(i).validate();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (!(o instanceof Stereo)) {
|
||||
return false;
|
||||
}
|
||||
Stereo other = (Stereo) o;
|
||||
if (mEffects.size() != other.mEffects.size()) {
|
||||
return false;
|
||||
}
|
||||
for (int i = 0; i < mEffects.size(); i++) {
|
||||
if (!mEffects.valueAt(i).equals(other.mEffects.get(mEffects.keyAt(i)))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(mEffects);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Stereo{mEffects=" + mEffects + '}';
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel out, int flags) {
|
||||
out.writeInt(PARCEL_TOKEN_STEREO);
|
||||
out.writeInt(mEffects.size());
|
||||
for (int i = 0; i < mEffects.size(); i++) {
|
||||
out.writeInt(mEffects.keyAt(i));
|
||||
mEffects.valueAt(i).writeToParcel(out, flags);
|
||||
}
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public static final Parcelable.Creator<Stereo> CREATOR =
|
||||
new Parcelable.Creator<Stereo>() {
|
||||
@Override
|
||||
public Stereo createFromParcel(@NonNull Parcel in) {
|
||||
// Skip the type token
|
||||
in.readInt();
|
||||
return new Stereo(in);
|
||||
}
|
||||
|
||||
@Override
|
||||
@NonNull
|
||||
public Stereo[] newArray(int size) {
|
||||
return new Stereo[size];
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a list of {@link VibrationEffect}s that should be executed in sequence.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public static final class Sequential extends CombinedVibrationEffect {
|
||||
private final List<CombinedVibrationEffect> mEffects;
|
||||
private final List<Integer> mDelays;
|
||||
|
||||
public Sequential(Parcel in) {
|
||||
int size = in.readInt();
|
||||
mEffects = new ArrayList<>(size);
|
||||
mDelays = new ArrayList<>(size);
|
||||
for (int i = 0; i < size; i++) {
|
||||
mDelays.add(in.readInt());
|
||||
mEffects.add(CombinedVibrationEffect.CREATOR.createFromParcel(in));
|
||||
}
|
||||
}
|
||||
|
||||
public Sequential(@NonNull List<CombinedVibrationEffect> effects,
|
||||
@NonNull List<Integer> delays) {
|
||||
mEffects = new ArrayList<>(effects);
|
||||
mDelays = new ArrayList<>(delays);
|
||||
}
|
||||
|
||||
/** Effects to be performed in sequence. */
|
||||
public List<CombinedVibrationEffect> getEffects() {
|
||||
return mEffects;
|
||||
}
|
||||
|
||||
/** Delay to be applied before each effect in {@link #getEffects()}. */
|
||||
public List<Integer> getDelays() {
|
||||
return mDelays;
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
@Override
|
||||
public void validate() {
|
||||
Preconditions.checkArgument(mEffects.size() > 0,
|
||||
"There should be at least one effect set for a combined effect");
|
||||
Preconditions.checkArgument(mEffects.size() == mDelays.size(),
|
||||
"Effect and delays should have equal length");
|
||||
for (long delay : mDelays) {
|
||||
if (delay < 0) {
|
||||
throw new IllegalArgumentException("Delays must all be >= 0"
|
||||
+ " (delays=" + mDelays + ")");
|
||||
}
|
||||
}
|
||||
for (CombinedVibrationEffect effect : mEffects) {
|
||||
if (effect instanceof Sequential) {
|
||||
throw new IllegalArgumentException(
|
||||
"There should be no nested sequential effects in a combined effect");
|
||||
}
|
||||
effect.validate();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (!(o instanceof Sequential)) {
|
||||
return false;
|
||||
}
|
||||
Sequential other = (Sequential) o;
|
||||
return mDelays.equals(other.mDelays) && mEffects.equals(other.mEffects);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(mEffects);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Sequential{mEffects=" + mEffects + ", mDelays=" + mDelays + '}';
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel out, int flags) {
|
||||
out.writeInt(PARCEL_TOKEN_SEQUENTIAL);
|
||||
out.writeInt(mEffects.size());
|
||||
for (int i = 0; i < mEffects.size(); i++) {
|
||||
out.writeInt(mDelays.get(i));
|
||||
mEffects.get(i).writeToParcel(out, flags);
|
||||
}
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public static final Parcelable.Creator<Sequential> CREATOR =
|
||||
new Parcelable.Creator<Sequential>() {
|
||||
@Override
|
||||
public Sequential createFromParcel(@NonNull Parcel in) {
|
||||
// Skip the type token
|
||||
in.readInt();
|
||||
return new Sequential(in);
|
||||
}
|
||||
|
||||
@Override
|
||||
@NonNull
|
||||
public Sequential[] newArray(int size) {
|
||||
return new Sequential[size];
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public static final Parcelable.Creator<CombinedVibrationEffect> CREATOR =
|
||||
new Parcelable.Creator<CombinedVibrationEffect>() {
|
||||
@@ -135,7 +524,11 @@ public abstract class CombinedVibrationEffect implements Parcelable {
|
||||
public CombinedVibrationEffect createFromParcel(Parcel in) {
|
||||
int token = in.readInt();
|
||||
if (token == PARCEL_TOKEN_MONO) {
|
||||
return new CombinedVibrationEffect.Mono(in);
|
||||
return new Mono(in);
|
||||
} else if (token == PARCEL_TOKEN_STEREO) {
|
||||
return new Stereo(in);
|
||||
} else if (token == PARCEL_TOKEN_SEQUENTIAL) {
|
||||
return new Sequential(in);
|
||||
} else {
|
||||
throw new IllegalStateException(
|
||||
"Unexpected combined vibration event type token in parcel.");
|
||||
|
||||
@@ -26,22 +26,135 @@ import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.JUnit4;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
@Presubmit
|
||||
@RunWith(JUnit4.class)
|
||||
public class CombinedVibrationEffectTest {
|
||||
|
||||
private static final VibrationEffect VALID_EFFECT = VibrationEffect.createOneShot(10, 255);
|
||||
private static final VibrationEffect INVALID_EFFECT = new VibrationEffect.OneShot(-1, -1);
|
||||
|
||||
@Test
|
||||
public void testValidateMono() {
|
||||
CombinedVibrationEffect.createSynced(VibrationEffect.get(VibrationEffect.EFFECT_CLICK));
|
||||
CombinedVibrationEffect.createSynced(VALID_EFFECT);
|
||||
|
||||
assertThrows(IllegalArgumentException.class,
|
||||
() -> CombinedVibrationEffect.createSynced(new VibrationEffect.OneShot(-1, -1)));
|
||||
() -> CombinedVibrationEffect.createSynced(INVALID_EFFECT));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidateStereo() {
|
||||
CombinedVibrationEffect.startSynced()
|
||||
.addVibrator(0, VALID_EFFECT)
|
||||
.addVibrator(1, VibrationEffect.get(VibrationEffect.EFFECT_TICK))
|
||||
.combine();
|
||||
CombinedVibrationEffect.startSynced()
|
||||
.addVibrator(0, INVALID_EFFECT)
|
||||
.addVibrator(0, VALID_EFFECT)
|
||||
.combine();
|
||||
|
||||
assertThrows(IllegalArgumentException.class,
|
||||
() -> CombinedVibrationEffect.startSynced()
|
||||
.addVibrator(0, INVALID_EFFECT)
|
||||
.combine());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidateSequential() {
|
||||
CombinedVibrationEffect.startSequential()
|
||||
.addNext(0, VALID_EFFECT)
|
||||
.addNext(CombinedVibrationEffect.createSynced(VALID_EFFECT))
|
||||
.combine();
|
||||
CombinedVibrationEffect.startSequential()
|
||||
.addNext(0, VALID_EFFECT)
|
||||
.addNext(0, VALID_EFFECT, 100)
|
||||
.combine();
|
||||
CombinedVibrationEffect.startSequential()
|
||||
.addNext(CombinedVibrationEffect.startSequential()
|
||||
.addNext(0, VALID_EFFECT)
|
||||
.combine())
|
||||
.combine();
|
||||
|
||||
assertThrows(IllegalArgumentException.class,
|
||||
() -> CombinedVibrationEffect.startSequential()
|
||||
.addNext(0, VALID_EFFECT, -1)
|
||||
.combine());
|
||||
assertThrows(IllegalArgumentException.class,
|
||||
() -> CombinedVibrationEffect.startSequential()
|
||||
.addNext(0, INVALID_EFFECT)
|
||||
.combine());
|
||||
assertThrows(IllegalArgumentException.class,
|
||||
() -> new CombinedVibrationEffect.Sequential(
|
||||
Arrays.asList(CombinedVibrationEffect.startSequential()
|
||||
.addNext(CombinedVibrationEffect.createSynced(VALID_EFFECT))
|
||||
.combine()),
|
||||
Arrays.asList(0))
|
||||
.validate());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNestedSequentialAccumulatesDelays() {
|
||||
CombinedVibrationEffect.Sequential combined =
|
||||
(CombinedVibrationEffect.Sequential) CombinedVibrationEffect.startSequential()
|
||||
.addNext(CombinedVibrationEffect.startSequential()
|
||||
.addNext(0, VALID_EFFECT, /* delay= */ 100)
|
||||
.addNext(1, VALID_EFFECT, /* delay= */ 100)
|
||||
.combine(),
|
||||
/* delay= */ 10)
|
||||
.addNext(CombinedVibrationEffect.startSequential()
|
||||
.addNext(0, VALID_EFFECT, /* delay= */ 100)
|
||||
.combine())
|
||||
.addNext(CombinedVibrationEffect.startSequential()
|
||||
.addNext(0, VALID_EFFECT)
|
||||
.addNext(0, VALID_EFFECT, /* delay= */ 100)
|
||||
.combine(),
|
||||
/* delay= */ 10)
|
||||
.combine();
|
||||
|
||||
assertEquals(Arrays.asList(110, 100, 100, 10, 100), combined.getDelays());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCombineEmptyFails() {
|
||||
assertThrows(IllegalStateException.class,
|
||||
() -> CombinedVibrationEffect.startSynced().combine());
|
||||
assertThrows(IllegalStateException.class,
|
||||
() -> CombinedVibrationEffect.startSequential().combine());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSerializationMono() {
|
||||
CombinedVibrationEffect original = CombinedVibrationEffect.createSynced(
|
||||
VibrationEffect.get(VibrationEffect.EFFECT_CLICK));
|
||||
CombinedVibrationEffect original = CombinedVibrationEffect.createSynced(VALID_EFFECT);
|
||||
|
||||
Parcel parcel = Parcel.obtain();
|
||||
original.writeToParcel(parcel, 0);
|
||||
parcel.setDataPosition(0);
|
||||
CombinedVibrationEffect restored = CombinedVibrationEffect.CREATOR.createFromParcel(parcel);
|
||||
assertEquals(original, restored);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSerializationStereo() {
|
||||
CombinedVibrationEffect original = CombinedVibrationEffect.startSynced()
|
||||
.addVibrator(0, VibrationEffect.get(VibrationEffect.EFFECT_CLICK))
|
||||
.addVibrator(1, VibrationEffect.createOneShot(10, 255))
|
||||
.combine();
|
||||
|
||||
Parcel parcel = Parcel.obtain();
|
||||
original.writeToParcel(parcel, 0);
|
||||
parcel.setDataPosition(0);
|
||||
CombinedVibrationEffect restored = CombinedVibrationEffect.CREATOR.createFromParcel(parcel);
|
||||
assertEquals(original, restored);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSerializationSequential() {
|
||||
CombinedVibrationEffect original = CombinedVibrationEffect.startSequential()
|
||||
.addNext(0, VALID_EFFECT)
|
||||
.addNext(CombinedVibrationEffect.createSynced(VALID_EFFECT))
|
||||
.addNext(0, VibrationEffect.get(VibrationEffect.EFFECT_CLICK), 100)
|
||||
.combine();
|
||||
|
||||
Parcel parcel = Parcel.obtain();
|
||||
original.writeToParcel(parcel, 0);
|
||||
|
||||
Reference in New Issue
Block a user