blob: b6f16a7b9ff89873b582caf6d7814f9d61ec7ffd [file] [log] [blame]
Michael Wright71216972017-01-31 18:33:54 +00001/*
2 * Copyright (C) 2017 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.os;
18
Michael Wright35a0c672018-01-24 00:32:53 +000019import android.hardware.vibrator.V1_0.Constants.EffectStrength;
Michael Wright57d94d92017-05-31 14:44:45 +010020import android.hardware.vibrator.V1_1.Constants.Effect_1_1;
Michael Wright35a0c672018-01-24 00:32:53 +000021import android.util.MathUtils;
Michael Wright71216972017-01-31 18:33:54 +000022
23import java.util.Arrays;
24
25/**
26 * A VibrationEffect describes a haptic effect to be performed by a {@link Vibrator}.
27 *
28 * These effects may be any number of things, from single shot vibrations to complex waveforms.
29 */
30public abstract class VibrationEffect implements Parcelable {
31 private static final int PARCEL_TOKEN_ONE_SHOT = 1;
32 private static final int PARCEL_TOKEN_WAVEFORM = 2;
33 private static final int PARCEL_TOKEN_EFFECT = 3;
34
35 /**
36 * The default vibration strength of the device.
37 */
38 public static final int DEFAULT_AMPLITUDE = -1;
39
40 /**
Michael Wright35a0c672018-01-24 00:32:53 +000041 * The maximum amplitude value
42 * @hide
43 */
44 public static final int MAX_AMPLITUDE = 255;
45
46 /**
Michael Wright71216972017-01-31 18:33:54 +000047 * A click effect.
48 *
49 * @see #get(int)
50 * @hide
51 */
Michael Wright57d94d92017-05-31 14:44:45 +010052 public static final int EFFECT_CLICK = Effect_1_1.CLICK;
Michael Wright71216972017-01-31 18:33:54 +000053
54 /**
55 * A double click effect.
56 *
57 * @see #get(int)
58 * @hide
59 */
Michael Wright57d94d92017-05-31 14:44:45 +010060 public static final int EFFECT_DOUBLE_CLICK = Effect_1_1.DOUBLE_CLICK;
61
62 /**
63 * A tick effect.
64 * @see #get(int)
65 * @hide
66 */
67 public static final int EFFECT_TICK = Effect_1_1.TICK;
Michael Wright71216972017-01-31 18:33:54 +000068
69 /** @hide to prevent subclassing from outside of the framework */
70 public VibrationEffect() { }
71
72 /**
73 * Create a one shot vibration.
74 *
75 * One shot vibrations will vibrate constantly for the specified period of time at the
76 * specified amplitude, and then stop.
77 *
78 * @param milliseconds The number of milliseconds to vibrate. This must be a positive number.
79 * @param amplitude The strength of the vibration. This must be a value between 1 and 255, or
80 * {@link #DEFAULT_AMPLITUDE}.
81 *
82 * @return The desired effect.
83 */
84 public static VibrationEffect createOneShot(long milliseconds, int amplitude) {
85 VibrationEffect effect = new OneShot(milliseconds, amplitude);
86 effect.validate();
87 return effect;
88 }
89
90 /**
91 * Create a waveform vibration.
92 *
93 * Waveform vibrations are a potentially repeating series of timing and amplitude pairs. For
94 * each pair, the value in the amplitude array determines the strength of the vibration and the
95 * value in the timing array determines how long it vibrates for. An amplitude of 0 implies no
96 * vibration (i.e. off), and any pairs with a timing value of 0 will be ignored.
97 * <p>
98 * The amplitude array of the generated waveform will be the same size as the given
99 * timing array with alternating values of 0 (i.e. off) and {@link #DEFAULT_AMPLITUDE},
100 * starting with 0. Therefore the first timing value will be the period to wait before turning
101 * the vibrator on, the second value will be how long to vibrate at {@link #DEFAULT_AMPLITUDE}
102 * strength, etc.
103 * </p><p>
104 * To cause the pattern to repeat, pass the index into the timings array at which to start the
105 * repetition, or -1 to disable repeating.
106 * </p>
107 *
108 * @param timings The pattern of alternating on-off timings, starting with off. Timing values
109 * of 0 will cause the timing / amplitude pair to be ignored.
110 * @param repeat The index into the timings array at which to repeat, or -1 if you you don't
111 * want to repeat.
112 *
113 * @return The desired effect.
114 */
115 public static VibrationEffect createWaveform(long[] timings, int repeat) {
116 int[] amplitudes = new int[timings.length];
117 for (int i = 0; i < (timings.length / 2); i++) {
118 amplitudes[i*2 + 1] = VibrationEffect.DEFAULT_AMPLITUDE;
119 }
120 return createWaveform(timings, amplitudes, repeat);
121 }
122
123 /**
124 * Create a waveform vibration.
125 *
126 * Waveform vibrations are a potentially repeating series of timing and amplitude pairs. For
127 * each pair, the value in the amplitude array determines the strength of the vibration and the
128 * value in the timing array determines how long it vibrates for. An amplitude of 0 implies no
129 * vibration (i.e. off), and any pairs with a timing value of 0 will be ignored.
130 * </p><p>
131 * To cause the pattern to repeat, pass the index into the timings array at which to start the
132 * repetition, or -1 to disable repeating.
133 * </p>
134 *
135 * @param timings The timing values of the timing / amplitude pairs. Timing values of 0
136 * will cause the pair to be ignored.
137 * @param amplitudes The amplitude values of the timing / amplitude pairs. Amplitude values
138 * must be between 0 and 255, or equal to {@link #DEFAULT_AMPLITUDE}. An
139 * amplitude value of 0 implies the motor is off.
140 * @param repeat The index into the timings array at which to repeat, or -1 if you you don't
141 * want to repeat.
142 *
143 * @return The desired effect.
144 */
145 public static VibrationEffect createWaveform(long[] timings, int[] amplitudes, int repeat) {
146 VibrationEffect effect = new Waveform(timings, amplitudes, repeat);
147 effect.validate();
148 return effect;
149 }
150
151 /**
152 * Get a predefined vibration effect.
153 *
154 * Predefined effects are a set of common vibration effects that should be identical, regardless
155 * of the app they come from, in order to provide a cohesive experience for users across
156 * the entire device. They also may be custom tailored to the device hardware in order to
157 * provide a better experience than you could otherwise build using the generic building
158 * blocks.
159 *
Michael Wrightdc2b3be2017-08-02 20:44:45 +0100160 * This will fallback to a generic pattern if one exists and there does not exist a
161 * hardware-specific implementation of the effect.
162 *
Michael Wright71216972017-01-31 18:33:54 +0000163 * @param effectId The ID of the effect to perform:
Michael Wrightdc2b3be2017-08-02 20:44:45 +0100164 * {@link #EFFECT_CLICK}, {@link #EFFECT_DOUBLE_CLICK}, {@link #EFFECT_TICK}
Michael Wright71216972017-01-31 18:33:54 +0000165 *
166 * @return The desired effect.
167 * @hide
168 */
169 public static VibrationEffect get(int effectId) {
Michael Wrightdc2b3be2017-08-02 20:44:45 +0100170 return get(effectId, true);
171 }
172
173 /**
174 * Get a predefined vibration effect.
175 *
176 * Predefined effects are a set of common vibration effects that should be identical, regardless
177 * of the app they come from, in order to provide a cohesive experience for users across
178 * the entire device. They also may be custom tailored to the device hardware in order to
179 * provide a better experience than you could otherwise build using the generic building
180 * blocks.
181 *
182 * Some effects you may only want to play if there's a hardware specific implementation because
183 * they may, for example, be too disruptive to the user without tuning. The {@code fallback}
184 * parameter allows you to decide whether you want to fallback to the generic implementation or
185 * only play if there's a tuned, hardware specific one available.
186 *
187 * @param effectId The ID of the effect to perform:
188 * {@link #EFFECT_CLICK}, {@link #EFFECT_DOUBLE_CLICK}, {@link #EFFECT_TICK}
189 * @param fallback Whether to fallback to a generic pattern if a hardware specific
190 * implementation doesn't exist.
191 *
192 * @return The desired effect.
193 * @hide
194 */
195 public static VibrationEffect get(int effectId, boolean fallback) {
196 VibrationEffect effect = new Prebaked(effectId, fallback);
Michael Wright71216972017-01-31 18:33:54 +0000197 effect.validate();
198 return effect;
199 }
200
201 @Override
202 public int describeContents() {
203 return 0;
204 }
205
206 /** @hide */
207 public abstract void validate();
208
Michael Wright35a0c672018-01-24 00:32:53 +0000209 /**
210 * Gets the estimated duration of the vibration in milliseconds.
211 *
212 * For effects without a defined end (e.g. a Waveform with a non-negative repeat index), this
213 * returns Long.MAX_VALUE. For effects with an unknown duration (e.g. Prebaked effects where
214 * the length is device and potentially run-time dependent), this returns -1.
215 *
216 * @hide
217 */
218 public abstract long getDuration();
219
220 /**
221 * Scale the amplitude with the given constraints.
222 *
223 * This assumes that the previous value was in the range [0, MAX_AMPLITUDE]
224 * @hide
225 */
226 protected static int scale(int amplitude, float gamma, int maxAmplitude) {
227 float val = MathUtils.pow(amplitude / (float) MAX_AMPLITUDE, gamma);
228 return (int) (val * maxAmplitude);
229 }
230
Michael Wright71216972017-01-31 18:33:54 +0000231 /** @hide */
232 public static class OneShot extends VibrationEffect implements Parcelable {
Michael Wright35a0c672018-01-24 00:32:53 +0000233 private final long mDuration;
234 private final int mAmplitude;
Michael Wright71216972017-01-31 18:33:54 +0000235
236 public OneShot(Parcel in) {
Michael Wright35a0c672018-01-24 00:32:53 +0000237 mDuration = in.readLong();
238 mAmplitude = in.readInt();
Michael Wright71216972017-01-31 18:33:54 +0000239 }
240
241 public OneShot(long milliseconds, int amplitude) {
Michael Wright35a0c672018-01-24 00:32:53 +0000242 mDuration = milliseconds;
Michael Wright71216972017-01-31 18:33:54 +0000243 mAmplitude = amplitude;
244 }
245
Michael Wright35a0c672018-01-24 00:32:53 +0000246 @Override
247 public long getDuration() {
248 return mDuration;
Michael Wright71216972017-01-31 18:33:54 +0000249 }
250
251 public int getAmplitude() {
252 return mAmplitude;
253 }
254
Michael Wright35a0c672018-01-24 00:32:53 +0000255 /**
256 * Scale the amplitude of this effect.
257 *
258 * @param gamma the gamma adjustment to apply
259 * @param maxAmplitude the new maximum amplitude of the effect
260 *
261 * @return A {@link OneShot} effect with the same timing but scaled amplitude.
262 */
263 public VibrationEffect scale(float gamma, int maxAmplitude) {
264 int newAmplitude = scale(mAmplitude, gamma, maxAmplitude);
265 return new OneShot(mDuration, newAmplitude);
266 }
267
Michael Wright71216972017-01-31 18:33:54 +0000268 @Override
269 public void validate() {
270 if (mAmplitude < -1 || mAmplitude == 0 || mAmplitude > 255) {
271 throw new IllegalArgumentException(
Michael Wright35a0c672018-01-24 00:32:53 +0000272 "amplitude must either be DEFAULT_AMPLITUDE, "
273 + "or between 1 and 255 inclusive (amplitude=" + mAmplitude + ")");
Michael Wright71216972017-01-31 18:33:54 +0000274 }
Michael Wright35a0c672018-01-24 00:32:53 +0000275 if (mDuration <= 0) {
Michael Wright0ef6edd2017-04-05 20:57:39 +0100276 throw new IllegalArgumentException(
Michael Wright35a0c672018-01-24 00:32:53 +0000277 "duration must be positive (duration=" + mDuration + ")");
Michael Wright71216972017-01-31 18:33:54 +0000278 }
279 }
280
281 @Override
282 public boolean equals(Object o) {
283 if (!(o instanceof VibrationEffect.OneShot)) {
284 return false;
285 }
286 VibrationEffect.OneShot other = (VibrationEffect.OneShot) o;
Michael Wright35a0c672018-01-24 00:32:53 +0000287 return other.mDuration == mDuration && other.mAmplitude == mAmplitude;
Michael Wright71216972017-01-31 18:33:54 +0000288 }
289
290 @Override
291 public int hashCode() {
292 int result = 17;
Michael Wright35a0c672018-01-24 00:32:53 +0000293 result += 37 * (int) mDuration;
294 result += 37 * mAmplitude;
Michael Wright71216972017-01-31 18:33:54 +0000295 return result;
296 }
297
298 @Override
299 public String toString() {
Michael Wright35a0c672018-01-24 00:32:53 +0000300 return "OneShot{mDuration=" + mDuration + ", mAmplitude=" + mAmplitude + "}";
Michael Wright71216972017-01-31 18:33:54 +0000301 }
302
303 @Override
304 public void writeToParcel(Parcel out, int flags) {
305 out.writeInt(PARCEL_TOKEN_ONE_SHOT);
Michael Wright35a0c672018-01-24 00:32:53 +0000306 out.writeLong(mDuration);
Michael Wright71216972017-01-31 18:33:54 +0000307 out.writeInt(mAmplitude);
308 }
309
310 public static final Parcelable.Creator<OneShot> CREATOR =
311 new Parcelable.Creator<OneShot>() {
312 @Override
313 public OneShot createFromParcel(Parcel in) {
314 // Skip the type token
315 in.readInt();
316 return new OneShot(in);
317 }
318 @Override
319 public OneShot[] newArray(int size) {
320 return new OneShot[size];
321 }
322 };
323 }
324
325 /** @hide */
326 public static class Waveform extends VibrationEffect implements Parcelable {
Michael Wright35a0c672018-01-24 00:32:53 +0000327 private final long[] mTimings;
328 private final int[] mAmplitudes;
329 private final int mRepeat;
Michael Wright71216972017-01-31 18:33:54 +0000330
331 public Waveform(Parcel in) {
332 this(in.createLongArray(), in.createIntArray(), in.readInt());
333 }
334
335 public Waveform(long[] timings, int[] amplitudes, int repeat) {
336 mTimings = new long[timings.length];
337 System.arraycopy(timings, 0, mTimings, 0, timings.length);
338 mAmplitudes = new int[amplitudes.length];
339 System.arraycopy(amplitudes, 0, mAmplitudes, 0, amplitudes.length);
340 mRepeat = repeat;
341 }
342
343 public long[] getTimings() {
344 return mTimings;
345 }
346
347 public int[] getAmplitudes() {
348 return mAmplitudes;
349 }
350
351 public int getRepeatIndex() {
352 return mRepeat;
353 }
354
355 @Override
Michael Wright35a0c672018-01-24 00:32:53 +0000356 public long getDuration() {
357 if (mRepeat >= 0) {
358 return Long.MAX_VALUE;
359 }
360 long duration = 0;
361 for (long d : mTimings) {
362 duration += d;
363 }
364 return duration;
365 }
366
367 /**
368 * Scale the Waveform with the given gamma and new max amplitude.
369 *
370 * @param gamma the gamma adjustment to apply
371 * @param maxAmplitude the new maximum amplitude of the effect
372 *
373 * @return A {@link Waveform} effect with the same timings and repeat index
374 * but scaled amplitude.
375 */
376 public VibrationEffect scale(float gamma, int maxAmplitude) {
377 if (gamma == 1.0f && maxAmplitude == MAX_AMPLITUDE) {
378 // Just return a copy of the original if there's no scaling to be done.
379 return new Waveform(mTimings, mAmplitudes, mRepeat);
380 }
381
382 int[] scaledAmplitudes = Arrays.copyOf(mAmplitudes, mAmplitudes.length);
383 for (int i = 0; i < scaledAmplitudes.length; i++) {
384 scaledAmplitudes[i] = scale(scaledAmplitudes[i], gamma, maxAmplitude);
385 }
386 return new Waveform(mTimings, scaledAmplitudes, mRepeat);
387 }
388
389 @Override
Michael Wright71216972017-01-31 18:33:54 +0000390 public void validate() {
391 if (mTimings.length != mAmplitudes.length) {
392 throw new IllegalArgumentException(
Michael Wright35a0c672018-01-24 00:32:53 +0000393 "timing and amplitude arrays must be of equal length"
394 + " (timings.length=" + mTimings.length
395 + ", amplitudes.length=" + mAmplitudes.length + ")");
Michael Wright71216972017-01-31 18:33:54 +0000396 }
397 if (!hasNonZeroEntry(mTimings)) {
Michael Wright35a0c672018-01-24 00:32:53 +0000398 throw new IllegalArgumentException("at least one timing must be non-zero"
399 + " (timings=" + Arrays.toString(mTimings) + ")");
Michael Wright71216972017-01-31 18:33:54 +0000400 }
401 for (long timing : mTimings) {
402 if (timing < 0) {
Michael Wright35a0c672018-01-24 00:32:53 +0000403 throw new IllegalArgumentException("timings must all be >= 0"
404 + " (timings=" + Arrays.toString(mTimings) + ")");
Michael Wright71216972017-01-31 18:33:54 +0000405 }
406 }
407 for (int amplitude : mAmplitudes) {
408 if (amplitude < -1 || amplitude > 255) {
409 throw new IllegalArgumentException(
Michael Wright35a0c672018-01-24 00:32:53 +0000410 "amplitudes must all be DEFAULT_AMPLITUDE or between 0 and 255"
411 + " (amplitudes=" + Arrays.toString(mAmplitudes) + ")");
Michael Wright71216972017-01-31 18:33:54 +0000412 }
413 }
414 if (mRepeat < -1 || mRepeat >= mTimings.length) {
Michael Wright0ef6edd2017-04-05 20:57:39 +0100415 throw new IllegalArgumentException(
Michael Wright35a0c672018-01-24 00:32:53 +0000416 "repeat index must be within the bounds of the timings array"
417 + " (timings.length=" + mTimings.length + ", index=" + mRepeat + ")");
Michael Wright71216972017-01-31 18:33:54 +0000418 }
419 }
420
421 @Override
422 public boolean equals(Object o) {
423 if (!(o instanceof VibrationEffect.Waveform)) {
424 return false;
425 }
426 VibrationEffect.Waveform other = (VibrationEffect.Waveform) o;
Michael Wright35a0c672018-01-24 00:32:53 +0000427 return Arrays.equals(mTimings, other.mTimings)
428 && Arrays.equals(mAmplitudes, other.mAmplitudes)
429 && mRepeat == other.mRepeat;
Michael Wright71216972017-01-31 18:33:54 +0000430 }
431
432 @Override
433 public int hashCode() {
434 int result = 17;
Michael Wright35a0c672018-01-24 00:32:53 +0000435 result += 37 * Arrays.hashCode(mTimings);
436 result += 37 * Arrays.hashCode(mAmplitudes);
437 result += 37 * mRepeat;
Michael Wright71216972017-01-31 18:33:54 +0000438 return result;
439 }
440
441 @Override
442 public String toString() {
Michael Wright35a0c672018-01-24 00:32:53 +0000443 return "Waveform{mTimings=" + Arrays.toString(mTimings)
444 + ", mAmplitudes=" + Arrays.toString(mAmplitudes)
445 + ", mRepeat=" + mRepeat
446 + "}";
Michael Wright71216972017-01-31 18:33:54 +0000447 }
448
449 @Override
450 public void writeToParcel(Parcel out, int flags) {
451 out.writeInt(PARCEL_TOKEN_WAVEFORM);
452 out.writeLongArray(mTimings);
453 out.writeIntArray(mAmplitudes);
454 out.writeInt(mRepeat);
455 }
456
457 private static boolean hasNonZeroEntry(long[] vals) {
458 for (long val : vals) {
459 if (val != 0) {
460 return true;
461 }
462 }
463 return false;
464 }
465
466
467 public static final Parcelable.Creator<Waveform> CREATOR =
468 new Parcelable.Creator<Waveform>() {
469 @Override
470 public Waveform createFromParcel(Parcel in) {
471 // Skip the type token
472 in.readInt();
473 return new Waveform(in);
474 }
475 @Override
476 public Waveform[] newArray(int size) {
477 return new Waveform[size];
478 }
479 };
480 }
481
482 /** @hide */
483 public static class Prebaked extends VibrationEffect implements Parcelable {
Michael Wright35a0c672018-01-24 00:32:53 +0000484 private final int mEffectId;
485 private final boolean mFallback;
486
487 private int mEffectStrength;
Michael Wright71216972017-01-31 18:33:54 +0000488
489 public Prebaked(Parcel in) {
Michael Wrightdc2b3be2017-08-02 20:44:45 +0100490 this(in.readInt(), in.readByte() != 0);
Michael Wright35a0c672018-01-24 00:32:53 +0000491 mEffectStrength = in.readInt();
Michael Wright71216972017-01-31 18:33:54 +0000492 }
493
Michael Wrightdc2b3be2017-08-02 20:44:45 +0100494 public Prebaked(int effectId, boolean fallback) {
Michael Wright71216972017-01-31 18:33:54 +0000495 mEffectId = effectId;
Michael Wrightdc2b3be2017-08-02 20:44:45 +0100496 mFallback = fallback;
Michael Wright35a0c672018-01-24 00:32:53 +0000497 mEffectStrength = EffectStrength.MEDIUM;
Michael Wright71216972017-01-31 18:33:54 +0000498 }
499
500 public int getId() {
501 return mEffectId;
502 }
503
Michael Wrightdc2b3be2017-08-02 20:44:45 +0100504 /**
505 * Whether the effect should fall back to a generic pattern if there's no hardware specific
506 * implementation of it.
507 */
508 public boolean shouldFallback() {
509 return mFallback;
510 }
511
Michael Wright71216972017-01-31 18:33:54 +0000512 @Override
Michael Wright35a0c672018-01-24 00:32:53 +0000513 public long getDuration() {
514 return -1;
515 }
516
517 /**
518 * Set the effect strength of the prebaked effect.
519 */
520 public void setEffectStrength(int strength) {
521 if (!isValidEffectStrength(strength)) {
522 throw new IllegalArgumentException("Invalid effect strength: " + strength);
523 }
524 mEffectStrength = strength;
525 }
526
527 /**
528 * Set the effect strength.
529 */
530 public int getEffectStrength() {
531 return mEffectStrength;
532 }
533
534 private static boolean isValidEffectStrength(int strength) {
535 switch (strength) {
536 case EffectStrength.LIGHT:
537 case EffectStrength.MEDIUM:
538 case EffectStrength.STRONG:
539 return true;
540 default:
541 return false;
542 }
543 }
544
545 @Override
Michael Wright71216972017-01-31 18:33:54 +0000546 public void validate() {
Michael Wright57d94d92017-05-31 14:44:45 +0100547 switch (mEffectId) {
548 case EFFECT_CLICK:
549 case EFFECT_DOUBLE_CLICK:
550 case EFFECT_TICK:
551 break;
552 default:
553 throw new IllegalArgumentException(
554 "Unknown prebaked effect type (value=" + mEffectId + ")");
Michael Wright71216972017-01-31 18:33:54 +0000555 }
Michael Wright35a0c672018-01-24 00:32:53 +0000556 if (!isValidEffectStrength(mEffectStrength)) {
557 throw new IllegalArgumentException(
558 "Unknown prebaked effect strength (value=" + mEffectStrength + ")");
559 }
Michael Wright71216972017-01-31 18:33:54 +0000560 }
561
562 @Override
563 public boolean equals(Object o) {
564 if (!(o instanceof VibrationEffect.Prebaked)) {
565 return false;
566 }
567 VibrationEffect.Prebaked other = (VibrationEffect.Prebaked) o;
Michael Wright35a0c672018-01-24 00:32:53 +0000568 return mEffectId == other.mEffectId
569 && mFallback == other.mFallback
570 && mEffectStrength == other.mEffectStrength;
Michael Wright71216972017-01-31 18:33:54 +0000571 }
572
573 @Override
574 public int hashCode() {
Michael Wright35a0c672018-01-24 00:32:53 +0000575 int result = 17;
576 result += 37 * mEffectId;
577 result += 37 * mEffectStrength;
578 return result;
Michael Wright71216972017-01-31 18:33:54 +0000579 }
580
581 @Override
582 public String toString() {
Michael Wright35a0c672018-01-24 00:32:53 +0000583 return "Prebaked{mEffectId=" + mEffectId
584 + ", mEffectStrength=" + mEffectStrength
585 + ", mFallback=" + mFallback
586 + "}";
Michael Wright71216972017-01-31 18:33:54 +0000587 }
588
589
590 @Override
591 public void writeToParcel(Parcel out, int flags) {
592 out.writeInt(PARCEL_TOKEN_EFFECT);
593 out.writeInt(mEffectId);
Michael Wrightdc2b3be2017-08-02 20:44:45 +0100594 out.writeByte((byte) (mFallback ? 1 : 0));
Michael Wright35a0c672018-01-24 00:32:53 +0000595 out.writeInt(mEffectStrength);
Michael Wright71216972017-01-31 18:33:54 +0000596 }
597
598 public static final Parcelable.Creator<Prebaked> CREATOR =
599 new Parcelable.Creator<Prebaked>() {
600 @Override
601 public Prebaked createFromParcel(Parcel in) {
602 // Skip the type token
603 in.readInt();
604 return new Prebaked(in);
605 }
606 @Override
607 public Prebaked[] newArray(int size) {
608 return new Prebaked[size];
609 }
610 };
611 }
612
613 public static final Parcelable.Creator<VibrationEffect> CREATOR =
614 new Parcelable.Creator<VibrationEffect>() {
615 @Override
616 public VibrationEffect createFromParcel(Parcel in) {
617 int token = in.readInt();
618 if (token == PARCEL_TOKEN_ONE_SHOT) {
619 return new OneShot(in);
620 } else if (token == PARCEL_TOKEN_WAVEFORM) {
621 return new Waveform(in);
622 } else if (token == PARCEL_TOKEN_EFFECT) {
623 return new Prebaked(in);
624 } else {
625 throw new IllegalStateException(
626 "Unexpected vibration event type token in parcel.");
627 }
628 }
629 @Override
630 public VibrationEffect[] newArray(int size) {
631 return new VibrationEffect[size];
632 }
633 };
634}