Merge "Changes to VibrationThread in preparation for sessions" into main
diff --git a/services/core/java/com/android/server/vibrator/ExternalVibrationSession.java b/services/core/java/com/android/server/vibrator/ExternalVibrationSession.java
index b4d3862..b5a7fcb 100644
--- a/services/core/java/com/android/server/vibrator/ExternalVibrationSession.java
+++ b/services/core/java/com/android/server/vibrator/ExternalVibrationSession.java
@@ -16,6 +16,7 @@
package com.android.server.vibrator;
+import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.Context;
import android.os.ExternalVibration;
@@ -24,6 +25,7 @@
import android.os.VibrationAttributes;
import android.os.vibrator.Flags;
+import com.android.internal.annotations.GuardedBy;
import com.android.internal.util.FrameworkStatsLog;
/**
@@ -32,14 +34,16 @@
final class ExternalVibrationSession extends Vibration
implements VibrationSession, IBinder.DeathRecipient {
+ private final Object mLock = new Object();
private final ExternalVibration mExternalVibration;
private final ExternalVibrationScale mScale = new ExternalVibrationScale();
+ @GuardedBy("mLock")
@Nullable
private Runnable mBinderDeathCallback;
ExternalVibrationSession(ExternalVibration externalVibration) {
- super(externalVibration.getToken(), new CallerInfo(
+ super(new CallerInfo(
externalVibration.getVibrationAttributes(), externalVibration.getUid(),
// TODO(b/249785241): Find a way to link ExternalVibration to a VirtualDevice
// instead of using DEVICE_ID_INVALID here and relying on the UID checks.
@@ -82,24 +86,25 @@
}
@Override
- public void linkToDeath(Runnable callback) {
- synchronized (this) {
+ public boolean linkToDeath(Runnable callback) {
+ synchronized (mLock) {
mBinderDeathCallback = callback;
}
mExternalVibration.linkToDeath(this);
+ return true;
}
@Override
public void unlinkToDeath() {
mExternalVibration.unlinkToDeath(this);
- synchronized (this) {
+ synchronized (mLock) {
mBinderDeathCallback = null;
}
}
@Override
public void binderDied() {
- synchronized (this) {
+ synchronized (mLock) {
if (mBinderDeathCallback != null) {
mBinderDeathCallback.run();
}
@@ -119,9 +124,11 @@
}
@Override
- public void notifyEnded() {
+ public void requestEnd(@NonNull Status status, @Nullable CallerInfo endedBy,
+ boolean immediate) {
// Notify external client that this vibration should stop sending data to the vibrator.
mExternalVibration.mute();
+ end(new EndInfo(status, endedBy));
}
boolean isHoldingSameVibration(ExternalVibration vib) {
diff --git a/services/core/java/com/android/server/vibrator/HalVibration.java b/services/core/java/com/android/server/vibrator/HalVibration.java
index ea4bd01..ce9c47b 100644
--- a/services/core/java/com/android/server/vibrator/HalVibration.java
+++ b/services/core/java/com/android/server/vibrator/HalVibration.java
@@ -36,6 +36,7 @@
final class HalVibration extends Vibration {
public final SparseArray<VibrationEffect> mFallbacks = new SparseArray<>();
+ public final IBinder callerToken;
/** A {@link CountDownLatch} to enable waiting for completion. */
private final CountDownLatch mCompletionLatch = new CountDownLatch(1);
@@ -55,9 +56,10 @@
private int mScaleLevel;
private float mAdaptiveScale;
- HalVibration(@NonNull IBinder token, @NonNull CombinedVibration effect,
+ HalVibration(@NonNull IBinder callerToken, @NonNull CombinedVibration effect,
@NonNull VibrationSession.CallerInfo callerInfo) {
- super(token, callerInfo);
+ super(callerInfo);
+ this.callerToken = callerToken;
mOriginalEffect = effect;
mEffectToPlay = effect;
mScaleLevel = VibrationScaler.SCALE_NONE;
diff --git a/services/core/java/com/android/server/vibrator/Vibration.java b/services/core/java/com/android/server/vibrator/Vibration.java
index 9a04793..21fd4ce 100644
--- a/services/core/java/com/android/server/vibrator/Vibration.java
+++ b/services/core/java/com/android/server/vibrator/Vibration.java
@@ -53,16 +53,13 @@
public final long id;
public final VibrationSession.CallerInfo callerInfo;
public final VibrationStats stats = new VibrationStats();
- public final IBinder callerToken;
private VibrationSession.Status mStatus;
- Vibration(@NonNull IBinder token, @NonNull VibrationSession.CallerInfo callerInfo) {
- Objects.requireNonNull(token);
+ Vibration(@NonNull VibrationSession.CallerInfo callerInfo) {
Objects.requireNonNull(callerInfo);
mStatus = VibrationSession.Status.RUNNING;
this.id = sNextVibrationId.getAndIncrement();
- this.callerToken = token;
this.callerInfo = callerInfo;
}
diff --git a/services/core/java/com/android/server/vibrator/VibrationSession.java b/services/core/java/com/android/server/vibrator/VibrationSession.java
index 5640b49..70477a2 100644
--- a/services/core/java/com/android/server/vibrator/VibrationSession.java
+++ b/services/core/java/com/android/server/vibrator/VibrationSession.java
@@ -49,14 +49,26 @@
* Links this session to the app process death with given callback to handle it.
*
* <p>This can be used by the service to end the vibration session when the app process dies.
+ *
+ * @param callback The service callback to be triggered when the binder dies
+ * @return true if the link was successful, false otherwise
*/
- void linkToDeath(Runnable callback);
+ boolean linkToDeath(@Nullable Runnable callback);
/** Removes link to the app process death. */
void unlinkToDeath();
- /** Notify the session end was requested, which might be acted upon asynchronously. */
- void notifyEnded();
+ /**
+ * Notify the session end was requested, which might be acted upon asynchronously.
+ *
+ * <p>Only the first end signal will be used to end a session, but subsequent calls with
+ * {@code immediate} flag set to true can still force it to take effect urgently.
+ *
+ * @param status the end status.
+ * @param endedBy the {@link CallerInfo} of the session that requested this session to end.
+ * @param immediate indicates whether cancellation should abort urgently and skip cleanup steps.
+ */
+ void requestEnd(@NonNull Status status, @Nullable CallerInfo endedBy, boolean immediate);
/**
* Session status with reference to values from vibratormanagerservice.proto for logging.
@@ -119,7 +131,7 @@
public final String reason;
CallerInfo(@NonNull VibrationAttributes attrs, int uid, int deviceId, String opPkg,
- String reason) {
+ @Nullable String reason) {
Objects.requireNonNull(attrs);
this.attrs = attrs;
this.uid = uid;
diff --git a/services/core/java/com/android/server/vibrator/VibrationStepConductor.java b/services/core/java/com/android/server/vibrator/VibrationStepConductor.java
index 5137d19..1d52e3c 100644
--- a/services/core/java/com/android/server/vibrator/VibrationStepConductor.java
+++ b/services/core/java/com/android/server/vibrator/VibrationStepConductor.java
@@ -21,6 +21,7 @@
import android.os.Build;
import android.os.CombinedVibration;
import android.os.IBinder;
+import android.os.RemoteException;
import android.os.VibrationEffect;
import android.os.vibrator.Flags;
import android.os.vibrator.PrebakedSegment;
@@ -38,6 +39,7 @@
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
+import java.util.NoSuchElementException;
import java.util.PriorityQueue;
import java.util.Queue;
import java.util.concurrent.CancellationException;
@@ -358,6 +360,28 @@
}
/**
+ * Returns true if successfully linked this conductor to the death of the binder that requested
+ * the vibration.
+ */
+ public boolean linkToDeath() {
+ try {
+ mVibration.callerToken.linkToDeath(this, 0);
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Error linking vibration to token death", e);
+ return false;
+ }
+ return true;
+ }
+
+ public void unlinkToDeath() {
+ try {
+ mVibration.callerToken.unlinkToDeath(this, 0);
+ } catch (NoSuchElementException e) {
+ Slog.wtf(TAG, "Failed to unlink vibration to token death", e);
+ }
+ }
+
+ /**
* Notify the execution that cancellation is requested. This will be acted upon
* asynchronously in the VibrationThread.
*
@@ -452,6 +476,23 @@
}
}
+ /**
+ * Notify that the VibrationThread has completed the vibration effect playback.
+ *
+ * <p>This is a lightweight method intended to be called by the vibration thread directly. The
+ * VibrationThread may still be continuing with cleanup tasks, and should not be given new work
+ * until it notifies the manager that it has been released.
+ */
+ public void notifyVibrationComplete(@NonNull Vibration.EndInfo endInfo) {
+ if (Build.IS_DEBUGGABLE) {
+ expectIsVibrationThread(true);
+ }
+ if (DEBUG) {
+ Slog.d(TAG, "Vibration " + mVibration.id + " finished with " + endInfo);
+ }
+ mVibration.end(endInfo);
+ }
+
/** Returns true if a cancellation signal was sent via {@link #notifyCancelled}. */
public boolean wasNotifiedToCancel() {
if (Build.IS_DEBUGGABLE) {
diff --git a/services/core/java/com/android/server/vibrator/VibrationThread.java b/services/core/java/com/android/server/vibrator/VibrationThread.java
index 4c1e16c..090e679 100644
--- a/services/core/java/com/android/server/vibrator/VibrationThread.java
+++ b/services/core/java/com/android/server/vibrator/VibrationThread.java
@@ -18,10 +18,8 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
-import android.os.IBinder;
import android.os.PowerManager;
import android.os.Process;
-import android.os.RemoteException;
import android.os.SystemClock;
import android.os.Trace;
import android.os.WorkSource;
@@ -31,7 +29,6 @@
import com.android.internal.annotations.VisibleForTesting;
import com.android.server.vibrator.VibrationSession.Status;
-import java.util.NoSuchElementException;
import java.util.Objects;
/** Plays a {@link HalVibration} in dedicated thread. */
@@ -72,14 +69,6 @@
void noteVibratorOff(int uid);
/**
- * Tell the manager that the currently active vibration has completed its vibration, from
- * the perspective of the Effect. However, the VibrationThread may still be continuing with
- * cleanup tasks, and should not be given new work until {@link #onVibrationThreadReleased}
- * is called.
- */
- void onVibrationCompleted(long vibrationId, @NonNull Vibration.EndInfo vibrationEndInfo);
-
- /**
* Tells the manager that the VibrationThread is finished with the previous vibration and
* all of its cleanup tasks, and the vibrators can now be used for another vibration.
*/
@@ -243,7 +232,7 @@
mWakeLock.acquire();
try {
try {
- runCurrentVibrationWithWakeLockAndDeathLink();
+ playVibration();
} finally {
clientVibrationCompleteIfNotAlready(
new Vibration.EndInfo(Status.FINISHED_UNEXPECTED));
@@ -254,41 +243,18 @@
}
}
- /**
- * Runs the VibrationThread with the binder death link, handling link/unlink failures.
- * Called from within runWithWakeLock.
- */
- private void runCurrentVibrationWithWakeLockAndDeathLink() {
- IBinder vibrationBinderToken = mExecutingConductor.getVibration().callerToken;
- try {
- vibrationBinderToken.linkToDeath(mExecutingConductor, 0);
- } catch (RemoteException e) {
- Slog.e(TAG, "Error linking vibration to token death", e);
- clientVibrationCompleteIfNotAlready(
- new Vibration.EndInfo(Status.IGNORED_ERROR_TOKEN));
- return;
- }
- // Ensure that the unlink always occurs now.
- try {
- // This is the actual execution of the vibration.
- playVibration();
- } finally {
- try {
- vibrationBinderToken.unlinkToDeath(mExecutingConductor, 0);
- } catch (NoSuchElementException e) {
- Slog.wtf(TAG, "Failed to unlink token", e);
- }
- }
- }
-
// Indicate that the vibration is complete. This can be called multiple times only for
// convenience of handling error conditions - an error after the client is complete won't
// affect the status.
private void clientVibrationCompleteIfNotAlready(@NonNull Vibration.EndInfo vibrationEndInfo) {
if (!mCalledVibrationCompleteCallback) {
mCalledVibrationCompleteCallback = true;
- mVibratorManagerHooks.onVibrationCompleted(
- mExecutingConductor.getVibration().id, vibrationEndInfo);
+ Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "notifyVibrationComplete");
+ try {
+ mExecutingConductor.notifyVibrationComplete(vibrationEndInfo);
+ } finally {
+ Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR);
+ }
}
}
diff --git a/services/core/java/com/android/server/vibrator/VibratorManagerService.java b/services/core/java/com/android/server/vibrator/VibratorManagerService.java
index a76d8d6..bd17e5d 100644
--- a/services/core/java/com/android/server/vibrator/VibratorManagerService.java
+++ b/services/core/java/com/android/server/vibrator/VibratorManagerService.java
@@ -633,12 +633,9 @@
final long ident = Binder.clearCallingIdentity();
try {
if (mCurrentExternalVibration != null) {
- mCurrentExternalVibration.notifyEnded();
vib.stats.reportInterruptedAnotherVibration(
- mCurrentExternalVibration.callerInfo);
- endExternalVibrateLocked(
- new Vibration.EndInfo(Status.CANCELLED_SUPERSEDED,
- vib.callerInfo),
+ mCurrentExternalVibration.getCallerInfo());
+ endExternalVibrateLocked(Status.CANCELLED_SUPERSEDED, vib.callerInfo,
/* continueExternalControl= */ false);
} else if (mCurrentVibration != null) {
if (mCurrentVibration.getVibration().canPipelineWith(vib)) {
@@ -666,7 +663,7 @@
// Ignored or failed to start the vibration, end it and report metrics right away.
if (vibrationEndInfo != null) {
- endVibrationLocked(vib, vibrationEndInfo, /* shouldWriteStats= */ true);
+ endVibrationLocked(vib, vibrationEndInfo);
}
return vib;
}
@@ -703,9 +700,8 @@
&& shouldCancelVibration(
mCurrentExternalVibration.getCallerInfo().attrs,
usageFilter)) {
- mCurrentExternalVibration.notifyEnded();
- endExternalVibrateLocked(
- cancelledByUserInfo, /* continueExternalControl= */ false);
+ endExternalVibrateLocked(cancelledByUserInfo.status,
+ cancelledByUserInfo.endedBy, /* continueExternalControl= */ false);
}
} finally {
Binder.restoreCallingIdentity(ident);
@@ -937,6 +933,11 @@
Trace.asyncTraceBegin(Trace.TRACE_TAG_VIBRATOR, "vibration", 0);
// Make sure mCurrentVibration is set while triggering the VibrationThread.
mCurrentVibration = conductor;
+ if (!mCurrentVibration.linkToDeath()) {
+ // Shouldn't happen. The method call already logs a wtf.
+ mCurrentVibration = null; // Aborted.
+ return new Vibration.EndInfo(Status.IGNORED_ERROR_TOKEN);
+ }
if (!mVibrationThread.runVibrationOnVibrationThread(mCurrentVibration)) {
// Shouldn't happen. The method call already logs a wtf.
mCurrentVibration = null; // Aborted.
@@ -953,14 +954,21 @@
}
@GuardedBy("mLock")
- private void endVibrationLocked(Vibration vib, Vibration.EndInfo vibrationEndInfo,
- boolean shouldWriteStats) {
+ private void endVibrationLocked(Vibration vib, Status status) {
+ endVibrationLocked(vib, new Vibration.EndInfo(status));
+ }
+
+ @GuardedBy("mLock")
+ private void endVibrationLocked(Vibration vib, Vibration.EndInfo vibrationEndInfo) {
vib.end(vibrationEndInfo);
+ reportEndedVibrationLocked(vib);
+ }
+
+ @GuardedBy("mLock")
+ private void reportEndedVibrationLocked(Vibration vib) {
logAndRecordVibration(vib.getDebugInfo());
- if (shouldWriteStats) {
- mFrameworkStatsLogger.writeVibrationReportedAsync(
- vib.getStatsInfo(/* completionUptimeMillis= */ SystemClock.uptimeMillis()));
- }
+ mFrameworkStatsLogger.writeVibrationReportedAsync(
+ vib.getStatsInfo(/* completionUptimeMillis= */ SystemClock.uptimeMillis()));
}
private VibrationStepConductor createVibrationStepConductor(HalVibration vib) {
@@ -1055,17 +1063,15 @@
}
@GuardedBy("mLock")
- private void reportFinishedVibrationLocked(Vibration.EndInfo vibrationEndInfo) {
+ private void reportFinishedVibrationLocked() {
Trace.asyncTraceEnd(Trace.TRACE_TAG_VIBRATOR, "vibration", 0);
+ mCurrentVibration.unlinkToDeath();
HalVibration vib = mCurrentVibration.getVibration();
if (DEBUG) {
- Slog.d(TAG, "Reporting vibration " + vib.id + " finished with "
- + vibrationEndInfo);
+ Slog.d(TAG, "Reporting vibration " + vib.id + " finished with " + vib.getStatus());
}
- // DO NOT write metrics at this point, wait for the VibrationThread to report the
- // vibration was released, after all cleanup. The metrics will be reported then.
- endVibrationLocked(vib, vibrationEndInfo, /* shouldWriteStats= */ false);
finishAppOpModeLocked(vib.callerInfo);
+ reportEndedVibrationLocked(vib);
}
private void onSyncedVibrationComplete(long vibrationId) {
@@ -1647,24 +1653,6 @@
}
@Override
- public void onVibrationCompleted(long vibrationId, Vibration.EndInfo vibrationEndInfo) {
- if (DEBUG) {
- Slog.d(TAG, "Vibration " + vibrationId + " finished with " + vibrationEndInfo);
- }
- Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "onVibrationCompleted");
- try {
- synchronized (mLock) {
- if (mCurrentVibration != null
- && mCurrentVibration.getVibration().id == vibrationId) {
- reportFinishedVibrationLocked(vibrationEndInfo);
- }
- }
- } finally {
- Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR);
- }
- }
-
- @Override
public void onVibrationThreadReleased(long vibrationId) {
if (DEBUG) {
Slog.d(TAG, "VibrationThread released after finished vibration");
@@ -1682,11 +1670,8 @@
mCurrentVibration.getVibration().id, vibrationId));
}
if (mCurrentVibration != null) {
- // This is when we consider the current vibration complete, so report
- // metrics.
- mFrameworkStatsLogger.writeVibrationReportedAsync(
- mCurrentVibration.getVibration().getStatsInfo(
- /* completionUptimeMillis= */ SystemClock.uptimeMillis()));
+ // This is when we consider the current vibration complete, report metrics.
+ reportFinishedVibrationLocked();
mCurrentVibration = null;
}
if (mNextVibration != null) {
@@ -1696,8 +1681,7 @@
nextConductor);
if (vibrationEndInfo != null) {
// Failed to start the vibration, end it and report metrics right away.
- endVibrationLocked(nextConductor.getVibration(),
- vibrationEndInfo, /* shouldWriteStats= */ true);
+ endVibrationLocked(nextConductor.getVibration(), vibrationEndInfo);
}
}
}
@@ -1929,8 +1913,7 @@
+ " with end info: " + vibrationEndInfo);
}
// Clearing next vibration before playing it, end it and report metrics right away.
- endVibrationLocked(mNextVibration.getVibration(), vibrationEndInfo,
- /* shouldWriteStats= */ true);
+ endVibrationLocked(mNextVibration.getVibration(), vibrationEndInfo);
mNextVibration = null;
}
}
@@ -1938,23 +1921,24 @@
/**
* Ends the external vibration, and clears related service state.
*
- * @param vibrationEndInfo the status and related info to end the associated Vibration
+ * @param status the status to end the associated Vibration
+ * @param endedBy the caller that caused this vibration to end
* @param continueExternalControl indicates whether external control will continue. If not, the
* HAL will have external control turned off.
*/
@GuardedBy("mLock")
- private void endExternalVibrateLocked(Vibration.EndInfo vibrationEndInfo,
+ private void endExternalVibrateLocked(Status status, CallerInfo endedBy,
boolean continueExternalControl) {
if (mCurrentExternalVibration == null) {
return;
}
+ mCurrentExternalVibration.requestEnd(status, endedBy, /* immediate= */ true);
mCurrentExternalVibration.unlinkToDeath();
if (!continueExternalControl) {
setExternalControl(false, mCurrentExternalVibration.stats);
}
// The external control was turned off, end it and report metrics right away.
- endVibrationLocked(mCurrentExternalVibration, vibrationEndInfo,
- /* shouldWriteStats= */ true);
+ reportEndedVibrationLocked(mCurrentExternalVibration);
mCurrentExternalVibration = null;
}
@@ -2022,9 +2006,7 @@
synchronized (mLock) {
if (!hasExternalControlCapability()) {
- endVibrationLocked(externalVibration,
- new Vibration.EndInfo(Status.IGNORED_UNSUPPORTED),
- /* shouldWriteStats= */ true);
+ endVibrationLocked(externalVibration, Status.IGNORED_UNSUPPORTED);
return externalVibration.getScale();
}
@@ -2035,9 +2017,7 @@
Slog.w(TAG, "pkg=" + vib.getPackage() + ", uid=" + vib.getUid()
+ " tried to play externally controlled vibration"
+ " without VIBRATE permission, ignoring.");
- endVibrationLocked(externalVibration,
- new Vibration.EndInfo(Status.IGNORED_MISSING_PERMISSION),
- /* shouldWriteStats= */ true);
+ endVibrationLocked(externalVibration, Status.IGNORED_MISSING_PERMISSION);
return externalVibration.getScale();
}
@@ -2058,8 +2038,7 @@
}
if (vibrationEndInfo != null) {
- endVibrationLocked(externalVibration, vibrationEndInfo,
- /* shouldWriteStats= */ true);
+ endVibrationLocked(externalVibration, vibrationEndInfo);
return externalVibration.getScale();
}
@@ -2092,15 +2071,32 @@
// as we would need to mute the old one still if it came from a different
// controller.
alreadyUnderExternalControl = true;
- mCurrentExternalVibration.notifyEnded();
externalVibration.stats.reportInterruptedAnotherVibration(
- mCurrentExternalVibration.callerInfo);
- endExternalVibrateLocked(
- new Vibration.EndInfo(Status.CANCELLED_SUPERSEDED,
- externalVibration.callerInfo),
- /* continueExternalControl= */ true);
+ mCurrentExternalVibration.getCallerInfo());
+ endExternalVibrateLocked(Status.CANCELLED_SUPERSEDED,
+ externalVibration.callerInfo, /* continueExternalControl= */ true);
}
-
+ }
+ // Wait for lock and interact with HAL to set external control outside main lock.
+ if (waitForCompletion) {
+ if (!mVibrationThread.waitForThreadIdle(VIBRATION_CANCEL_WAIT_MILLIS)) {
+ Slog.e(TAG, "Timed out waiting for vibration to cancel");
+ synchronized (mLock) {
+ endVibrationLocked(externalVibration, Status.IGNORED_ERROR_CANCELLING);
+ return externalVibration.getScale();
+ }
+ }
+ }
+ if (!alreadyUnderExternalControl) {
+ if (DEBUG) {
+ Slog.d(TAG, "Vibrator going under external control.");
+ }
+ setExternalControl(true, externalVibration.stats);
+ }
+ synchronized (mLock) {
+ if (DEBUG) {
+ Slog.d(TAG, "Playing external vibration: " + vib);
+ }
VibrationAttributes attrs = fixupVibrationAttributes(
vib.getVibrationAttributes(),
/* effect= */ null);
@@ -2113,35 +2109,12 @@
mCurrentExternalVibration = externalVibration;
externalVibration.linkToDeath(this::onExternalVibrationBinderDied);
externalVibration.scale(mVibrationScaler, attrs.getUsage());
- }
- if (waitForCompletion) {
- if (!mVibrationThread.waitForThreadIdle(VIBRATION_CANCEL_WAIT_MILLIS)) {
- Slog.e(TAG, "Timed out waiting for vibration to cancel");
- synchronized (mLock) {
- // Trigger endExternalVibrateLocked to unlink to death recipient.
- endExternalVibrateLocked(
- new Vibration.EndInfo(Status.IGNORED_ERROR_CANCELLING),
- /* continueExternalControl= */ false);
- // Mute the request, vibration will be ignored.
- externalVibration.muteScale();
- }
- return externalVibration.getScale();
- }
+ // Vibrator will start receiving data from external channels after this point.
+ // Report current time as the vibration start time, for debugging.
+ externalVibration.stats.reportStarted();
+ return externalVibration.getScale();
}
- if (!alreadyUnderExternalControl) {
- if (DEBUG) {
- Slog.d(TAG, "Vibrator going under external control.");
- }
- setExternalControl(true, externalVibration.stats);
- }
- if (DEBUG) {
- Slog.d(TAG, "Playing external vibration: " + vib);
- }
- // Vibrator will start receiving data from external channels after this point.
- // Report current time as the vibration start time, for debugging.
- externalVibration.stats.reportStarted();
- return externalVibration.getScale();
} finally {
Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR);
}
@@ -2157,8 +2130,7 @@
if (DEBUG) {
Slog.d(TAG, "Stopping external vibration: " + vib);
}
- endExternalVibrateLocked(
- new Vibration.EndInfo(Status.FINISHED),
+ endExternalVibrateLocked(Status.FINISHED, /* endedBy= */ null,
/* continueExternalControl= */ false);
}
}
@@ -2182,8 +2154,7 @@
if (DEBUG) {
Slog.d(TAG, "External vibration finished because binder died");
}
- endExternalVibrateLocked(
- new Vibration.EndInfo(Status.CANCELLED_BINDER_DIED),
+ endExternalVibrateLocked(Status.CANCELLED_BINDER_DIED, /* endedBy= */ null,
/* continueExternalControl= */ false);
}
}
diff --git a/services/tests/vibrator/src/com/android/server/vibrator/VibrationThreadTest.java b/services/tests/vibrator/src/com/android/server/vibrator/VibrationThreadTest.java
index 31cc50f1..e83a4b2 100644
--- a/services/tests/vibrator/src/com/android/server/vibrator/VibrationThreadTest.java
+++ b/services/tests/vibrator/src/com/android/server/vibrator/VibrationThreadTest.java
@@ -29,13 +29,11 @@
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.ArgumentMatchers.same;
import static org.mockito.Mockito.atLeast;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.inOrder;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.timeout;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -96,8 +94,6 @@
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
import java.util.function.BooleanSupplier;
import java.util.stream.Collectors;
@@ -187,11 +183,11 @@
mVibratorProviders.clear();
CombinedVibration effect = CombinedVibration.createParallel(
VibrationEffect.get(VibrationEffect.EFFECT_CLICK));
- long vibrationId = startThreadAndDispatcher(effect);
+ HalVibration vibration = startThreadAndDispatcher(effect);
waitForCompletion();
- verify(mControllerCallbacks, never()).onComplete(anyInt(), eq(vibrationId));
- verifyCallbacksTriggered(vibrationId, Status.IGNORED_UNSUPPORTED);
+ verify(mControllerCallbacks, never()).onComplete(anyInt(), eq(vibration.id));
+ verifyCallbacksTriggered(vibration, Status.IGNORED_UNSUPPORTED);
}
@Test
@@ -200,11 +196,11 @@
.addNext(2, VibrationEffect.get(VibrationEffect.EFFECT_CLICK))
.addNext(3, VibrationEffect.get(VibrationEffect.EFFECT_TICK))
.combine();
- long vibrationId = startThreadAndDispatcher(effect);
+ HalVibration vibration = startThreadAndDispatcher(effect);
waitForCompletion();
- verify(mControllerCallbacks, never()).onComplete(anyInt(), eq(vibrationId));
- verifyCallbacksTriggered(vibrationId, Status.IGNORED_UNSUPPORTED);
+ verify(mControllerCallbacks, never()).onComplete(anyInt(), eq(vibration.id));
+ verifyCallbacksTriggered(vibration, Status.IGNORED_UNSUPPORTED);
}
@Test
@@ -212,34 +208,34 @@
mVibratorProviders.get(VIBRATOR_ID).setCapabilities(IVibrator.CAP_AMPLITUDE_CONTROL);
VibrationEffect effect = VibrationEffect.createOneShot(10, 100);
- long vibrationId = startThreadAndDispatcher(effect);
+ HalVibration vibration = startThreadAndDispatcher(effect);
waitForCompletion();
verify(mManagerHooks).noteVibratorOn(eq(UID), eq(10L));
verify(mManagerHooks).noteVibratorOff(eq(UID));
- verify(mControllerCallbacks).onComplete(eq(VIBRATOR_ID), eq(vibrationId));
- verifyCallbacksTriggered(vibrationId, Status.FINISHED);
+ verify(mControllerCallbacks).onComplete(eq(VIBRATOR_ID), eq(vibration.id));
+ verifyCallbacksTriggered(vibration, Status.FINISHED);
assertFalse(mControllers.get(VIBRATOR_ID).isVibrating());
assertEquals(Arrays.asList(expectedOneShot(10)),
- mVibratorProviders.get(VIBRATOR_ID).getEffectSegments(vibrationId));
+ mVibratorProviders.get(VIBRATOR_ID).getEffectSegments(vibration.id));
assertEquals(expectedAmplitudes(100), mVibratorProviders.get(VIBRATOR_ID).getAmplitudes());
}
@Test
public void vibrate_oneShotWithoutAmplitudeControl_runsVibrationWithDefaultAmplitude() {
VibrationEffect effect = VibrationEffect.createOneShot(10, 100);
- long vibrationId = startThreadAndDispatcher(effect);
+ HalVibration vibration = startThreadAndDispatcher(effect);
waitForCompletion();
verify(mManagerHooks).noteVibratorOn(eq(UID), eq(10L));
verify(mManagerHooks).noteVibratorOff(eq(UID));
- verify(mControllerCallbacks).onComplete(eq(VIBRATOR_ID), eq(vibrationId));
- verifyCallbacksTriggered(vibrationId, Status.FINISHED);
+ verify(mControllerCallbacks).onComplete(eq(VIBRATOR_ID), eq(vibration.id));
+ verifyCallbacksTriggered(vibration, Status.FINISHED);
assertFalse(mControllers.get(VIBRATOR_ID).isVibrating());
assertEquals(Arrays.asList(expectedOneShot(10)),
- mVibratorProviders.get(VIBRATOR_ID).getEffectSegments(vibrationId));
+ mVibratorProviders.get(VIBRATOR_ID).getEffectSegments(vibration.id));
assertTrue(mVibratorProviders.get(VIBRATOR_ID).getAmplitudes().isEmpty());
}
@@ -249,17 +245,17 @@
VibrationEffect effect = VibrationEffect.createWaveform(
new long[]{5, 5, 5}, new int[]{1, 2, 3}, -1);
- long vibrationId = startThreadAndDispatcher(effect);
+ HalVibration vibration = startThreadAndDispatcher(effect);
waitForCompletion();
verify(mManagerHooks).noteVibratorOn(eq(UID), eq(15L));
verify(mManagerHooks).noteVibratorOff(eq(UID));
- verify(mControllerCallbacks).onComplete(eq(VIBRATOR_ID), eq(vibrationId));
- verifyCallbacksTriggered(vibrationId, Status.FINISHED);
+ verify(mControllerCallbacks).onComplete(eq(VIBRATOR_ID), eq(vibration.id));
+ verifyCallbacksTriggered(vibration, Status.FINISHED);
assertFalse(mControllers.get(VIBRATOR_ID).isVibrating());
assertEquals(Arrays.asList(expectedOneShot(15)),
- mVibratorProviders.get(VIBRATOR_ID).getEffectSegments(vibrationId));
+ mVibratorProviders.get(VIBRATOR_ID).getEffectSegments(vibration.id));
assertEquals(expectedAmplitudes(1, 2, 3),
mVibratorProviders.get(VIBRATOR_ID).getAmplitudes());
}
@@ -277,13 +273,13 @@
mVibrationScaler.updateAdaptiveHapticsScale(USAGE_RINGTONE, 0.5f);
CompletableFuture<Void> mRequestVibrationParamsFuture = CompletableFuture.completedFuture(
null);
- long vibrationId = startThreadAndDispatcher(effect, mRequestVibrationParamsFuture,
+ HalVibration vibration = startThreadAndDispatcher(effect, mRequestVibrationParamsFuture,
USAGE_RINGTONE);
waitForCompletion();
verify(mStatsLoggerMock, never()).logVibrationParamRequestTimeout(UID);
assertEquals(Arrays.asList(expectedOneShot(15)),
- mVibratorProviders.get(VIBRATOR_ID).getEffectSegments(vibrationId));
+ mVibratorProviders.get(VIBRATOR_ID).getEffectSegments(vibration.id));
List<Float> amplitudes = mVibratorProviders.get(VIBRATOR_ID).getAmplitudes();
for (int i = 0; i < amplitudes.size(); i++) {
assertTrue(amplitudes.get(i) < 1 / 255f);
@@ -301,12 +297,13 @@
new long[]{5, 5, 5}, new int[]{1, 1, 1}, -1);
CompletableFuture<Void> neverCompletingFuture = new CompletableFuture<>();
- long vibrationId = startThreadAndDispatcher(effect, neverCompletingFuture, USAGE_RINGTONE);
+ HalVibration vibration = startThreadAndDispatcher(effect, neverCompletingFuture,
+ USAGE_RINGTONE);
waitForCompletion();
verify(mStatsLoggerMock).logVibrationParamRequestTimeout(UID);
assertEquals(Arrays.asList(expectedOneShot(15)),
- mVibratorProviders.get(VIBRATOR_ID).getEffectSegments(vibrationId));
+ mVibratorProviders.get(VIBRATOR_ID).getEffectSegments(vibration.id));
assertEquals(expectedAmplitudes(1, 1, 1),
mVibratorProviders.get(VIBRATOR_ID).getAmplitudes());
}
@@ -319,13 +316,13 @@
int[] amplitudes = new int[]{1, 2, 3};
VibrationEffect effect = VibrationEffect.createWaveform(new long[]{5, 5, 5}, amplitudes, 0);
- long vibrationId = startThreadAndDispatcher(effect);
+ HalVibration vibration = startThreadAndDispatcher(effect);
assertTrue(
waitUntil(() -> fakeVibrator.getAmplitudes().size() > 2 * amplitudes.length,
TEST_TIMEOUT_MILLIS));
// Vibration still running after 2 cycles.
- assertTrue(mThread.isRunningVibrationId(vibrationId));
+ assertTrue(mThread.isRunningVibrationId(vibration.id));
assertTrue(mControllers.get(VIBRATOR_ID).isVibrating());
Vibration.EndInfo cancelVibrationInfo = new Vibration.EndInfo(Status.CANCELLED_SUPERSEDED,
@@ -333,15 +330,15 @@
/* uid= */ 1, /* deviceId= */ -1, /* opPkg= */ null, /* reason= */ null));
mVibrationConductor.notifyCancelled(cancelVibrationInfo, /* immediate= */ false);
waitForCompletion();
- assertFalse(mThread.isRunningVibrationId(vibrationId));
+ assertFalse(mThread.isRunningVibrationId(vibration.id));
verify(mManagerHooks).noteVibratorOn(eq(UID), anyLong());
verify(mManagerHooks).noteVibratorOff(eq(UID));
- verifyCallbacksTriggered(vibrationId, cancelVibrationInfo);
+ verifyCallbacksTriggered(vibration, Status.CANCELLED_SUPERSEDED);
assertFalse(mControllers.get(VIBRATOR_ID).isVibrating());
List<Float> playedAmplitudes = fakeVibrator.getAmplitudes();
- assertFalse(fakeVibrator.getEffectSegments(vibrationId).isEmpty());
+ assertFalse(fakeVibrator.getEffectSegments(vibration.id).isEmpty());
assertFalse(playedAmplitudes.isEmpty());
for (int i = 0; i < playedAmplitudes.size(); i++) {
@@ -358,17 +355,17 @@
int[] amplitudes = new int[]{1, 2, 3};
VibrationEffect effect = VibrationEffect.createWaveform(
new long[]{1, 10, 100}, amplitudes, 0);
- long vibrationId = startThreadAndDispatcher(effect);
+ HalVibration vibration = startThreadAndDispatcher(effect);
assertTrue(waitUntil(() -> !fakeVibrator.getAmplitudes().isEmpty(), TEST_TIMEOUT_MILLIS));
mVibrationConductor.notifyCancelled(
new Vibration.EndInfo(Status.CANCELLED_BY_USER), /* immediate= */ false);
waitForCompletion();
- verifyCallbacksTriggered(vibrationId, Status.CANCELLED_BY_USER);
+ verifyCallbacksTriggered(vibration, Status.CANCELLED_BY_USER);
assertFalse(mControllers.get(VIBRATOR_ID).isVibrating());
assertEquals(Arrays.asList(expectedOneShot(5000)),
- fakeVibrator.getEffectSegments(vibrationId));
+ fakeVibrator.getEffectSegments(vibration.id));
}
@Test
@@ -377,16 +374,16 @@
VibrationEffect effect = VibrationEffect.createWaveform(
/* timings= */ new long[]{0, 100, 50, 100, 0, 0, 0, 50}, /* repeat= */ -1);
- long vibrationId = startThreadAndDispatcher(effect);
+ HalVibration vibration = startThreadAndDispatcher(effect);
waitForCompletion();
verify(mManagerHooks).noteVibratorOn(eq(UID), eq(300L));
verify(mManagerHooks).noteVibratorOff(eq(UID));
- verifyCallbacksTriggered(vibrationId, Status.FINISHED);
+ verifyCallbacksTriggered(vibration, Status.FINISHED);
assertThat(mControllers.get(VIBRATOR_ID).isVibrating()).isFalse();
- assertThat(mVibratorProviders.get(VIBRATOR_ID).getEffectSegments(vibrationId))
+ assertThat(mVibratorProviders.get(VIBRATOR_ID).getEffectSegments(vibration.id))
.isEqualTo(expectedOneShots(100L, 150L));
}
@@ -398,16 +395,16 @@
VibrationEffect effect = VibrationEffect.createWaveform(
/* timings= */ new long[]{0, 100, 0, 50, 50, 0, 100, 50}, amplitudes,
/* repeat= */ -1);
- long vibrationId = startThreadAndDispatcher(effect);
+ HalVibration vibration = startThreadAndDispatcher(effect);
waitForCompletion();
verify(mManagerHooks).noteVibratorOn(eq(UID), eq(350L));
verify(mManagerHooks).noteVibratorOff(eq(UID));
- verifyCallbacksTriggered(vibrationId, Status.FINISHED);
+ verifyCallbacksTriggered(vibration, Status.FINISHED);
assertThat(mControllers.get(VIBRATOR_ID).isVibrating()).isFalse();
- assertThat(mVibratorProviders.get(VIBRATOR_ID).getEffectSegments(vibrationId))
+ assertThat(mVibratorProviders.get(VIBRATOR_ID).getEffectSegments(vibration.id))
.isEqualTo(expectedOneShots(200L, 50L));
}
@@ -420,7 +417,7 @@
VibrationEffect effect = VibrationEffect.createWaveform(
/* timings= */ new long[]{0, 200, 50, 100, 0, 50, 50, 100}, /* repeat= */ 0);
- long vibrationId = startThreadAndDispatcher(effect);
+ HalVibration vibration = startThreadAndDispatcher(effect);
// We are expect this test to repeat the vibration effect twice, which would result in 5
// segments being played:
// 200ms ON
@@ -428,16 +425,17 @@
// 300ms ON (100ms + 200ms looping to the start and skipping first 0ms)
// 150ms ON (100ms + 50ms, skips 0ms)
// 300ms ON (100ms + 200ms looping to the start and skipping first 0ms)
- assertTrue(waitUntil(() -> fakeVibrator.getEffectSegments(vibrationId).size() >= 5,
+ assertTrue(waitUntil(() -> fakeVibrator.getEffectSegments(vibration.id).size() >= 5,
5000L + TEST_TIMEOUT_MILLIS));
mVibrationConductor.notifyCancelled(
new Vibration.EndInfo(Status.CANCELLED_BY_USER), /* immediate= */ false);
waitForCompletion();
- verifyCallbacksTriggered(vibrationId, Status.CANCELLED_BY_USER);
+ verifyCallbacksTriggered(vibration, Status.CANCELLED_BY_USER);
assertThat(mControllers.get(VIBRATOR_ID).isVibrating()).isFalse();
- assertThat(mVibratorProviders.get(VIBRATOR_ID).getEffectSegments(vibrationId).subList(0, 5))
+ assertThat(
+ mVibratorProviders.get(VIBRATOR_ID).getEffectSegments(vibration.id).subList(0, 5))
.isEqualTo(expectedOneShots(200L, 150L, 300L, 150L, 300L));
}
@@ -458,18 +456,18 @@
VibrationEffect repeatingEffect = VibrationEffect.startComposition()
.repeatEffectIndefinitely(effect)
.compose();
- long vibrationId = startThreadAndDispatcher(repeatingEffect);
+ HalVibration vibration = startThreadAndDispatcher(repeatingEffect);
- assertTrue(waitUntil(() -> !fakeVibrator.getEffectSegments(vibrationId).isEmpty(),
+ assertTrue(waitUntil(() -> !fakeVibrator.getEffectSegments(vibration.id).isEmpty(),
TEST_TIMEOUT_MILLIS));
mVibrationConductor.notifyCancelled(
new Vibration.EndInfo(Status.CANCELLED_BY_USER), /* immediate= */ false);
waitForCompletion();
// PWLE size max was used to generate a single vibrate call with 10 segments.
- verifyCallbacksTriggered(vibrationId, Status.CANCELLED_BY_USER);
+ verifyCallbacksTriggered(vibration, Status.CANCELLED_BY_USER);
assertFalse(mControllers.get(VIBRATOR_ID).isVibrating());
- assertEquals(10, fakeVibrator.getEffectSegments(vibrationId).size());
+ assertEquals(10, fakeVibrator.getEffectSegments(vibration.id).size());
}
@Test
@@ -487,18 +485,18 @@
VibrationEffect repeatingEffect = VibrationEffect.startComposition()
.repeatEffectIndefinitely(effect)
.compose();
- long vibrationId = startThreadAndDispatcher(repeatingEffect);
+ HalVibration vibration = startThreadAndDispatcher(repeatingEffect);
- assertTrue(waitUntil(() -> !fakeVibrator.getEffectSegments(vibrationId).isEmpty(),
+ assertTrue(waitUntil(() -> !fakeVibrator.getEffectSegments(vibration.id).isEmpty(),
TEST_TIMEOUT_MILLIS));
mVibrationConductor.notifyCancelled(
new Vibration.EndInfo(Status.CANCELLED_BY_SCREEN_OFF), /* immediate= */ false);
waitForCompletion();
// Composition size max was used to generate a single vibrate call with 10 primitives.
- verifyCallbacksTriggered(vibrationId, Status.CANCELLED_BY_SCREEN_OFF);
+ verifyCallbacksTriggered(vibration, Status.CANCELLED_BY_SCREEN_OFF);
assertFalse(mControllers.get(VIBRATOR_ID).isVibrating());
- assertEquals(10, fakeVibrator.getEffectSegments(vibrationId).size());
+ assertEquals(10, fakeVibrator.getEffectSegments(vibration.id).size());
}
@Test
@@ -510,17 +508,17 @@
int[] amplitudes = new int[]{1, 2, 3};
VibrationEffect effect = VibrationEffect.createWaveform(
new long[]{5000, 500, 50}, amplitudes, 0);
- long vibrationId = startThreadAndDispatcher(effect);
+ HalVibration vibration = startThreadAndDispatcher(effect);
assertTrue(waitUntil(() -> !fakeVibrator.getAmplitudes().isEmpty(), TEST_TIMEOUT_MILLIS));
mVibrationConductor.notifyCancelled(
new Vibration.EndInfo(Status.CANCELLED_BY_USER), /* immediate= */ false);
waitForCompletion();
- verifyCallbacksTriggered(vibrationId, Status.CANCELLED_BY_USER);
+ verifyCallbacksTriggered(vibration, Status.CANCELLED_BY_USER);
assertFalse(mControllers.get(VIBRATOR_ID).isVibrating());
assertEquals(Arrays.asList(expectedOneShot(5550)),
- fakeVibrator.getEffectSegments(vibrationId));
+ fakeVibrator.getEffectSegments(vibration.id));
}
@LargeTest
@@ -534,17 +532,17 @@
VibrationEffect effect = VibrationEffect.createWaveform(
/* timings= */ new long[]{expectedOnDuration - 100, 50},
/* amplitudes= */ new int[]{1, 2}, /* repeat= */ 0);
- long vibrationId = startThreadAndDispatcher(effect);
+ HalVibration vibration = startThreadAndDispatcher(effect);
- assertTrue(waitUntil(() -> fakeVibrator.getEffectSegments(vibrationId).size() > 1,
+ assertTrue(waitUntil(() -> fakeVibrator.getEffectSegments(vibration.id).size() > 1,
expectedOnDuration + TEST_TIMEOUT_MILLIS));
mVibrationConductor.notifyCancelled(
new Vibration.EndInfo(Status.CANCELLED_BY_USER), /* immediate= */ false);
waitForCompletion();
- verifyCallbacksTriggered(vibrationId, Status.CANCELLED_BY_USER);
+ verifyCallbacksTriggered(vibration, Status.CANCELLED_BY_USER);
assertFalse(mControllers.get(VIBRATOR_ID).isVibrating());
- List<VibrationEffectSegment> effectSegments = fakeVibrator.getEffectSegments(vibrationId);
+ List<VibrationEffectSegment> effectSegments = fakeVibrator.getEffectSegments(vibration.id);
// First time, turn vibrator ON for the expected fixed duration.
assertEquals(expectedOnDuration, effectSegments.get(0).getDuration());
// Vibrator turns off in the middle of the second execution of the first step. Expect it to
@@ -567,11 +565,11 @@
.addPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK, 1f, 100)
.addPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK, 1f, 100)
.compose();
- long vibrationId = startThreadAndDispatcher(effect);
+ HalVibration vibration = startThreadAndDispatcher(effect);
assertTrue(waitUntil(() -> mControllers.get(VIBRATOR_ID).isVibrating(),
TEST_TIMEOUT_MILLIS));
- assertTrue(mThread.isRunningVibrationId(vibrationId));
+ assertTrue(mThread.isRunningVibrationId(vibration.id));
// Run cancel in a separate thread so if VibrationThread.cancel blocks then this test should
// fail at waitForCompletion(vibrationThread) if the vibration not cancelled immediately.
@@ -584,7 +582,7 @@
waitForCompletion(/* timeout= */ 50);
cancellingThread.join();
- verifyCallbacksTriggered(vibrationId, Status.CANCELLED_BY_SETTINGS_UPDATE);
+ verifyCallbacksTriggered(vibration, Status.CANCELLED_BY_SETTINGS_UPDATE);
assertFalse(mControllers.get(VIBRATOR_ID).isVibrating());
}
@@ -597,11 +595,11 @@
mVibratorProviders.get(VIBRATOR_ID).setVendorEffectDuration(10 * TEST_TIMEOUT_MILLIS);
VibrationEffect effect = VibrationEffect.createVendorEffect(createTestVendorData());
- long vibrationId = startThreadAndDispatcher(effect);
+ HalVibration vibration = startThreadAndDispatcher(effect);
assertTrue(waitUntil(() -> mControllers.get(VIBRATOR_ID).isVibrating(),
TEST_TIMEOUT_MILLIS));
- assertTrue(mThread.isRunningVibrationId(vibrationId));
+ assertTrue(mThread.isRunningVibrationId(vibration.id));
// Run cancel in a separate thread so if VibrationThread.cancel blocks then this test should
// fail at waitForCompletion(vibrationThread) if the vibration not cancelled immediately.
@@ -614,7 +612,7 @@
waitForCompletion(/* timeout= */ 50);
cancellingThread.join();
- verifyCallbacksTriggered(vibrationId, Status.CANCELLED_BY_SETTINGS_UPDATE);
+ verifyCallbacksTriggered(vibration, Status.CANCELLED_BY_SETTINGS_UPDATE);
assertFalse(mControllers.get(VIBRATOR_ID).isVibrating());
}
@@ -624,11 +622,11 @@
mVibratorProviders.get(VIBRATOR_ID).setCapabilities(IVibrator.CAP_COMPOSE_EFFECTS);
VibrationEffect effect = VibrationEffect.createWaveform(new long[]{100}, new int[]{100}, 0);
- long vibrationId = startThreadAndDispatcher(effect);
+ HalVibration vibration = startThreadAndDispatcher(effect);
assertTrue(waitUntil(() -> mControllers.get(VIBRATOR_ID).isVibrating(),
TEST_TIMEOUT_MILLIS));
- assertTrue(mThread.isRunningVibrationId(vibrationId));
+ assertTrue(mThread.isRunningVibrationId(vibration.id));
// Run cancel in a separate thread so if VibrationThread.cancel blocks then this test should
// fail at waitForCompletion(vibrationThread) if the vibration not cancelled immediately.
@@ -641,7 +639,7 @@
waitForCompletion(/* timeout= */ 50);
cancellingThread.join();
- verifyCallbacksTriggered(vibrationId, Status.CANCELLED_BY_SCREEN_OFF);
+ verifyCallbacksTriggered(vibration, Status.CANCELLED_BY_SCREEN_OFF);
assertFalse(mControllers.get(VIBRATOR_ID).isVibrating());
}
@@ -650,17 +648,17 @@
mVibratorProviders.get(1).setSupportedEffects(VibrationEffect.EFFECT_THUD);
VibrationEffect effect = VibrationEffect.get(VibrationEffect.EFFECT_THUD);
- long vibrationId = startThreadAndDispatcher(effect);
+ HalVibration vibration = startThreadAndDispatcher(effect);
waitForCompletion();
verify(mManagerHooks).noteVibratorOn(eq(UID), eq(20L));
verify(mManagerHooks).noteVibratorOff(eq(UID));
- verify(mControllerCallbacks).onComplete(eq(VIBRATOR_ID), eq(vibrationId));
- verifyCallbacksTriggered(vibrationId, Status.FINISHED);
+ verify(mControllerCallbacks).onComplete(eq(VIBRATOR_ID), eq(vibration.id));
+ verifyCallbacksTriggered(vibration, Status.FINISHED);
assertFalse(mControllers.get(VIBRATOR_ID).isVibrating());
assertEquals(Arrays.asList(expectedPrebaked(VibrationEffect.EFFECT_THUD)),
- mVibratorProviders.get(VIBRATOR_ID).getEffectSegments(vibrationId));
+ mVibratorProviders.get(VIBRATOR_ID).getEffectSegments(vibration.id));
}
@Test
@@ -671,31 +669,31 @@
HalVibration vibration = createVibration(CombinedVibration.createParallel(
VibrationEffect.get(VibrationEffect.EFFECT_CLICK)));
vibration.addFallback(VibrationEffect.EFFECT_CLICK, fallback);
- long vibrationId = startThreadAndDispatcher(vibration);
+ startThreadAndDispatcher(vibration);
waitForCompletion();
verify(mManagerHooks).noteVibratorOn(eq(UID), eq(10L));
verify(mManagerHooks).noteVibratorOff(eq(UID));
- verify(mControllerCallbacks).onComplete(eq(VIBRATOR_ID), eq(vibrationId));
- verifyCallbacksTriggered(vibrationId, Status.FINISHED);
+ verify(mControllerCallbacks).onComplete(eq(VIBRATOR_ID), eq(vibration.id));
+ verifyCallbacksTriggered(vibration, Status.FINISHED);
assertFalse(mControllers.get(VIBRATOR_ID).isVibrating());
assertEquals(Arrays.asList(expectedOneShot(10)),
- mVibratorProviders.get(VIBRATOR_ID).getEffectSegments(vibrationId));
+ mVibratorProviders.get(VIBRATOR_ID).getEffectSegments(vibration.id));
assertEquals(expectedAmplitudes(100), mVibratorProviders.get(VIBRATOR_ID).getAmplitudes());
}
@Test
public void vibrate_singleVibratorPrebakedAndUnsupportedEffect_ignoresVibration() {
VibrationEffect effect = VibrationEffect.get(VibrationEffect.EFFECT_CLICK);
- long vibrationId = startThreadAndDispatcher(effect);
+ HalVibration vibration = startThreadAndDispatcher(effect);
waitForCompletion();
verify(mManagerHooks).noteVibratorOn(eq(UID), eq(0L));
verify(mManagerHooks, never()).noteVibratorOff(eq(UID));
- verify(mControllerCallbacks, never()).onComplete(eq(VIBRATOR_ID), eq(vibrationId));
- verifyCallbacksTriggered(vibrationId, Status.IGNORED_UNSUPPORTED);
- assertTrue(mVibratorProviders.get(VIBRATOR_ID).getEffectSegments(vibrationId).isEmpty());
+ verify(mControllerCallbacks, never()).onComplete(eq(VIBRATOR_ID), eq(vibration.id));
+ verifyCallbacksTriggered(vibration, Status.IGNORED_UNSUPPORTED);
+ assertTrue(mVibratorProviders.get(VIBRATOR_ID).getEffectSegments(vibration.id).isEmpty());
}
@Test
@@ -704,17 +702,17 @@
mVibratorProviders.get(1).setCapabilities(IVibrator.CAP_PERFORM_VENDOR_EFFECTS);
VibrationEffect effect = VibrationEffect.createVendorEffect(createTestVendorData());
- long vibrationId = startThreadAndDispatcher(effect);
+ HalVibration vibration = startThreadAndDispatcher(effect);
waitForCompletion();
verify(mManagerHooks).noteVibratorOn(eq(UID),
eq(PerformVendorEffectVibratorStep.VENDOR_EFFECT_MAX_DURATION_MS));
verify(mManagerHooks).noteVibratorOff(eq(UID));
- verify(mControllerCallbacks).onComplete(eq(VIBRATOR_ID), eq(vibrationId));
- verifyCallbacksTriggered(vibrationId, Status.FINISHED);
+ verify(mControllerCallbacks).onComplete(eq(VIBRATOR_ID), eq(vibration.id));
+ verifyCallbacksTriggered(vibration, Status.FINISHED);
assertThat(mControllers.get(VIBRATOR_ID).isVibrating()).isFalse();
- assertThat(mVibratorProviders.get(VIBRATOR_ID).getVendorEffects(vibrationId))
+ assertThat(mVibratorProviders.get(VIBRATOR_ID).getVendorEffects(vibration.id))
.containsExactly(effect)
.inOrder();
}
@@ -730,18 +728,18 @@
.addPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK, 1f)
.addPrimitive(VibrationEffect.Composition.PRIMITIVE_TICK, 0.5f)
.compose();
- long vibrationId = startThreadAndDispatcher(effect);
+ HalVibration vibration = startThreadAndDispatcher(effect);
waitForCompletion();
verify(mManagerHooks).noteVibratorOn(eq(UID), eq(40L));
verify(mManagerHooks).noteVibratorOff(eq(UID));
- verify(mControllerCallbacks).onComplete(eq(VIBRATOR_ID), eq(vibrationId));
- verifyCallbacksTriggered(vibrationId, Status.FINISHED);
+ verify(mControllerCallbacks).onComplete(eq(VIBRATOR_ID), eq(vibration.id));
+ verifyCallbacksTriggered(vibration, Status.FINISHED);
assertFalse(mControllers.get(VIBRATOR_ID).isVibrating());
assertEquals(Arrays.asList(
expectedPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK, 1, 0),
expectedPrimitive(VibrationEffect.Composition.PRIMITIVE_TICK, 0.5f, 0)),
- fakeVibrator.getEffectSegments(vibrationId));
+ fakeVibrator.getEffectSegments(vibration.id));
}
@Test
@@ -749,14 +747,14 @@
VibrationEffect effect = VibrationEffect.startComposition()
.addPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK, 1f)
.compose();
- long vibrationId = startThreadAndDispatcher(effect);
+ HalVibration vibration = startThreadAndDispatcher(effect);
waitForCompletion();
verify(mManagerHooks).noteVibratorOn(eq(UID), eq(0L));
verify(mManagerHooks, never()).noteVibratorOff(eq(UID));
- verify(mControllerCallbacks, never()).onComplete(eq(VIBRATOR_ID), eq(vibrationId));
- verifyCallbacksTriggered(vibrationId, Status.IGNORED_UNSUPPORTED);
- assertTrue(mVibratorProviders.get(VIBRATOR_ID).getEffectSegments(vibrationId).isEmpty());
+ verify(mControllerCallbacks, never()).onComplete(eq(VIBRATOR_ID), eq(vibration.id));
+ verifyCallbacksTriggered(vibration, Status.IGNORED_UNSUPPORTED);
+ assertTrue(mVibratorProviders.get(VIBRATOR_ID).getEffectSegments(vibration.id).isEmpty());
}
@Test
@@ -774,13 +772,13 @@
.addPrimitive(VibrationEffect.Composition.PRIMITIVE_TICK, 0.5f)
.addPrimitive(VibrationEffect.Composition.PRIMITIVE_SPIN, 0.8f)
.compose();
- long vibrationId = startThreadAndDispatcher(effect);
+ HalVibration vibration = startThreadAndDispatcher(effect);
waitForCompletion();
- verifyCallbacksTriggered(vibrationId, Status.FINISHED);
+ verifyCallbacksTriggered(vibration, Status.FINISHED);
// Vibrator compose called twice.
- verify(mControllerCallbacks, times(2)).onComplete(eq(VIBRATOR_ID), eq(vibrationId));
- assertEquals(3, fakeVibrator.getEffectSegments(vibrationId).size());
+ verify(mControllerCallbacks, times(2)).onComplete(eq(VIBRATOR_ID), eq(vibration.id));
+ assertEquals(3, fakeVibrator.getEffectSegments(vibration.id).size());
}
@Test
@@ -810,14 +808,14 @@
.build())
.addEffect(VibrationEffect.get(VibrationEffect.EFFECT_CLICK))
.compose();
- long vibrationId = startThreadAndDispatcher(effect);
+ HalVibration vibration = startThreadAndDispatcher(effect);
waitForCompletion();
// Use first duration the vibrator is turned on since we cannot estimate the clicks.
verify(mManagerHooks).noteVibratorOn(eq(UID), eq(10L));
verify(mManagerHooks).noteVibratorOff(eq(UID));
- verify(mControllerCallbacks, times(5)).onComplete(eq(VIBRATOR_ID), eq(vibrationId));
- verifyCallbacksTriggered(vibrationId, Status.FINISHED);
+ verify(mControllerCallbacks, times(5)).onComplete(eq(VIBRATOR_ID), eq(vibration.id));
+ verifyCallbacksTriggered(vibration, Status.FINISHED);
assertFalse(mControllers.get(VIBRATOR_ID).isVibrating());
assertEquals(Arrays.asList(
expectedOneShot(10),
@@ -829,7 +827,7 @@
expectedRamp(/* startAmplitude= */ 0.5f, /* endAmplitude= */ 0.7f,
/* startFrequencyHz= */ 100, /* endFrequencyHz= */ 120, /* duration= */ 20),
expectedPrebaked(VibrationEffect.EFFECT_CLICK)),
- mVibratorProviders.get(VIBRATOR_ID).getEffectSegments(vibrationId));
+ mVibratorProviders.get(VIBRATOR_ID).getEffectSegments(vibration.id));
assertEquals(expectedAmplitudes(100), mVibratorProviders.get(VIBRATOR_ID).getAmplitudes());
}
@@ -851,18 +849,18 @@
.compose();
HalVibration vibration = createVibration(CombinedVibration.createParallel(effect));
vibration.addFallback(VibrationEffect.EFFECT_TICK, fallback);
- long vibrationId = startThreadAndDispatcher(vibration);
+ startThreadAndDispatcher(vibration);
waitForCompletion();
// Use first duration the vibrator is turned on since we cannot estimate the clicks.
verify(mManagerHooks).noteVibratorOn(eq(UID), anyLong());
verify(mManagerHooks).noteVibratorOff(eq(UID));
- verify(mControllerCallbacks, times(4)).onComplete(eq(VIBRATOR_ID), eq(vibrationId));
- verifyCallbacksTriggered(vibrationId, Status.FINISHED);
+ verify(mControllerCallbacks, times(4)).onComplete(eq(VIBRATOR_ID), eq(vibration.id));
+ verifyCallbacksTriggered(vibration, Status.FINISHED);
assertFalse(mControllers.get(VIBRATOR_ID).isVibrating());
List<VibrationEffectSegment> segments =
- mVibratorProviders.get(VIBRATOR_ID).getEffectSegments(vibrationId);
+ mVibratorProviders.get(VIBRATOR_ID).getEffectSegments(vibration.id);
assertTrue("Wrong segments: " + segments, segments.size() >= 4);
assertTrue(segments.get(0) instanceof PrebakedSegment);
assertTrue(segments.get(1) instanceof PrimitiveSegment);
@@ -891,13 +889,13 @@
.addSustain(Duration.ofMillis(30))
.addTransition(Duration.ofMillis(40), targetAmplitude(0.6f), targetFrequency(200))
.build();
- long vibrationId = startThreadAndDispatcher(effect);
+ HalVibration vibration = startThreadAndDispatcher(effect);
waitForCompletion();
verify(mManagerHooks).noteVibratorOn(eq(UID), eq(100L));
verify(mManagerHooks).noteVibratorOff(eq(UID));
- verify(mControllerCallbacks).onComplete(eq(VIBRATOR_ID), eq(vibrationId));
- verifyCallbacksTriggered(vibrationId, Status.FINISHED);
+ verify(mControllerCallbacks).onComplete(eq(VIBRATOR_ID), eq(vibration.id));
+ verifyCallbacksTriggered(vibration, Status.FINISHED);
assertFalse(mControllers.get(VIBRATOR_ID).isVibrating());
assertEquals(Arrays.asList(
expectedRamp(/* amplitude= */ 1, /* frequencyHz= */ 150, /* duration= */ 10),
@@ -907,8 +905,8 @@
expectedRamp(/* startAmplitude= */ 0.5f, /* endAmplitude= */ 0.6f,
/* startFrequencyHz= */ 100, /* endFrequencyHz= */ 200,
/* duration= */ 40)),
- fakeVibrator.getEffectSegments(vibrationId));
- assertEquals(Arrays.asList(Braking.CLAB), fakeVibrator.getBraking(vibrationId));
+ fakeVibrator.getEffectSegments(vibration.id));
+ assertEquals(Arrays.asList(Braking.CLAB), fakeVibrator.getBraking(vibration.id));
}
@Test
@@ -932,15 +930,15 @@
.addTransition(Duration.ofMillis(40), targetAmplitude(0.7f), targetFrequency(200))
.addTransition(Duration.ofMillis(40), targetAmplitude(0.6f), targetFrequency(200))
.build();
- long vibrationId = startThreadAndDispatcher(effect);
+ HalVibration vibration = startThreadAndDispatcher(effect);
waitForCompletion();
- verifyCallbacksTriggered(vibrationId, Status.FINISHED);
+ verifyCallbacksTriggered(vibration, Status.FINISHED);
// Vibrator compose called 3 times with 2 segments instead of 2 times with 3 segments.
// Using best split points instead of max-packing PWLEs.
- verify(mControllerCallbacks, times(3)).onComplete(eq(VIBRATOR_ID), eq(vibrationId));
- assertEquals(6, fakeVibrator.getEffectSegments(vibrationId).size());
+ verify(mControllerCallbacks, times(3)).onComplete(eq(VIBRATOR_ID), eq(vibration.id));
+ assertEquals(6, fakeVibrator.getEffectSegments(vibration.id).size());
}
@Test
@@ -949,28 +947,28 @@
fakeVibrator.setCapabilities(IVibrator.CAP_AMPLITUDE_CONTROL);
VibrationEffect effect = VibrationEffect.createWaveform(new long[]{5}, new int[]{100}, 0);
- long vibrationId = startThreadAndDispatcher(effect);
+ HalVibration vibration = startThreadAndDispatcher(effect);
assertTrue(waitUntil(() -> fakeVibrator.getAmplitudes().size() > 2, TEST_TIMEOUT_MILLIS));
// Vibration still running after 2 cycles.
- assertTrue(mThread.isRunningVibrationId(vibrationId));
+ assertTrue(mThread.isRunningVibrationId(vibration.id));
assertTrue(mControllers.get(VIBRATOR_ID).isVibrating());
mVibrationConductor.binderDied();
waitForCompletion();
assertFalse(mControllers.get(VIBRATOR_ID).isVibrating());
- verifyCallbacksTriggered(vibrationId, Status.CANCELLED_BINDER_DIED);
+ verifyCallbacksTriggered(vibration, Status.CANCELLED_BINDER_DIED);
}
@Test
public void vibrate_singleVibrator_skipsSyncedCallbacks() {
mVibratorProviders.get(1).setCapabilities(IVibrator.CAP_AMPLITUDE_CONTROL);
- long vibrationId = startThreadAndDispatcher(VibrationEffect.createOneShot(10, 100));
+ HalVibration vibration = startThreadAndDispatcher(VibrationEffect.createOneShot(10, 100));
waitForCompletion();
- verifyCallbacksTriggered(vibrationId, Status.FINISHED);
+ verifyCallbacksTriggered(vibration, Status.FINISHED);
verify(mManagerHooks, never()).prepareSyncedVibration(anyLong(), any());
verify(mManagerHooks, never()).triggerSyncedVibration(anyLong());
verify(mManagerHooks, never()).cancelSyncedVibration();
@@ -984,18 +982,18 @@
.addVibrator(VIBRATOR_ID, VibrationEffect.get(VibrationEffect.EFFECT_TICK))
.addVibrator(2, VibrationEffect.get(VibrationEffect.EFFECT_TICK))
.combine();
- long vibrationId = startThreadAndDispatcher(effect);
+ HalVibration vibration = startThreadAndDispatcher(effect);
waitForCompletion();
verify(mManagerHooks).noteVibratorOn(eq(UID), eq(20L));
verify(mManagerHooks).noteVibratorOff(eq(UID));
- verify(mControllerCallbacks).onComplete(eq(VIBRATOR_ID), eq(vibrationId));
- verify(mControllerCallbacks, never()).onComplete(eq(2), eq(vibrationId));
- verifyCallbacksTriggered(vibrationId, Status.FINISHED);
+ verify(mControllerCallbacks).onComplete(eq(VIBRATOR_ID), eq(vibration.id));
+ verify(mControllerCallbacks, never()).onComplete(eq(2), eq(vibration.id));
+ verifyCallbacksTriggered(vibration, Status.FINISHED);
assertFalse(mControllers.get(VIBRATOR_ID).isVibrating());
assertEquals(Arrays.asList(expectedPrebaked(VibrationEffect.EFFECT_TICK)),
- mVibratorProviders.get(VIBRATOR_ID).getEffectSegments(vibrationId));
+ mVibratorProviders.get(VIBRATOR_ID).getEffectSegments(vibration.id));
}
@Test
@@ -1007,26 +1005,26 @@
CombinedVibration effect = CombinedVibration.createParallel(
VibrationEffect.get(VibrationEffect.EFFECT_CLICK));
- long vibrationId = startThreadAndDispatcher(effect);
+ HalVibration vibration = startThreadAndDispatcher(effect);
waitForCompletion();
verify(mManagerHooks).noteVibratorOn(eq(UID), eq(20L));
verify(mManagerHooks).noteVibratorOff(eq(UID));
- verify(mControllerCallbacks).onComplete(eq(1), eq(vibrationId));
- verify(mControllerCallbacks).onComplete(eq(2), eq(vibrationId));
- verify(mControllerCallbacks).onComplete(eq(3), eq(vibrationId));
- verifyCallbacksTriggered(vibrationId, Status.FINISHED);
+ verify(mControllerCallbacks).onComplete(eq(1), eq(vibration.id));
+ verify(mControllerCallbacks).onComplete(eq(2), eq(vibration.id));
+ verify(mControllerCallbacks).onComplete(eq(3), eq(vibration.id));
+ verifyCallbacksTriggered(vibration, Status.FINISHED);
assertFalse(mControllers.get(1).isVibrating());
assertFalse(mControllers.get(2).isVibrating());
assertFalse(mControllers.get(3).isVibrating());
VibrationEffectSegment expected = expectedPrebaked(VibrationEffect.EFFECT_CLICK);
assertEquals(Arrays.asList(expected),
- mVibratorProviders.get(1).getEffectSegments(vibrationId));
+ mVibratorProviders.get(1).getEffectSegments(vibration.id));
assertEquals(Arrays.asList(expected),
- mVibratorProviders.get(2).getEffectSegments(vibrationId));
+ mVibratorProviders.get(2).getEffectSegments(vibration.id));
assertEquals(Arrays.asList(expected),
- mVibratorProviders.get(3).getEffectSegments(vibrationId));
+ mVibratorProviders.get(3).getEffectSegments(vibration.id));
}
@Test
@@ -1049,32 +1047,32 @@
new long[]{10, 10}, new int[]{1, 2}, -1))
.addVibrator(4, composed)
.combine();
- long vibrationId = startThreadAndDispatcher(effect);
+ HalVibration vibration = startThreadAndDispatcher(effect);
waitForCompletion();
verify(mManagerHooks).noteVibratorOn(eq(UID), eq(20L));
verify(mManagerHooks).noteVibratorOff(eq(UID));
- verify(mControllerCallbacks).onComplete(eq(1), eq(vibrationId));
- verify(mControllerCallbacks).onComplete(eq(2), eq(vibrationId));
- verify(mControllerCallbacks).onComplete(eq(3), eq(vibrationId));
- verify(mControllerCallbacks).onComplete(eq(4), eq(vibrationId));
- verifyCallbacksTriggered(vibrationId, Status.FINISHED);
+ verify(mControllerCallbacks).onComplete(eq(1), eq(vibration.id));
+ verify(mControllerCallbacks).onComplete(eq(2), eq(vibration.id));
+ verify(mControllerCallbacks).onComplete(eq(3), eq(vibration.id));
+ verify(mControllerCallbacks).onComplete(eq(4), eq(vibration.id));
+ verifyCallbacksTriggered(vibration, Status.FINISHED);
assertFalse(mControllers.get(1).isVibrating());
assertFalse(mControllers.get(2).isVibrating());
assertFalse(mControllers.get(3).isVibrating());
assertFalse(mControllers.get(4).isVibrating());
assertEquals(Arrays.asList(expectedPrebaked(VibrationEffect.EFFECT_CLICK)),
- mVibratorProviders.get(1).getEffectSegments(vibrationId));
+ mVibratorProviders.get(1).getEffectSegments(vibration.id));
assertEquals(Arrays.asList(expectedOneShot(10)),
- mVibratorProviders.get(2).getEffectSegments(vibrationId));
+ mVibratorProviders.get(2).getEffectSegments(vibration.id));
assertEquals(expectedAmplitudes(100), mVibratorProviders.get(2).getAmplitudes());
assertEquals(Arrays.asList(expectedOneShot(20)),
- mVibratorProviders.get(3).getEffectSegments(vibrationId));
+ mVibratorProviders.get(3).getEffectSegments(vibration.id));
assertEquals(expectedAmplitudes(1, 2), mVibratorProviders.get(3).getAmplitudes());
assertEquals(Arrays.asList(
expectedPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK, 1, 0)),
- mVibratorProviders.get(4).getEffectSegments(vibrationId));
+ mVibratorProviders.get(4).getEffectSegments(vibration.id));
}
@Test
@@ -1094,13 +1092,13 @@
.addNext(1, VibrationEffect.createOneShot(10, 100), /* delay= */ 50)
.addNext(2, composed, /* delay= */ 50)
.combine();
- long vibrationId = startThreadAndDispatcher(effect);
+ HalVibration vibration = startThreadAndDispatcher(effect);
waitForCompletion();
InOrder controllerVerifier = inOrder(mControllerCallbacks);
- controllerVerifier.verify(mControllerCallbacks).onComplete(eq(3), eq(vibrationId));
- controllerVerifier.verify(mControllerCallbacks).onComplete(eq(1), eq(vibrationId));
- controllerVerifier.verify(mControllerCallbacks).onComplete(eq(2), eq(vibrationId));
+ controllerVerifier.verify(mControllerCallbacks).onComplete(eq(3), eq(vibration.id));
+ controllerVerifier.verify(mControllerCallbacks).onComplete(eq(1), eq(vibration.id));
+ controllerVerifier.verify(mControllerCallbacks).onComplete(eq(2), eq(vibration.id));
InOrder batteryVerifier = inOrder(mManagerHooks);
batteryVerifier.verify(mManagerHooks).noteVibratorOn(eq(UID), eq(20L));
@@ -1110,19 +1108,19 @@
batteryVerifier.verify(mManagerHooks).noteVibratorOn(eq(UID), eq(20L));
batteryVerifier.verify(mManagerHooks).noteVibratorOff(eq(UID));
- verifyCallbacksTriggered(vibrationId, Status.FINISHED);
+ verifyCallbacksTriggered(vibration, Status.FINISHED);
assertFalse(mControllers.get(1).isVibrating());
assertFalse(mControllers.get(2).isVibrating());
assertFalse(mControllers.get(3).isVibrating());
assertEquals(Arrays.asList(expectedOneShot(10)),
- mVibratorProviders.get(1).getEffectSegments(vibrationId));
+ mVibratorProviders.get(1).getEffectSegments(vibration.id));
assertEquals(expectedAmplitudes(100), mVibratorProviders.get(1).getAmplitudes());
assertEquals(Arrays.asList(
expectedPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK, 1, 0)),
- mVibratorProviders.get(2).getEffectSegments(vibrationId));
+ mVibratorProviders.get(2).getEffectSegments(vibration.id));
assertEquals(Arrays.asList(expectedPrebaked(VibrationEffect.EFFECT_CLICK)),
- mVibratorProviders.get(3).getEffectSegments(vibrationId));
+ mVibratorProviders.get(3).getEffectSegments(vibration.id));
}
@Test
@@ -1143,30 +1141,29 @@
CombinedVibration effect = CombinedVibration.createParallel(composed);
// We create the HalVibration here to obtain the vibration id and use it to mock the
// required response when calling triggerSyncedVibration.
- HalVibration halVibration = createVibration(effect);
- long vibrationId = halVibration.id;
- when(mManagerHooks.triggerSyncedVibration(eq(vibrationId))).thenReturn(true);
- startThreadAndDispatcher(halVibration);
+ HalVibration vibration = createVibration(effect);
+ when(mManagerHooks.triggerSyncedVibration(eq(vibration.id))).thenReturn(true);
+ startThreadAndDispatcher(vibration);
assertTrue(waitUntil(
- () -> !mVibratorProviders.get(1).getEffectSegments(vibrationId).isEmpty()
- && !mVibratorProviders.get(2).getEffectSegments(vibrationId).isEmpty(),
+ () -> !mVibratorProviders.get(1).getEffectSegments(vibration.id).isEmpty()
+ && !mVibratorProviders.get(2).getEffectSegments(vibration.id).isEmpty(),
TEST_TIMEOUT_MILLIS));
mVibrationConductor.notifySyncedVibrationComplete();
waitForCompletion();
long expectedCap = IVibratorManager.CAP_SYNC | IVibratorManager.CAP_PREPARE_COMPOSE;
verify(mManagerHooks).prepareSyncedVibration(eq(expectedCap), eq(vibratorIds));
- verify(mManagerHooks).triggerSyncedVibration(eq(vibrationId));
+ verify(mManagerHooks).triggerSyncedVibration(eq(vibration.id));
verify(mManagerHooks, never()).cancelSyncedVibration();
- verifyCallbacksTriggered(vibrationId, Status.FINISHED);
+ verifyCallbacksTriggered(vibration, Status.FINISHED);
VibrationEffectSegment expected = expectedPrimitive(
VibrationEffect.Composition.PRIMITIVE_CLICK, 1, 100);
assertEquals(Arrays.asList(expected),
- mVibratorProviders.get(1).getEffectSegments(vibrationId));
+ mVibratorProviders.get(1).getEffectSegments(vibration.id));
assertEquals(Arrays.asList(expected),
- mVibratorProviders.get(2).getEffectSegments(vibrationId));
+ mVibratorProviders.get(2).getEffectSegments(vibration.id));
}
@Test
@@ -1190,10 +1187,9 @@
.combine();
// We create the HalVibration here to obtain the vibration id and use it to mock the
// required response when calling triggerSyncedVibration.
- HalVibration halVibration = createVibration(effect);
- long vibrationId = halVibration.id;
- when(mManagerHooks.triggerSyncedVibration(eq(vibrationId))).thenReturn(true);
- startThreadAndDispatcher(halVibration);
+ HalVibration vibration = createVibration(effect);
+ when(mManagerHooks.triggerSyncedVibration(eq(vibration.id))).thenReturn(true);
+ startThreadAndDispatcher(vibration);
waitForCompletion();
long expectedCap = IVibratorManager.CAP_SYNC
@@ -1204,9 +1200,9 @@
| IVibratorManager.CAP_MIXED_TRIGGER_PERFORM
| IVibratorManager.CAP_MIXED_TRIGGER_COMPOSE;
verify(mManagerHooks).prepareSyncedVibration(eq(expectedCap), eq(vibratorIds));
- verify(mManagerHooks).triggerSyncedVibration(eq(vibrationId));
+ verify(mManagerHooks).triggerSyncedVibration(eq(vibration.id));
verify(mManagerHooks, never()).cancelSyncedVibration();
- verifyCallbacksTriggered(vibrationId, Status.FINISHED);
+ verifyCallbacksTriggered(vibration, Status.FINISHED);
}
@Test
@@ -1221,19 +1217,19 @@
.addVibrator(1, VibrationEffect.createOneShot(10, 100))
.addVibrator(2, VibrationEffect.createWaveform(new long[]{5}, new int[]{200}, -1))
.combine();
- long vibrationId = startThreadAndDispatcher(effect);
+ HalVibration vibration = startThreadAndDispatcher(effect);
waitForCompletion();
long expectedCap = IVibratorManager.CAP_SYNC | IVibratorManager.CAP_PREPARE_ON;
verify(mManagerHooks).prepareSyncedVibration(eq(expectedCap), eq(vibratorIds));
- verify(mManagerHooks, never()).triggerSyncedVibration(eq(vibrationId));
+ verify(mManagerHooks, never()).triggerSyncedVibration(eq(vibration.id));
verify(mManagerHooks, never()).cancelSyncedVibration();
assertEquals(Arrays.asList(expectedOneShot(10)),
- mVibratorProviders.get(1).getEffectSegments(vibrationId));
+ mVibratorProviders.get(1).getEffectSegments(vibration.id));
assertEquals(expectedAmplitudes(100), mVibratorProviders.get(1).getAmplitudes());
assertEquals(Arrays.asList(expectedOneShot(5)),
- mVibratorProviders.get(2).getEffectSegments(vibrationId));
+ mVibratorProviders.get(2).getEffectSegments(vibration.id));
assertEquals(expectedAmplitudes(200), mVibratorProviders.get(2).getAmplitudes());
}
@@ -1250,10 +1246,9 @@
.combine();
// We create the HalVibration here to obtain the vibration id and use it to mock the
// required response when calling triggerSyncedVibration.
- HalVibration halVibration = createVibration(effect);
- long vibrationId = halVibration.id;
- when(mManagerHooks.triggerSyncedVibration(eq(vibrationId))).thenReturn(false);
- startThreadAndDispatcher(halVibration);
+ HalVibration vibration = createVibration(effect);
+ when(mManagerHooks.triggerSyncedVibration(eq(vibration.id))).thenReturn(false);
+ startThreadAndDispatcher(vibration);
waitForCompletion();
long expectedCap = IVibratorManager.CAP_SYNC
@@ -1262,7 +1257,7 @@
| IVibratorManager.CAP_MIXED_TRIGGER_ON
| IVibratorManager.CAP_MIXED_TRIGGER_PERFORM;
verify(mManagerHooks).prepareSyncedVibration(eq(expectedCap), eq(vibratorIds));
- verify(mManagerHooks).triggerSyncedVibration(eq(vibrationId));
+ verify(mManagerHooks).triggerSyncedVibration(eq(vibration.id));
verify(mManagerHooks).cancelSyncedVibration();
assertTrue(mVibratorProviders.get(1).getAmplitudes().isEmpty());
}
@@ -1282,7 +1277,7 @@
.addVibrator(3, VibrationEffect.createWaveform(
new long[]{60}, new int[]{6}, -1))
.combine();
- long vibrationId = startThreadAndDispatcher(effect);
+ HalVibration vibration = startThreadAndDispatcher(effect);
// All vibrators are turned on in parallel.
assertTrue(waitUntil(
@@ -1295,20 +1290,20 @@
verify(mManagerHooks).noteVibratorOn(eq(UID), eq(80L));
verify(mManagerHooks).noteVibratorOff(eq(UID));
- verify(mControllerCallbacks).onComplete(eq(1), eq(vibrationId));
- verify(mControllerCallbacks).onComplete(eq(2), eq(vibrationId));
- verify(mControllerCallbacks).onComplete(eq(3), eq(vibrationId));
- verifyCallbacksTriggered(vibrationId, Status.FINISHED);
+ verify(mControllerCallbacks).onComplete(eq(1), eq(vibration.id));
+ verify(mControllerCallbacks).onComplete(eq(2), eq(vibration.id));
+ verify(mControllerCallbacks).onComplete(eq(3), eq(vibration.id));
+ verifyCallbacksTriggered(vibration, Status.FINISHED);
assertFalse(mControllers.get(1).isVibrating());
assertFalse(mControllers.get(2).isVibrating());
assertFalse(mControllers.get(3).isVibrating());
assertEquals(Arrays.asList(expectedOneShot(25)),
- mVibratorProviders.get(1).getEffectSegments(vibrationId));
+ mVibratorProviders.get(1).getEffectSegments(vibration.id));
assertEquals(Arrays.asList(expectedOneShot(80)),
- mVibratorProviders.get(2).getEffectSegments(vibrationId));
+ mVibratorProviders.get(2).getEffectSegments(vibration.id));
assertEquals(Arrays.asList(expectedOneShot(60)),
- mVibratorProviders.get(3).getEffectSegments(vibrationId));
+ mVibratorProviders.get(3).getEffectSegments(vibration.id));
assertEquals(expectedAmplitudes(1, 2, 3), mVibratorProviders.get(1).getAmplitudes());
assertEquals(expectedAmplitudes(4, 5), mVibratorProviders.get(2).getAmplitudes());
assertEquals(expectedAmplitudes(6), mVibratorProviders.get(3).getAmplitudes());
@@ -1327,17 +1322,11 @@
CombinedVibration.createParallel(
VibrationEffect.createOneShot(
expectedDuration, VibrationEffect.DEFAULT_AMPLITUDE)));
- CountDownLatch vibrationCompleteLatch = new CountDownLatch(1);
- doAnswer(unused -> {
- vibrationCompleteLatch.countDown();
- return null;
- }).when(mManagerHooks).onVibrationCompleted(eq(vibration.id), any());
startThreadAndDispatcher(vibration);
long startTime = SystemClock.elapsedRealtime();
- assertTrue(vibrationCompleteLatch.await(expectedDuration + TEST_TIMEOUT_MILLIS,
- TimeUnit.MILLISECONDS));
+ vibration.waitForEnd();
long vibrationEndTime = SystemClock.elapsedRealtime();
waitForCompletion(rampDownDuration + TEST_TIMEOUT_MILLIS);
@@ -1363,17 +1352,11 @@
CombinedVibration.createParallel(
VibrationEffect.createOneShot(
expectedDuration, VibrationEffect.DEFAULT_AMPLITUDE)));
- CountDownLatch vibrationCompleteLatch = new CountDownLatch(1);
- doAnswer(unused -> {
- vibrationCompleteLatch.countDown();
- return null;
- }).when(mManagerHooks).onVibrationCompleted(eq(vibration.id), any());
startThreadAndDispatcher(vibration);
long startTime = SystemClock.elapsedRealtime();
- assertTrue(vibrationCompleteLatch.await(callbackDelay + TEST_TIMEOUT_MILLIS,
- TimeUnit.MILLISECONDS));
+ vibration.waitForEnd();
long vibrationEndTime = SystemClock.elapsedRealtime();
waitForCompletion(TEST_TIMEOUT_MILLIS);
@@ -1397,17 +1380,11 @@
CombinedVibration.createParallel(
VibrationEffect.createOneShot(
expectedDuration, VibrationEffect.DEFAULT_AMPLITUDE)));
- CountDownLatch vibrationCompleteLatch = new CountDownLatch(1);
- doAnswer(unused -> {
- vibrationCompleteLatch.countDown();
- return null;
- }).when(mManagerHooks).onVibrationCompleted(eq(vibration.id), any());
startThreadAndDispatcher(vibration);
long startTime = SystemClock.elapsedRealtime();
- assertTrue(vibrationCompleteLatch.await(callbackTimeout + TEST_TIMEOUT_MILLIS,
- TimeUnit.MILLISECONDS));
+ vibration.waitForEnd();
long vibrationEndTime = SystemClock.elapsedRealtime();
waitForCompletion(callbackDelay + TEST_TIMEOUT_MILLIS);
@@ -1461,11 +1438,11 @@
fakeVibrator.setOnLatency(latency);
VibrationEffect effect = VibrationEffect.get(VibrationEffect.EFFECT_CLICK);
- long vibrationId = startThreadAndDispatcher(effect);
+ HalVibration vibration = startThreadAndDispatcher(effect);
- assertTrue(waitUntil(() -> !fakeVibrator.getEffectSegments(vibrationId).isEmpty(),
+ assertTrue(waitUntil(() -> !fakeVibrator.getEffectSegments(vibration.id).isEmpty(),
TEST_TIMEOUT_MILLIS));
- assertTrue(mThread.isRunningVibrationId(vibrationId));
+ assertTrue(mThread.isRunningVibrationId(vibration.id));
// Run cancel in a separate thread so if VibrationThread.cancel blocks then this test should
// fail at waitForCompletion(cancellingThread).
@@ -1480,7 +1457,7 @@
// After the vibrator call ends the vibration is cancelled and the vibrator is turned off.
waitForCompletion(/* timeout= */ latency + TEST_TIMEOUT_MILLIS);
- verifyCallbacksTriggered(vibrationId, Status.CANCELLED_BY_USER);
+ verifyCallbacksTriggered(vibration, Status.CANCELLED_BY_USER);
assertFalse(mControllers.get(VIBRATOR_ID).isVibrating());
}
@@ -1500,10 +1477,10 @@
.addPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK, 1f, 100)
.compose())
.combine();
- long vibrationId = startThreadAndDispatcher(effect);
+ HalVibration vibration = startThreadAndDispatcher(effect);
assertTrue(waitUntil(() -> mControllers.get(2).isVibrating(), TEST_TIMEOUT_MILLIS));
- assertTrue(mThread.isRunningVibrationId(vibrationId));
+ assertTrue(mThread.isRunningVibrationId(vibration.id));
// Run cancel in a separate thread so if VibrationThread.cancel blocks then this test should
// fail at waitForCompletion(vibrationThread) if the vibration not cancelled immediately.
@@ -1516,7 +1493,7 @@
waitForCompletion(/* timeout= */ 50);
cancellingThread.join();
- verifyCallbacksTriggered(vibrationId, Status.CANCELLED_BY_SCREEN_OFF);
+ verifyCallbacksTriggered(vibration, Status.CANCELLED_BY_SCREEN_OFF);
assertFalse(mControllers.get(1).isVibrating());
assertFalse(mControllers.get(2).isVibrating());
}
@@ -1534,10 +1511,10 @@
.addVibrator(1, VibrationEffect.createVendorEffect(createTestVendorData()))
.addVibrator(2, VibrationEffect.createVendorEffect(createTestVendorData()))
.combine();
- long vibrationId = startThreadAndDispatcher(effect);
+ HalVibration vibration = startThreadAndDispatcher(effect);
assertTrue(waitUntil(() -> mControllers.get(2).isVibrating(), TEST_TIMEOUT_MILLIS));
- assertTrue(mThread.isRunningVibrationId(vibrationId));
+ assertTrue(mThread.isRunningVibrationId(vibration.id));
// Run cancel in a separate thread so if VibrationThread.cancel blocks then this test should
// fail at waitForCompletion(vibrationThread) if the vibration not cancelled immediately.
@@ -1550,7 +1527,7 @@
waitForCompletion(/* timeout= */ 50);
cancellingThread.join();
- verifyCallbacksTriggered(vibrationId, Status.CANCELLED_BY_SCREEN_OFF);
+ verifyCallbacksTriggered(vibration, Status.CANCELLED_BY_SCREEN_OFF);
assertFalse(mControllers.get(1).isVibrating());
assertFalse(mControllers.get(2).isVibrating());
}
@@ -1566,12 +1543,12 @@
new long[]{100, 100}, new int[]{1, 2}, 0))
.addVibrator(2, VibrationEffect.createOneShot(100, 100))
.combine();
- long vibrationId = startThreadAndDispatcher(effect);
+ HalVibration vibration = startThreadAndDispatcher(effect);
assertTrue(waitUntil(() -> mControllers.get(1).isVibrating()
&& mControllers.get(2).isVibrating(),
TEST_TIMEOUT_MILLIS));
- assertTrue(mThread.isRunningVibrationId(vibrationId));
+ assertTrue(mThread.isRunningVibrationId(vibration.id));
// Run cancel in a separate thread so if VibrationThread.cancel blocks then this test should
// fail at waitForCompletion(vibrationThread) if the vibration not cancelled immediately.
@@ -1584,7 +1561,7 @@
waitForCompletion(/* timeout= */ 50);
cancellingThread.join();
- verifyCallbacksTriggered(vibrationId, Status.CANCELLED_BY_SCREEN_OFF);
+ verifyCallbacksTriggered(vibration, Status.CANCELLED_BY_SCREEN_OFF);
assertFalse(mControllers.get(1).isVibrating());
assertFalse(mControllers.get(2).isVibrating());
}
@@ -1592,19 +1569,17 @@
@Test
public void vibrate_binderDied_cancelsVibration() throws Exception {
VibrationEffect effect = VibrationEffect.createWaveform(new long[]{5}, new int[]{100}, 0);
- long vibrationId = startThreadAndDispatcher(effect);
+ HalVibration vibration = startThreadAndDispatcher(effect);
assertTrue(waitUntil(() -> mControllers.get(VIBRATOR_ID).isVibrating(),
TEST_TIMEOUT_MILLIS));
- assertTrue(mThread.isRunningVibrationId(vibrationId));
+ assertTrue(mThread.isRunningVibrationId(vibration.id));
mVibrationConductor.binderDied();
waitForCompletion();
- verify(mVibrationToken).linkToDeath(same(mVibrationConductor), eq(0));
- verify(mVibrationToken).unlinkToDeath(same(mVibrationConductor), eq(0));
- verifyCallbacksTriggered(vibrationId, Status.CANCELLED_BINDER_DIED);
- assertFalse(mVibratorProviders.get(VIBRATOR_ID).getEffectSegments(vibrationId).isEmpty());
+ verifyCallbacksTriggered(vibration, Status.CANCELLED_BINDER_DIED);
+ assertFalse(mVibratorProviders.get(VIBRATOR_ID).getEffectSegments(vibration.id).isEmpty());
assertFalse(mControllers.get(VIBRATOR_ID).isVibrating());
}
@@ -1615,15 +1590,15 @@
VibrationEffect effect = VibrationEffect.createWaveform(
new long[]{5, 5, 5}, new int[]{60, 120, 240}, -1);
- long vibrationId = startThreadAndDispatcher(effect);
+ HalVibration vibration = startThreadAndDispatcher(effect);
waitForCompletion();
- verify(mControllerCallbacks).onComplete(eq(VIBRATOR_ID), eq(vibrationId));
- verifyCallbacksTriggered(vibrationId, Status.FINISHED);
+ verify(mControllerCallbacks).onComplete(eq(VIBRATOR_ID), eq(vibration.id));
+ verifyCallbacksTriggered(vibration, Status.FINISHED);
// Duration extended for 5 + 5 + 5 + 15.
assertEquals(Arrays.asList(expectedOneShot(30)),
- mVibratorProviders.get(VIBRATOR_ID).getEffectSegments(vibrationId));
+ mVibratorProviders.get(VIBRATOR_ID).getEffectSegments(vibration.id));
List<Float> amplitudes = mVibratorProviders.get(VIBRATOR_ID).getAmplitudes();
assertTrue(amplitudes.size() > 3);
assertEquals(expectedAmplitudes(60, 120, 240), amplitudes.subList(0, 3));
@@ -1633,24 +1608,24 @@
}
@Test
- public void vibrate_waveformWithRampDown_triggersCallbackWhenOriginalVibrationEnds() {
+ public void vibrate_waveformWithRampDown_triggersCallbackWhenOriginalVibrationEnds()
+ throws Exception {
when(mVibrationConfigMock.getRampDownDurationMs()).thenReturn(10_000);
mVibratorProviders.get(VIBRATOR_ID).setCapabilities(IVibrator.CAP_AMPLITUDE_CONTROL);
VibrationEffect effect = VibrationEffect.createOneShot(10, 200);
- long vibrationId = startThreadAndDispatcher(effect);
+ HalVibration vibration = startThreadAndDispatcher(effect);
// Vibration completed but vibrator not yet released.
- verify(mManagerHooks, timeout(TEST_TIMEOUT_MILLIS)).onVibrationCompleted(eq(vibrationId),
- eq(new Vibration.EndInfo(Status.FINISHED)));
+ vibration.waitForEnd();
verify(mManagerHooks, never()).onVibrationThreadReleased(anyLong());
// Thread still running ramp down.
- assertTrue(mThread.isRunningVibrationId(vibrationId));
+ assertTrue(mThread.isRunningVibrationId(vibration.id));
// Duration extended for 10 + 10000.
assertEquals(Arrays.asList(expectedOneShot(10_010)),
- mVibratorProviders.get(VIBRATOR_ID).getEffectSegments(vibrationId));
+ mVibratorProviders.get(VIBRATOR_ID).getEffectSegments(vibration.id));
// Will stop the ramp down right away.
mVibrationConductor.notifyCancelled(
@@ -1658,9 +1633,8 @@
waitForCompletion();
// Does not cancel already finished vibration, but releases vibrator.
- verify(mManagerHooks, never()).onVibrationCompleted(eq(vibrationId),
- eq(new Vibration.EndInfo(Status.CANCELLED_BY_SETTINGS_UPDATE)));
- verify(mManagerHooks).onVibrationThreadReleased(vibrationId);
+ assertThat(vibration.getStatus()).isNotEqualTo(Status.CANCELLED_BY_SETTINGS_UPDATE);
+ verify(mManagerHooks).onVibrationThreadReleased(vibration.id);
}
@Test
@@ -1670,18 +1644,18 @@
mVibratorProviders.get(VIBRATOR_ID).setCapabilities(IVibrator.CAP_AMPLITUDE_CONTROL);
VibrationEffect effect = VibrationEffect.createOneShot(10_000, 240);
- long vibrationId = startThreadAndDispatcher(effect);
+ HalVibration vibration = startThreadAndDispatcher(effect);
assertTrue(waitUntil(() -> mControllers.get(VIBRATOR_ID).isVibrating(),
TEST_TIMEOUT_MILLIS));
mVibrationConductor.notifyCancelled(
new Vibration.EndInfo(Status.CANCELLED_BY_USER), /* immediate= */ false);
waitForCompletion();
- verifyCallbacksTriggered(vibrationId, Status.CANCELLED_BY_USER);
+ verifyCallbacksTriggered(vibration, Status.CANCELLED_BY_USER);
// Duration extended for 10000 + 15.
assertEquals(Arrays.asList(expectedOneShot(10_015)),
- mVibratorProviders.get(VIBRATOR_ID).getEffectSegments(vibrationId));
+ mVibratorProviders.get(VIBRATOR_ID).getEffectSegments(vibration.id));
List<Float> amplitudes = mVibratorProviders.get(VIBRATOR_ID).getAmplitudes();
assertTrue(amplitudes.size() > 1);
for (int i = 1; i < amplitudes.size(); i++) {
@@ -1696,14 +1670,14 @@
mVibratorProviders.get(VIBRATOR_ID).setSupportedEffects(VibrationEffect.EFFECT_CLICK);
VibrationEffect effect = VibrationEffect.get(VibrationEffect.EFFECT_CLICK);
- long vibrationId = startThreadAndDispatcher(effect);
+ HalVibration vibration = startThreadAndDispatcher(effect);
waitForCompletion();
- verify(mControllerCallbacks).onComplete(eq(VIBRATOR_ID), eq(vibrationId));
- verifyCallbacksTriggered(vibrationId, Status.FINISHED);
+ verify(mControllerCallbacks).onComplete(eq(VIBRATOR_ID), eq(vibration.id));
+ verifyCallbacksTriggered(vibration, Status.FINISHED);
assertEquals(Arrays.asList(expectedPrebaked(VibrationEffect.EFFECT_CLICK)),
- mVibratorProviders.get(VIBRATOR_ID).getEffectSegments(vibrationId));
+ mVibratorProviders.get(VIBRATOR_ID).getEffectSegments(vibration.id));
assertTrue(mVibratorProviders.get(VIBRATOR_ID).getAmplitudes().isEmpty());
}
@@ -1714,13 +1688,13 @@
mVibratorProviders.get(VIBRATOR_ID).setCapabilities(IVibrator.CAP_PERFORM_VENDOR_EFFECTS);
VibrationEffect effect = VibrationEffect.createVendorEffect(createTestVendorData());
- long vibrationId = startThreadAndDispatcher(effect);
+ HalVibration vibration = startThreadAndDispatcher(effect);
waitForCompletion();
- verify(mControllerCallbacks).onComplete(eq(VIBRATOR_ID), eq(vibrationId));
- verifyCallbacksTriggered(vibrationId, Status.FINISHED);
+ verify(mControllerCallbacks).onComplete(eq(VIBRATOR_ID), eq(vibration.id));
+ verifyCallbacksTriggered(vibration, Status.FINISHED);
- assertThat(mVibratorProviders.get(VIBRATOR_ID).getVendorEffects(vibrationId))
+ assertThat(mVibratorProviders.get(VIBRATOR_ID).getVendorEffects(vibration.id))
.containsExactly(effect)
.inOrder();
assertThat(mVibratorProviders.get(VIBRATOR_ID).getAmplitudes()).isEmpty();
@@ -1737,15 +1711,15 @@
VibrationEffect effect = VibrationEffect.startComposition()
.addPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK)
.compose();
- long vibrationId = startThreadAndDispatcher(effect);
+ HalVibration vibration = startThreadAndDispatcher(effect);
waitForCompletion();
- verify(mControllerCallbacks).onComplete(eq(VIBRATOR_ID), eq(vibrationId));
- verifyCallbacksTriggered(vibrationId, Status.FINISHED);
+ verify(mControllerCallbacks).onComplete(eq(VIBRATOR_ID), eq(vibration.id));
+ verifyCallbacksTriggered(vibration, Status.FINISHED);
assertEquals(
Arrays.asList(expectedPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK, 1, 0)),
- mVibratorProviders.get(VIBRATOR_ID).getEffectSegments(vibrationId));
+ mVibratorProviders.get(VIBRATOR_ID).getEffectSegments(vibration.id));
assertTrue(mVibratorProviders.get(VIBRATOR_ID).getAmplitudes().isEmpty());
}
@@ -1764,14 +1738,14 @@
VibrationEffect effect = VibrationEffect.startWaveform()
.addTransition(Duration.ofMillis(1), targetAmplitude(1))
.build();
- long vibrationId = startThreadAndDispatcher(effect);
+ HalVibration vibration = startThreadAndDispatcher(effect);
waitForCompletion();
- verify(mControllerCallbacks).onComplete(eq(VIBRATOR_ID), eq(vibrationId));
- verifyCallbacksTriggered(vibrationId, Status.FINISHED);
+ verify(mControllerCallbacks).onComplete(eq(VIBRATOR_ID), eq(vibration.id));
+ verifyCallbacksTriggered(vibration, Status.FINISHED);
assertEquals(Arrays.asList(expectedRamp(0, 1, 150, 150, 1)),
- fakeVibrator.getEffectSegments(vibrationId));
+ fakeVibrator.getEffectSegments(vibration.id));
assertTrue(fakeVibrator.getAmplitudes().isEmpty());
}
@@ -1796,69 +1770,68 @@
VibrationEffect effect4 = VibrationEffect.createOneShot(8000, 100);
VibrationEffect effect5 = VibrationEffect.get(VibrationEffect.EFFECT_CLICK);
- long vibrationId1 = startThreadAndDispatcher(effect1);
+ HalVibration vibration1 = startThreadAndDispatcher(effect1);
waitForCompletion();
- verify(mControllerCallbacks).onComplete(VIBRATOR_ID, vibrationId1);
- verifyCallbacksTriggered(vibrationId1, Status.FINISHED);
- long vibrationId2 = startThreadAndDispatcher(effect2);
+ HalVibration vibration2 = startThreadAndDispatcher(effect2);
// Effect2 won't complete on its own. Cancel it after a couple of repeats.
Thread.sleep(150); // More than two TICKs.
mVibrationConductor.notifyCancelled(
new Vibration.EndInfo(Status.CANCELLED_BY_USER), /* immediate= */ false);
waitForCompletion();
- long vibrationId3 = startThreadAndDispatcher(effect3);
+ HalVibration vibration3 = startThreadAndDispatcher(effect3);
waitForCompletion();
// Effect4 is a long oneshot, but it gets cancelled as fast as possible.
long start4 = System.currentTimeMillis();
- long vibrationId4 = startThreadAndDispatcher(effect4);
+ HalVibration vibration4 = startThreadAndDispatcher(effect4);
mVibrationConductor.notifyCancelled(
new Vibration.EndInfo(Status.CANCELLED_BY_SCREEN_OFF), /* immediate= */ true);
waitForCompletion();
long duration4 = System.currentTimeMillis() - start4;
// Effect5 is to show that things keep going after the immediate cancel.
- long vibrationId5 = startThreadAndDispatcher(effect5);
+ HalVibration vibration5 = startThreadAndDispatcher(effect5);
waitForCompletion();
FakeVibratorControllerProvider fakeVibrator = mVibratorProviders.get(VIBRATOR_ID);
assertFalse(mControllers.get(VIBRATOR_ID).isVibrating());
// Effect1
- verify(mControllerCallbacks).onComplete(VIBRATOR_ID, vibrationId1);
- verifyCallbacksTriggered(vibrationId1, Status.FINISHED);
+ verify(mControllerCallbacks).onComplete(VIBRATOR_ID, vibration1.id);
+ verifyCallbacksTriggered(vibration1, Status.FINISHED);
assertEquals(Arrays.asList(expectedPrebaked(VibrationEffect.EFFECT_CLICK)),
- fakeVibrator.getEffectSegments(vibrationId1));
+ fakeVibrator.getEffectSegments(vibration1.id));
// Effect2: repeating, cancelled.
- verify(mControllerCallbacks, atLeast(2)).onComplete(VIBRATOR_ID, vibrationId2);
- verifyCallbacksTriggered(vibrationId2, Status.CANCELLED_BY_USER);
+ verify(mControllerCallbacks, atLeast(2)).onComplete(VIBRATOR_ID, vibration2.id);
+ verifyCallbacksTriggered(vibration2, Status.CANCELLED_BY_USER);
// The exact count of segments might vary, so just check that there's more than 2 and
// all elements are the same segment.
- List<VibrationEffectSegment> actualSegments2 = fakeVibrator.getEffectSegments(vibrationId2);
+ List<VibrationEffectSegment> actualSegments2 =
+ fakeVibrator.getEffectSegments(vibration2.id);
assertTrue(actualSegments2.size() + " > 2", actualSegments2.size() > 2);
for (VibrationEffectSegment segment : actualSegments2) {
assertEquals(expectedPrebaked(VibrationEffect.EFFECT_TICK), segment);
}
// Effect3
- verify(mControllerCallbacks).onComplete(eq(VIBRATOR_ID), eq(vibrationId3));
- verifyCallbacksTriggered(vibrationId3, Status.FINISHED);
+ verify(mControllerCallbacks).onComplete(eq(VIBRATOR_ID), eq(vibration3.id));
+ verifyCallbacksTriggered(vibration3, Status.FINISHED);
assertEquals(Arrays.asList(
expectedPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK, 1, 0)),
- fakeVibrator.getEffectSegments(vibrationId3));
+ fakeVibrator.getEffectSegments(vibration3.id));
// Effect4: cancelled quickly.
- verifyCallbacksTriggered(vibrationId4, Status.CANCELLED_BY_SCREEN_OFF);
+ verifyCallbacksTriggered(vibration4, Status.CANCELLED_BY_SCREEN_OFF);
assertTrue("Tested duration=" + duration4, duration4 < 2000);
// Effect5: played normally after effect4, which may or may not have played.
assertEquals(Arrays.asList(expectedPrebaked(VibrationEffect.EFFECT_CLICK)),
- fakeVibrator.getEffectSegments(vibrationId5));
+ fakeVibrator.getEffectSegments(vibration5.id));
}
private void mockVibrators(int... vibratorIds) {
@@ -1875,19 +1848,19 @@
mVibrationSettings.mSettingObserver.onChange(false);
}
- private long startThreadAndDispatcher(VibrationEffect effect) {
+ private HalVibration startThreadAndDispatcher(VibrationEffect effect) {
return startThreadAndDispatcher(CombinedVibration.createParallel(effect));
}
- private long startThreadAndDispatcher(CombinedVibration effect) {
+ private HalVibration startThreadAndDispatcher(CombinedVibration effect) {
return startThreadAndDispatcher(createVibration(effect));
}
- private long startThreadAndDispatcher(HalVibration vib) {
+ private HalVibration startThreadAndDispatcher(HalVibration vib) {
return startThreadAndDispatcher(vib, /* requestVibrationParamsFuture= */ null);
}
- private long startThreadAndDispatcher(VibrationEffect effect,
+ private HalVibration startThreadAndDispatcher(VibrationEffect effect,
CompletableFuture<Void> requestVibrationParamsFuture, int usage) {
VibrationAttributes attrs = new VibrationAttributes.Builder()
.setUsage(usage)
@@ -1898,14 +1871,14 @@
return startThreadAndDispatcher(vib, requestVibrationParamsFuture);
}
- private long startThreadAndDispatcher(HalVibration vib,
+ private HalVibration startThreadAndDispatcher(HalVibration vib,
CompletableFuture<Void> requestVibrationParamsFuture) {
mControllers = createVibratorControllers();
DeviceAdapter deviceAdapter = new DeviceAdapter(mVibrationSettings, mControllers);
mVibrationConductor = new VibrationStepConductor(vib, mVibrationSettings, deviceAdapter,
mVibrationScaler, mStatsLoggerMock, requestVibrationParamsFuture, mManagerHooks);
assertTrue(mThread.runVibrationOnVibrationThread(mVibrationConductor));
- return mVibrationConductor.getVibration().id;
+ return mVibrationConductor.getVibration();
}
private boolean waitUntil(BooleanSupplier predicate, long timeout)
@@ -1994,13 +1967,9 @@
.collect(Collectors.toList());
}
- private void verifyCallbacksTriggered(long vibrationId, Status expectedStatus) {
- verifyCallbacksTriggered(vibrationId, new Vibration.EndInfo(expectedStatus));
- }
-
- private void verifyCallbacksTriggered(long vibrationId, Vibration.EndInfo expectedEndInfo) {
- verify(mManagerHooks).onVibrationCompleted(eq(vibrationId), eq(expectedEndInfo));
- verify(mManagerHooks).onVibrationThreadReleased(vibrationId);
+ private void verifyCallbacksTriggered(HalVibration vibration, Status expectedStatus) {
+ assertThat(vibration.getStatus()).isEqualTo(expectedStatus);
+ verify(mManagerHooks).onVibrationThreadReleased(vibration.id);
}
private static final class TestLooperAutoDispatcher extends Thread {