From d8dc940fc013756cc46bdde7cb1537025dcdaaae Mon Sep 17 00:00:00 2001 From: Lais Andrade Date: Tue, 6 Apr 2021 14:20:23 +0000 Subject: Rename CombinedVibrationEffect to CombinedVibration The change makes the distinction between VibrationEffect and CombinedVibratio clearer. The later is a combination of the former with the extra information about the vibrator ids, allowing effects to be played in one or more vibrators in parallel or in sequence. The methods create/start synced where also renamed to parallel (together with respective builder classes), to indicate they perform one or more effects in parallel on multiple vibrators. This is also a better match to the sequential combinations. This change also deprecates the Context.VIBRATOR_SERVICE in favour of the new VIBRATOR_MANAGER_SERVICE. The default vibrator can be retrieved from the manager system service. Same deprecation applied to InputDevice.getVibrator method. Fix: 184123900 Test: CombinedVibrationTest Change-Id: I44d8b225098d35fbf7783254acaf6a78f9fb4505 --- core/java/android/content/Context.java | 2 + .../java/android/hardware/input/IInputManager.aidl | 4 +- .../hardware/input/InputDeviceVibratorManager.java | 4 +- core/java/android/hardware/input/InputManager.java | 4 +- core/java/android/os/CombinedVibration.aidl | 19 + core/java/android/os/CombinedVibration.java | 687 +++++++++++++++++++++ core/java/android/os/CombinedVibrationEffect.aidl | 19 - core/java/android/os/CombinedVibrationEffect.java | 669 -------------------- core/java/android/os/IVibratorManagerService.aidl | 6 +- core/java/android/os/SystemVibrator.java | 4 +- core/java/android/os/SystemVibratorManager.java | 8 +- core/java/android/os/VibratorManager.java | 16 +- core/java/android/view/InputDevice.java | 2 + 13 files changed, 733 insertions(+), 711 deletions(-) create mode 100644 core/java/android/os/CombinedVibration.aidl create mode 100644 core/java/android/os/CombinedVibration.java delete mode 100644 core/java/android/os/CombinedVibrationEffect.aidl delete mode 100644 core/java/android/os/CombinedVibrationEffect.java (limited to 'core/java') diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java index 5d66cdf880b8..09ac8103c526 100644 --- a/core/java/android/content/Context.java +++ b/core/java/android/content/Context.java @@ -4128,9 +4128,11 @@ public abstract class Context { * Use with {@link #getSystemService(String)} to retrieve a {@link android.os.Vibrator} for * interacting with the vibration hardware. * + * @deprecated Use {@link android.os.VibratorManager} to retrieve the default system vibrator. * @see #getSystemService(String) * @see android.os.Vibrator */ + @Deprecated public static final String VIBRATOR_SERVICE = "vibrator"; /** diff --git a/core/java/android/hardware/input/IInputManager.aidl b/core/java/android/hardware/input/IInputManager.aidl index 4743fee3257b..336fbf2954a3 100644 --- a/core/java/android/hardware/input/IInputManager.aidl +++ b/core/java/android/hardware/input/IInputManager.aidl @@ -22,7 +22,7 @@ import android.hardware.input.KeyboardLayout; import android.hardware.input.IInputDevicesChangedListener; import android.hardware.input.ITabletModeChangedListener; import android.hardware.input.TouchCalibration; -import android.os.CombinedVibrationEffect; +import android.os.CombinedVibration; import android.hardware.input.IInputSensorEventListener; import android.hardware.input.InputSensorInfo; import android.hardware.lights.Light; @@ -91,7 +91,7 @@ interface IInputManager { // Input device vibrator control. void vibrate(int deviceId, in VibrationEffect effect, IBinder token); - void vibrateCombined(int deviceId, in CombinedVibrationEffect effect, IBinder token); + void vibrateCombined(int deviceId, in CombinedVibration vibration, IBinder token); void cancelVibrate(int deviceId, IBinder token); int[] getVibratorIds(int deviceId); boolean isVibrating(int deviceId); diff --git a/core/java/android/hardware/input/InputDeviceVibratorManager.java b/core/java/android/hardware/input/InputDeviceVibratorManager.java index d843407c289d..ed0efffbb346 100644 --- a/core/java/android/hardware/input/InputDeviceVibratorManager.java +++ b/core/java/android/hardware/input/InputDeviceVibratorManager.java @@ -19,7 +19,7 @@ package android.hardware.input; import android.annotation.NonNull; import android.annotation.Nullable; import android.os.Binder; -import android.os.CombinedVibrationEffect; +import android.os.CombinedVibration; import android.os.NullVibrator; import android.os.VibrationAttributes; import android.os.Vibrator; @@ -125,7 +125,7 @@ public class InputDeviceVibratorManager extends VibratorManager } @Override - public void vibrate(int uid, String opPkg, @NonNull CombinedVibrationEffect effect, + public void vibrate(int uid, String opPkg, @NonNull CombinedVibration effect, String reason, @Nullable VibrationAttributes attributes) { mInputManager.vibrate(mDeviceId, effect, mToken); } diff --git a/core/java/android/hardware/input/InputManager.java b/core/java/android/hardware/input/InputManager.java index c83ccfa81f95..b6d2eaf11be6 100644 --- a/core/java/android/hardware/input/InputManager.java +++ b/core/java/android/hardware/input/InputManager.java @@ -37,7 +37,7 @@ import android.hardware.lights.LightsManager; import android.hardware.lights.LightsRequest; import android.os.BlockUntrustedTouchesMode; import android.os.Build; -import android.os.CombinedVibrationEffect; +import android.os.CombinedVibration; import android.os.Handler; import android.os.IBinder; import android.os.IVibratorStateListener; @@ -1470,7 +1470,7 @@ public final class InputManager { /* * Perform combined vibration effect */ - void vibrate(int deviceId, CombinedVibrationEffect effect, IBinder token) { + void vibrate(int deviceId, CombinedVibration effect, IBinder token) { try { mIm.vibrateCombined(deviceId, effect, token); } catch (RemoteException ex) { diff --git a/core/java/android/os/CombinedVibration.aidl b/core/java/android/os/CombinedVibration.aidl new file mode 100644 index 000000000000..91317bde64a3 --- /dev/null +++ b/core/java/android/os/CombinedVibration.aidl @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.os; + +parcelable CombinedVibration; diff --git a/core/java/android/os/CombinedVibration.java b/core/java/android/os/CombinedVibration.java new file mode 100644 index 000000000000..aff55aff39f7 --- /dev/null +++ b/core/java/android/os/CombinedVibration.java @@ -0,0 +1,687 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.os; + +import android.annotation.NonNull; +import android.annotation.TestApi; +import android.util.SparseArray; + +import com.android.internal.util.Preconditions; + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +/** + * A CombinedVibration describes a combination of haptic effects to be performed by one or more + * {@link Vibrator Vibrators}. + * + * These effects may be any number of things, from single shot vibrations to complex waveforms. + * + * @see VibrationEffect + */ +@SuppressWarnings({"ParcelNotFinal", "ParcelCreator"}) // Parcel only extended here. +public abstract class CombinedVibration 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; + + /** Prevent subclassing from outside of the framework. */ + CombinedVibration() { + } + + /** + * Create a vibration that plays a single effect in parallel on all vibrators. + * + * A parallel vibration that takes a single {@link VibrationEffect} to be performed by multiple + * vibrators at the same time. + * + * @param effect The {@link VibrationEffect} to perform. + * @return The combined vibration representing the single effect to be played in all vibrators. + */ + @NonNull + public static CombinedVibration createParallel(@NonNull VibrationEffect effect) { + CombinedVibration combined = new Mono(effect); + combined.validate(); + return combined; + } + + /** + * Start creating a vibration that plays effects in parallel on one or more vibrators. + * + * A parallel vibration takes one or more {@link VibrationEffect VibrationEffects} associated to + * individual vibrators to be performed at the same time. + * + * @see CombinedVibration.ParallelCombination + */ + @NonNull + public static ParallelCombination startParallel() { + return new ParallelCombination(); + } + + /** + * Start creating a vibration that plays effects in sequence on one or more vibrators. + * + * A sequential vibration takes one or more {@link CombinedVibration CombinedVibrations} to be + * performed by one or more vibrators in order. Each {@link CombinedVibration} starts only after + * the previous one is finished. + * + * @hide + * @see CombinedVibration.SequentialCombination + */ + @TestApi + @NonNull + public static SequentialCombination startSequential() { + return new SequentialCombination(); + } + + @Override + public int describeContents() { + return 0; + } + + /** + * Gets the estimated duration of the combined vibration in milliseconds. + * + *

For parallel combinations this means the maximum duration of any individual {@link + * VibrationEffect}. For sequential combinations, this is a sum of each step and delays. + * + *

For combinations of effects without a defined end (e.g. a Waveform with a non-negative + * repeat index), this returns Long.MAX_VALUE. For effects with an unknown duration (e.g. + * Prebaked effects where the length is device and potentially run-time dependent), this returns + * -1. + * + * @hide + */ + @TestApi + public abstract long getDuration(); + + /** @hide */ + public abstract void validate(); + + /** @hide */ + public abstract boolean hasVibrator(int vibratorId); + + /** + * A combination of haptic effects that should be played in multiple vibrators in parallel. + * + * @see CombinedVibration#startParallel() + */ + public static final class ParallelCombination { + + private final SparseArray mEffects = new SparseArray<>(); + + ParallelCombination() { + } + + /** + * 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 ParallelCombination} object to enable adding + * multiple effects in one chain. + * @see VibrationEffect#createOneShot(long, int) + */ + @NonNull + public ParallelCombination addVibrator(int vibratorId, @NonNull VibrationEffect effect) { + mEffects.put(vibratorId, effect); + return this; + } + + /** + * Combine all of the added effects into a {@link CombinedVibration}. + * + * The {@link ParallelCombination} object is still valid after this + * call, so you can continue adding more effects to it and generating more + * {@link CombinedVibration}s by calling this method again. + * + * @return The {@link CombinedVibration} resulting from combining the added effects to + * be played in parallel. + */ + @NonNull + public CombinedVibration combine() { + if (mEffects.size() == 0) { + throw new IllegalStateException( + "Combination must have at least one element to combine."); + } + CombinedVibration combined = new Stereo(mEffects); + combined.validate(); + return combined; + } + } + + /** + * A combination of haptic effects that should be played in multiple vibrators in sequence. + * + * @hide + * @see CombinedVibration#startSequential() + */ + @TestApi + public static final class SequentialCombination { + + private final ArrayList mEffects = new ArrayList<>(); + private final ArrayList mDelays = new ArrayList<>(); + + SequentialCombination() { + } + + /** + * Add a single vibration effect to be performed next. + * + * Similar to {@link #addNext(int, VibrationEffect, int)}, but with no delay. The effect + * will start playing immediately after the previous vibration is finished. + * + * @param vibratorId The id of the vibrator that should perform this effect. + * @param effect The effect this vibrator should play. + * @return The {@link CombinedVibration.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. + * + * The delay is applied immediately after the previous vibration is finished. The effect + * will start playing after the delay. + * + * @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 + * vibration and this one, starting at the time the previous vibration in + * this sequence is finished. + * @return The {@link CombinedVibration.SequentialCombination} object to enable adding + * multiple effects in one chain. + */ + @NonNull + public SequentialCombination addNext(int vibratorId, @NonNull VibrationEffect effect, + int delay) { + return addNext( + CombinedVibration.startParallel().addVibrator(vibratorId, effect).combine(), + delay); + } + + /** + * Add a combined vibration effect to be performed next. + * + * Similar to {@link #addNext(CombinedVibration, int)}, but with no delay. The effect will + * start playing immediately after the previous vibration is finished. + * + * @param effect The combined effect to be performed next. + * @return The {@link CombinedVibration.SequentialCombination} object to enable adding + * multiple effects in one chain. + * @see VibrationEffect#createOneShot(long, int) + */ + @NonNull + public SequentialCombination addNext(@NonNull CombinedVibration effect) { + return addNext(effect, /* delay= */ 0); + } + + /** + * Add a combined vibration effect to be performed next. + * + * The delay is applied immediately after the previous vibration is finished. The vibration + * will start playing after the delay. + * + * @param effect The combined effect to be performed next. + * @param delay The amount of time, in milliseconds, to wait between playing the prior + * vibration and this one, starting at the time the previous vibration in this + * sequence is finished. + * @return The {@link CombinedVibration.SequentialCombination} object to enable adding + * multiple effects in one chain. + */ + @NonNull + public SequentialCombination addNext(@NonNull CombinedVibration 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 CombinedVibration.SequentialCombination} object is still valid after + * this call, so you can continue adding more effects to it and generating more {@link + * CombinedVibration}s by calling this method again. + * + * @return The {@link CombinedVibration} resulting from combining the added effects to + * be played in sequence. + */ + @NonNull + public CombinedVibration combine() { + if (mEffects.size() == 0) { + throw new IllegalStateException( + "Combination must have at least one element to combine."); + } + CombinedVibration combined = new Sequential(mEffects, mDelays); + combined.validate(); + return combined; + } + } + + /** + * Represents a single {@link VibrationEffect} that should be played in all vibrators at the + * same time. + * + * @hide + */ + @TestApi + public static final class Mono extends CombinedVibration { + private final VibrationEffect mEffect; + + Mono(Parcel in) { + mEffect = VibrationEffect.CREATOR.createFromParcel(in); + } + + Mono(@NonNull VibrationEffect effect) { + mEffect = effect; + } + + @NonNull + public VibrationEffect getEffect() { + return mEffect; + } + + @Override + public long getDuration() { + return mEffect.getDuration(); + } + + /** @hide */ + @Override + public void validate() { + mEffect.validate(); + } + + /** @hide */ + @Override + public boolean hasVibrator(int vibratorId) { + return true; + } + + @Override + public boolean equals(Object o) { + if (!(o instanceof Mono)) { + return false; + } + Mono other = (Mono) o; + return mEffect.equals(other.mEffect); + } + + @Override + public int hashCode() { + return Objects.hash(mEffect); + } + + @Override + public String toString() { + return "Mono{mEffect=" + mEffect + '}'; + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(@NonNull Parcel out, int flags) { + out.writeInt(PARCEL_TOKEN_MONO); + mEffect.writeToParcel(out, flags); + } + + @NonNull + public static final Parcelable.Creator CREATOR = + new Parcelable.Creator() { + @Override + public Mono createFromParcel(@NonNull Parcel in) { + // Skip the type token + in.readInt(); + return new Mono(in); + } + + @Override + @NonNull + public Mono[] newArray(int size) { + return new Mono[size]; + } + }; + } + + /** + * Represents a set of {@link VibrationEffect VibrationEffects} associated to individual + * vibrators that should be played at the same time. + * + * @hide + */ + @TestApi + public static final class Stereo extends CombinedVibration { + + /** Mapping vibrator ids to effects. */ + private final SparseArray mEffects; + + 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)); + } + } + + Stereo(@NonNull SparseArray 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 parallel, where each key represents the vibrator id. */ + @NonNull + public SparseArray getEffects() { + return mEffects; + } + + @Override + public long getDuration() { + long maxDuration = Long.MIN_VALUE; + boolean hasUnknownStep = false; + for (int i = 0; i < mEffects.size(); i++) { + long duration = mEffects.valueAt(i).getDuration(); + if (duration == Long.MAX_VALUE) { + // If any duration is repeating, this combination duration is also repeating. + return duration; + } + maxDuration = Math.max(maxDuration, duration); + // If any step is unknown, this combination duration will also be unknown, unless + // any step is repeating. Repeating vibrations take precedence over non-repeating + // ones in the service, so continue looping to check for repeating steps. + hasUnknownStep |= duration < 0; + } + if (hasUnknownStep) { + // If any step is unknown, this combination duration is also unknown. + return -1; + } + return maxDuration; + } + + /** @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(); + } + } + + /** @hide */ + @Override + public boolean hasVibrator(int vibratorId) { + return mEffects.indexOfKey(vibratorId) >= 0; + } + + @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 mEffects.contentHashCode(); + } + + @Override + public String toString() { + return "Stereo{mEffects=" + mEffects + '}'; + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(@NonNull 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 CREATOR = + new Parcelable.Creator() { + @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 CombinedVibration CombinedVibrations} that should be played in + * sequence. + * + * @hide + */ + @TestApi + public static final class Sequential extends CombinedVibration { + private final List mEffects; + private final List mDelays; + + 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(CombinedVibration.CREATOR.createFromParcel(in)); + } + } + + Sequential(@NonNull List effects, + @NonNull List delays) { + mEffects = new ArrayList<>(effects); + mDelays = new ArrayList<>(delays); + } + + /** Effects to be performed in sequence. */ + @NonNull + public List getEffects() { + return mEffects; + } + + /** Delay to be applied before each effect in {@link #getEffects()}. */ + @NonNull + public List getDelays() { + return mDelays; + } + + @Override + public long getDuration() { + boolean hasUnknownStep = false; + long durations = 0; + final int effectCount = mEffects.size(); + for (int i = 0; i < effectCount; i++) { + CombinedVibration effect = mEffects.get(i); + long duration = effect.getDuration(); + if (duration == Long.MAX_VALUE) { + // If any duration is repeating, this combination duration is also repeating. + return duration; + } + durations += duration; + // If any step is unknown, this combination duration will also be unknown, unless + // any step is repeating. Repeating vibrations take precedence over non-repeating + // ones in the service, so continue looping to check for repeating steps. + hasUnknownStep |= duration < 0; + } + if (hasUnknownStep) { + // If any step is unknown, this combination duration is also unknown. + return -1; + } + long delays = 0; + for (int i = 0; i < effectCount; i++) { + delays += mDelays.get(i); + } + return durations + delays; + } + + /** @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"); + final int effectCount = mEffects.size(); + for (int i = 0; i < effectCount; i++) { + if (mDelays.get(i) < 0) { + throw new IllegalArgumentException("Delays must all be >= 0" + + " (delays=" + mDelays + ")"); + } + } + for (int i = 0; i < effectCount; i++) { + CombinedVibration effect = mEffects.get(i); + if (effect instanceof Sequential) { + throw new IllegalArgumentException( + "There should be no nested sequential effects in a combined effect"); + } + effect.validate(); + } + } + + /** @hide */ + @Override + public boolean hasVibrator(int vibratorId) { + final int effectCount = mEffects.size(); + for (int i = 0; i < effectCount; i++) { + if (mEffects.get(i).hasVibrator(vibratorId)) { + return true; + } + } + return false; + } + + @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, mDelays); + } + + @Override + public String toString() { + return "Sequential{mEffects=" + mEffects + ", mDelays=" + mDelays + '}'; + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(@NonNull 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 CREATOR = + new Parcelable.Creator() { + @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 CREATOR = + new Parcelable.Creator() { + @Override + public CombinedVibration createFromParcel(Parcel in) { + int token = in.readInt(); + if (token == PARCEL_TOKEN_MONO) { + 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."); + } + } + + @Override + public CombinedVibration[] newArray(int size) { + return new CombinedVibration[size]; + } + }; +} diff --git a/core/java/android/os/CombinedVibrationEffect.aidl b/core/java/android/os/CombinedVibrationEffect.aidl deleted file mode 100644 index 330733c2643f..000000000000 --- a/core/java/android/os/CombinedVibrationEffect.aidl +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright (C) 2020 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.os; - -parcelable CombinedVibrationEffect; diff --git a/core/java/android/os/CombinedVibrationEffect.java b/core/java/android/os/CombinedVibrationEffect.java deleted file mode 100644 index e068772e954a..000000000000 --- a/core/java/android/os/CombinedVibrationEffect.java +++ /dev/null @@ -1,669 +0,0 @@ -/* - * Copyright (C) 2020 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.os; - -import android.annotation.NonNull; -import android.annotation.TestApi; -import android.util.SparseArray; - -import com.android.internal.util.Preconditions; - -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; - -/** - * A CombinedVibrationEffect describes a haptic effect to be performed by one or more {@link - * Vibrator Vibrators}. - * - * These effects may be any number of things, from single shot vibrations to complex waveforms. - * @see VibrationEffect - */ -@SuppressWarnings({"ParcelNotFinal", "ParcelCreator"}) // Parcel only extended here. -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; - - /** Prevent subclassing from outside of the framework. */ - CombinedVibrationEffect() { - } - - /** - * Create a synced vibration effect. - * - * A synced vibration effect should be performed by multiple vibrators at the same time. - * - * @param effect The {@link VibrationEffect} to perform. - * @return The synced effect. - */ - @NonNull - public static CombinedVibrationEffect createSynced(@NonNull VibrationEffect effect) { - CombinedVibrationEffect combined = new Mono(effect); - combined.validate(); - 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 - * @hide - */ - @TestApi - @NonNull - public static SequentialCombination startSequential() { - return new SequentialCombination(); - } - - @Override - public int describeContents() { - return 0; - } - - /** - * Gets the estimated duration of the combined vibration in milliseconds. - * - *

For synced combinations this means the maximum duration of any individual {@link - * VibrationEffect}. For sequential combinations, this is a sum of each step and delays. - * - *

For combinations of effects without a defined end (e.g. a Waveform with a non-negative - * repeat index), this returns Long.MAX_VALUE. For effects with an unknown duration (e.g. - * Prebaked effects where the length is device and potentially run-time dependent), this returns - * -1. - * - * @hide - */ - @TestApi - public abstract long getDuration(); - - /** @hide */ - public abstract void validate(); - - /** @hide */ - public abstract boolean hasVibrator(int vibratorId); - - /** - * A combination of haptic effects that should be played in multiple vibrators in sync. - * - * @see CombinedVibrationEffect#startSynced() - */ - public static final class SyncedCombination { - - private final SparseArray 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, @NonNull 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. - * - * @see CombinedVibrationEffect#startSequential() - * @hide - */ - @TestApi - public static final class SequentialCombination { - - private final ArrayList mEffects = new ArrayList<>(); - private final ArrayList 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. - * - * @hide - */ - @TestApi - public static final class Mono extends CombinedVibrationEffect { - private final VibrationEffect mEffect; - - Mono(Parcel in) { - mEffect = VibrationEffect.CREATOR.createFromParcel(in); - } - - Mono(@NonNull VibrationEffect effect) { - mEffect = effect; - } - - @NonNull - public VibrationEffect getEffect() { - return mEffect; - } - - @Override - public long getDuration() { - return mEffect.getDuration(); - } - - /** @hide */ - @Override - public void validate() { - mEffect.validate(); - } - - /** @hide */ - @Override - public boolean hasVibrator(int vibratorId) { - return true; - } - - @Override - public boolean equals(Object o) { - if (!(o instanceof Mono)) { - return false; - } - Mono other = (Mono) o; - return mEffect.equals(other.mEffect); - } - - @Override - public int hashCode() { - return Objects.hash(mEffect); - } - - @Override - public String toString() { - return "Mono{mEffect=" + mEffect + '}'; - } - - @Override - public int describeContents() { - return 0; - } - - @Override - public void writeToParcel(@NonNull Parcel out, int flags) { - out.writeInt(PARCEL_TOKEN_MONO); - mEffect.writeToParcel(out, flags); - } - - @NonNull - public static final Parcelable.Creator CREATOR = - new Parcelable.Creator() { - @Override - public Mono createFromParcel(@NonNull Parcel in) { - // Skip the type token - in.readInt(); - return new Mono(in); - } - - @Override - @NonNull - public Mono[] newArray(int size) { - return new Mono[size]; - } - }; - } - - /** - * Represents a list of {@link VibrationEffect}s that should be executed in sync. - * - * @hide - */ - @TestApi - public static final class Stereo extends CombinedVibrationEffect { - - /** Mapping vibrator ids to effects. */ - private final SparseArray mEffects; - - 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)); - } - } - - Stereo(@NonNull SparseArray 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. */ - @NonNull - public SparseArray getEffects() { - return mEffects; - } - - @Override - public long getDuration() { - long maxDuration = Long.MIN_VALUE; - boolean hasUnknownStep = false; - for (int i = 0; i < mEffects.size(); i++) { - long duration = mEffects.valueAt(i).getDuration(); - if (duration == Long.MAX_VALUE) { - // If any duration is repeating, this combination duration is also repeating. - return duration; - } - maxDuration = Math.max(maxDuration, duration); - // If any step is unknown, this combination duration will also be unknown, unless - // any step is repeating. Repeating vibrations take precedence over non-repeating - // ones in the service, so continue looping to check for repeating steps. - hasUnknownStep |= duration < 0; - } - if (hasUnknownStep) { - // If any step is unknown, this combination duration is also unknown. - return -1; - } - return maxDuration; - } - - /** @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(); - } - } - - /** @hide */ - @Override - public boolean hasVibrator(int vibratorId) { - return mEffects.indexOfKey(vibratorId) >= 0; - } - - @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 mEffects.contentHashCode(); - } - - @Override - public String toString() { - return "Stereo{mEffects=" + mEffects + '}'; - } - - @Override - public int describeContents() { - return 0; - } - - @Override - public void writeToParcel(@NonNull 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 CREATOR = - new Parcelable.Creator() { - @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 - */ - @TestApi - public static final class Sequential extends CombinedVibrationEffect { - private final List mEffects; - private final List mDelays; - - 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)); - } - } - - Sequential(@NonNull List effects, - @NonNull List delays) { - mEffects = new ArrayList<>(effects); - mDelays = new ArrayList<>(delays); - } - - /** Effects to be performed in sequence. */ - @NonNull - public List getEffects() { - return mEffects; - } - - /** Delay to be applied before each effect in {@link #getEffects()}. */ - @NonNull - public List getDelays() { - return mDelays; - } - - @Override - public long getDuration() { - boolean hasUnknownStep = false; - long durations = 0; - final int effectCount = mEffects.size(); - for (int i = 0; i < effectCount; i++) { - CombinedVibrationEffect effect = mEffects.get(i); - long duration = effect.getDuration(); - if (duration == Long.MAX_VALUE) { - // If any duration is repeating, this combination duration is also repeating. - return duration; - } - durations += duration; - // If any step is unknown, this combination duration will also be unknown, unless - // any step is repeating. Repeating vibrations take precedence over non-repeating - // ones in the service, so continue looping to check for repeating steps. - hasUnknownStep |= duration < 0; - } - if (hasUnknownStep) { - // If any step is unknown, this combination duration is also unknown. - return -1; - } - long delays = 0; - for (int i = 0; i < effectCount; i++) { - delays += mDelays.get(i); - } - return durations + delays; - } - - /** @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"); - final int effectCount = mEffects.size(); - for (int i = 0; i < effectCount; i++) { - if (mDelays.get(i) < 0) { - throw new IllegalArgumentException("Delays must all be >= 0" - + " (delays=" + mDelays + ")"); - } - } - for (int i = 0; i < effectCount; i++) { - CombinedVibrationEffect effect = mEffects.get(i); - if (effect instanceof Sequential) { - throw new IllegalArgumentException( - "There should be no nested sequential effects in a combined effect"); - } - effect.validate(); - } - } - - /** @hide */ - @Override - public boolean hasVibrator(int vibratorId) { - final int effectCount = mEffects.size(); - for (int i = 0; i < effectCount; i++) { - if (mEffects.get(i).hasVibrator(vibratorId)) { - return true; - } - } - return false; - } - - @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, mDelays); - } - - @Override - public String toString() { - return "Sequential{mEffects=" + mEffects + ", mDelays=" + mDelays + '}'; - } - - @Override - public int describeContents() { - return 0; - } - - @Override - public void writeToParcel(@NonNull 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 CREATOR = - new Parcelable.Creator() { - @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 CREATOR = - new Parcelable.Creator() { - @Override - public CombinedVibrationEffect createFromParcel(Parcel in) { - int token = in.readInt(); - if (token == PARCEL_TOKEN_MONO) { - 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."); - } - } - - @Override - public CombinedVibrationEffect[] newArray(int size) { - return new CombinedVibrationEffect[size]; - } - }; -} diff --git a/core/java/android/os/IVibratorManagerService.aidl b/core/java/android/os/IVibratorManagerService.aidl index f9e294791cca..c58cc4f9988f 100644 --- a/core/java/android/os/IVibratorManagerService.aidl +++ b/core/java/android/os/IVibratorManagerService.aidl @@ -16,7 +16,7 @@ package android.os; -import android.os.CombinedVibrationEffect; +import android.os.CombinedVibration; import android.os.IVibratorStateListener; import android.os.VibrationAttributes; import android.os.VibratorInfo; @@ -29,8 +29,8 @@ interface IVibratorManagerService { boolean registerVibratorStateListener(int vibratorId, in IVibratorStateListener listener); boolean unregisterVibratorStateListener(int vibratorId, in IVibratorStateListener listener); boolean setAlwaysOnEffect(int uid, String opPkg, int alwaysOnId, - in CombinedVibrationEffect effect, in VibrationAttributes attributes); - void vibrate(int uid, String opPkg, in CombinedVibrationEffect effect, + in CombinedVibration vibration, in VibrationAttributes attributes); + void vibrate(int uid, String opPkg, in CombinedVibration vibration, in VibrationAttributes attributes, String reason, IBinder token); void cancelVibrate(IBinder token); } diff --git a/core/java/android/os/SystemVibrator.java b/core/java/android/os/SystemVibrator.java index 219912c24e70..2e8ecb59b0d3 100644 --- a/core/java/android/os/SystemVibrator.java +++ b/core/java/android/os/SystemVibrator.java @@ -168,7 +168,7 @@ public class SystemVibrator extends Vibrator { return false; } VibrationAttributes attr = new VibrationAttributes.Builder(attributes, effect).build(); - CombinedVibrationEffect combinedEffect = CombinedVibrationEffect.createSynced(effect); + CombinedVibration combinedEffect = CombinedVibration.createParallel(effect); return mVibratorManager.setAlwaysOnEffect(uid, opPkg, alwaysOnId, combinedEffect, attr); } @@ -179,7 +179,7 @@ public class SystemVibrator extends Vibrator { Log.w(TAG, "Failed to vibrate; no vibrator manager."); return; } - CombinedVibrationEffect combinedEffect = CombinedVibrationEffect.createSynced(effect); + CombinedVibration combinedEffect = CombinedVibration.createParallel(effect); mVibratorManager.vibrate(uid, opPkg, combinedEffect, reason, attributes); } diff --git a/core/java/android/os/SystemVibratorManager.java b/core/java/android/os/SystemVibratorManager.java index 5d8190213119..84a1016e3364 100644 --- a/core/java/android/os/SystemVibratorManager.java +++ b/core/java/android/os/SystemVibratorManager.java @@ -117,7 +117,7 @@ public class SystemVibratorManager extends VibratorManager { @Override public boolean setAlwaysOnEffect(int uid, String opPkg, int alwaysOnId, - @Nullable CombinedVibrationEffect effect, @Nullable VibrationAttributes attributes) { + @Nullable CombinedVibration effect, @Nullable VibrationAttributes attributes) { if (mService == null) { Log.w(TAG, "Failed to set always-on effect; no vibrator manager service."); return false; @@ -131,7 +131,7 @@ public class SystemVibratorManager extends VibratorManager { } @Override - public void vibrate(int uid, String opPkg, @NonNull CombinedVibrationEffect effect, + public void vibrate(int uid, String opPkg, @NonNull CombinedVibration effect, String reason, @Nullable VibrationAttributes attributes) { if (mService == null) { Log.w(TAG, "Failed to vibrate; no vibrator manager service."); @@ -240,7 +240,7 @@ public class SystemVibratorManager extends VibratorManager { try { VibrationAttributes attr = new VibrationAttributes.Builder( attributes, effect).build(); - CombinedVibrationEffect combined = CombinedVibrationEffect.startSynced() + CombinedVibration combined = CombinedVibration.startParallel() .addVibrator(mVibratorInfo.getId(), effect) .combine(); return mService.setAlwaysOnEffect(uid, opPkg, alwaysOnId, combined, attr); @@ -259,7 +259,7 @@ public class SystemVibratorManager extends VibratorManager { return; } try { - CombinedVibrationEffect combined = CombinedVibrationEffect.startSynced() + CombinedVibration combined = CombinedVibration.startParallel() .addVibrator(mVibratorInfo.getId(), vibe) .combine(); mService.vibrate(uid, opPkg, combined, attributes, reason, mToken); diff --git a/core/java/android/os/VibratorManager.java b/core/java/android/os/VibratorManager.java index 5a01814508e1..7c911160dfa6 100644 --- a/core/java/android/os/VibratorManager.java +++ b/core/java/android/os/VibratorManager.java @@ -69,7 +69,7 @@ public abstract class VibratorManager { public abstract Vibrator getVibrator(int vibratorId); /** - * Returns the system default Vibrator service. + * Returns the default Vibrator for the device. */ @NonNull public abstract Vibrator getDefaultVibrator(); @@ -81,7 +81,7 @@ public abstract class VibratorManager { */ @RequiresPermission(android.Manifest.permission.VIBRATE_ALWAYS_ON) public boolean setAlwaysOnEffect(int uid, String opPkg, int alwaysOnId, - @Nullable CombinedVibrationEffect effect, @Nullable VibrationAttributes attributes) { + @Nullable CombinedVibration effect, @Nullable VibrationAttributes attributes) { Log.w(TAG, "Always-on effects aren't supported"); return false; } @@ -90,14 +90,14 @@ public abstract class VibratorManager { * Vibrate with a given combination of effects. * *

- * Pass in a {@link CombinedVibrationEffect} representing a combination of {@link + * Pass in a {@link CombinedVibration} representing a combination of {@link * VibrationEffect VibrationEffects} to be played on one or more vibrators. *

* * @param effect a combination of effects to be performed by one or more vibrators. */ @RequiresPermission(android.Manifest.permission.VIBRATE) - public final void vibrate(@NonNull CombinedVibrationEffect effect) { + public final void vibrate(@NonNull CombinedVibration effect) { vibrate(effect, null); } @@ -105,7 +105,7 @@ public abstract class VibratorManager { * Vibrate with a given combination of effects. * *

- * Pass in a {@link CombinedVibrationEffect} representing a combination of {@link + * Pass in a {@link CombinedVibration} representing a combination of {@link * VibrationEffect} to be played on one or more vibrators. *

* @@ -116,19 +116,19 @@ public abstract class VibratorManager { * incoming calls. */ @RequiresPermission(android.Manifest.permission.VIBRATE) - public final void vibrate(@NonNull CombinedVibrationEffect effect, + public final void vibrate(@NonNull CombinedVibration effect, @Nullable VibrationAttributes attributes) { vibrate(Process.myUid(), mPackageName, effect, null, attributes); } /** - * Like {@link #vibrate(CombinedVibrationEffect, VibrationAttributes)}, but allows the + * Like {@link #vibrate(CombinedVibration, VibrationAttributes)}, but allows the * caller to specify the vibration is owned by someone else and set reason for vibration. * * @hide */ @RequiresPermission(android.Manifest.permission.VIBRATE) - public abstract void vibrate(int uid, String opPkg, @NonNull CombinedVibrationEffect effect, + public abstract void vibrate(int uid, String opPkg, @NonNull CombinedVibration effect, String reason, @Nullable VibrationAttributes attributes); /** diff --git a/core/java/android/view/InputDevice.java b/core/java/android/view/InputDevice.java index d1f8ee9b0cc7..3b1c8ec23016 100644 --- a/core/java/android/view/InputDevice.java +++ b/core/java/android/view/InputDevice.java @@ -812,7 +812,9 @@ public final class InputDevice implements Parcelable { * {@link Context#getSystemService} with {@link Context#VIBRATOR_SERVICE} as argument. * * @return The vibrator service associated with the device, never null. + * @deprecated Use {@link #getVibratorManager()} to retrieve the default device vibrator. */ + @Deprecated public Vibrator getVibrator() { synchronized (mMotionRanges) { if (mVibrator == null) { -- cgit v1.2.3