diff --git a/services/core/java/com/android/server/vibrator/AbstractVibratorStep.java b/services/core/java/com/android/server/vibrator/AbstractVibratorStep.java
new file mode 100644
index 0000000..3550bda
--- /dev/null
+++ b/services/core/java/com/android/server/vibrator/AbstractVibratorStep.java
@@ -0,0 +1,148 @@
+/*
+ * Copyright (C) 2022 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 com.android.server.vibrator;
+
+import android.os.SystemClock;
+import android.os.VibrationEffect;
+import android.util.Slog;
+
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * Represent a step on a single vibrator that plays one or more segments from a
+ * {@link VibrationEffect.Composed} effect.
+ */
+abstract class AbstractVibratorStep extends Step {
+    public final VibratorController controller;
+    public final VibrationEffect.Composed effect;
+    public final int segmentIndex;
+    public final long previousStepVibratorOffTimeout;
+
+    long mVibratorOnResult;
+    boolean mVibratorCompleteCallbackReceived;
+
+    /**
+     * @param conductor          The VibrationStepConductor for these steps.
+     * @param startTime          The time to schedule this step in the
+     *                           {@link VibrationStepConductor}.
+     * @param controller         The vibrator that is playing the effect.
+     * @param effect             The effect being played in this step.
+     * @param index              The index of the next segment to be played by this step
+     * @param previousStepVibratorOffTimeout The time the vibrator is expected to complete any
+     *                           previous vibration and turn off. This is used to allow this step to
+     *                           be triggered when the completion callback is received, and can
+     *                           be used to play effects back-to-back.
+     */
+    AbstractVibratorStep(VibrationStepConductor conductor, long startTime,
+            VibratorController controller, VibrationEffect.Composed effect, int index,
+            long previousStepVibratorOffTimeout) {
+        super(conductor, startTime);
+        this.controller = controller;
+        this.effect = effect;
+        this.segmentIndex = index;
+        this.previousStepVibratorOffTimeout = previousStepVibratorOffTimeout;
+    }
+
+    public int getVibratorId() {
+        return controller.getVibratorInfo().getId();
+    }
+
+    @Override
+    public long getVibratorOnDuration() {
+        return mVibratorOnResult;
+    }
+
+    @Override
+    public boolean acceptVibratorCompleteCallback(int vibratorId) {
+        boolean isSameVibrator = controller.getVibratorInfo().getId() == vibratorId;
+        mVibratorCompleteCallbackReceived |= isSameVibrator;
+        // Only activate this step if a timeout was set to wait for the vibration to complete,
+        // otherwise we are waiting for the correct time to play the next step.
+        return isSameVibrator && (previousStepVibratorOffTimeout > SystemClock.uptimeMillis());
+    }
+
+    @Override
+    public List<Step> cancel() {
+        return Arrays.asList(new CompleteEffectVibratorStep(conductor, SystemClock.uptimeMillis(),
+                /* cancelled= */ true, controller, previousStepVibratorOffTimeout));
+    }
+
+    @Override
+    public void cancelImmediately() {
+        if (previousStepVibratorOffTimeout > SystemClock.uptimeMillis()) {
+            // Vibrator might be running from previous steps, so turn it off while canceling.
+            stopVibrating();
+        }
+    }
+
+    protected void stopVibrating() {
+        if (VibrationThread.DEBUG) {
+            Slog.d(VibrationThread.TAG,
+                    "Turning off vibrator " + getVibratorId());
+        }
+        controller.off();
+    }
+
+    protected void changeAmplitude(float amplitude) {
+        if (VibrationThread.DEBUG) {
+            Slog.d(VibrationThread.TAG,
+                    "Amplitude changed on vibrator " + getVibratorId() + " to " + amplitude);
+        }
+        controller.setAmplitude(amplitude);
+    }
+
+    /**
+     * Return the {@link VibrationStepConductor#nextVibrateStep} with same timings, only jumping
+     * the segments.
+     */
+    protected List<Step> skipToNextSteps(int segmentsSkipped) {
+        return nextSteps(startTime, previousStepVibratorOffTimeout, segmentsSkipped);
+    }
+
+    /**
+     * Return the {@link VibrationStepConductor#nextVibrateStep} with same start and off timings
+     * calculated from {@link #getVibratorOnDuration()}, jumping all played segments.
+     *
+     * <p>This method has same behavior as {@link #skipToNextSteps(int)} when the vibrator
+     * result is non-positive, meaning the vibrator has either ignored or failed to turn on.
+     */
+    protected List<Step> nextSteps(int segmentsPlayed) {
+        if (mVibratorOnResult <= 0) {
+            // Vibration was not started, so just skip the played segments and keep timings.
+            return skipToNextSteps(segmentsPlayed);
+        }
+        long nextStartTime = SystemClock.uptimeMillis() + mVibratorOnResult;
+        long nextVibratorOffTimeout =
+                nextStartTime + VibrationStepConductor.CALLBACKS_EXTRA_TIMEOUT;
+        return nextSteps(nextStartTime, nextVibratorOffTimeout, segmentsPlayed);
+    }
+
+    /**
+     * Return the {@link VibrationStepConductor#nextVibrateStep} with given start and off timings,
+     * which might be calculated independently, jumping all played segments.
+     *
+     * <p>This should be used when the vibrator on/off state is not responsible for the steps
+     * execution timings, e.g. while playing the vibrator amplitudes.
+     */
+    protected List<Step> nextSteps(long nextStartTime, long vibratorOffTimeout,
+            int segmentsPlayed) {
+        Step nextStep = conductor.nextVibrateStep(nextStartTime, controller, effect,
+                segmentIndex + segmentsPlayed, vibratorOffTimeout);
+        return nextStep == null ? VibrationStepConductor.EMPTY_STEP_LIST : Arrays.asList(nextStep);
+    }
+}
diff --git a/services/core/java/com/android/server/vibrator/CompleteEffectVibratorStep.java b/services/core/java/com/android/server/vibrator/CompleteEffectVibratorStep.java
new file mode 100644
index 0000000..8585e34
--- /dev/null
+++ b/services/core/java/com/android/server/vibrator/CompleteEffectVibratorStep.java
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2022 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 com.android.server.vibrator;
+
+import android.os.SystemClock;
+import android.os.Trace;
+import android.os.VibrationEffect;
+import android.util.Slog;
+
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * Represents a step to complete a {@link VibrationEffect}.
+ *
+ * <p>This runs right at the time the vibration is considered to end and will update the pending
+ * vibrators count. This can turn off the vibrator or slowly ramp it down to zero amplitude.
+ */
+final class CompleteEffectVibratorStep extends AbstractVibratorStep {
+    private final boolean mCancelled;
+
+    CompleteEffectVibratorStep(VibrationStepConductor conductor, long startTime, boolean cancelled,
+            VibratorController controller, long previousStepVibratorOffTimeout) {
+        super(conductor, startTime, controller, /* effect= */ null, /* index= */ -1,
+                previousStepVibratorOffTimeout);
+        mCancelled = cancelled;
+    }
+
+    @Override
+    public boolean isCleanUp() {
+        // If the vibration was cancelled then this is just a clean up to ramp off the vibrator.
+        // Otherwise this step is part of the vibration.
+        return mCancelled;
+    }
+
+    @Override
+    public List<Step> cancel() {
+        if (mCancelled) {
+            // Double cancelling will just turn off the vibrator right away.
+            return Arrays.asList(
+                    new TurnOffVibratorStep(conductor, SystemClock.uptimeMillis(), controller));
+        }
+        return super.cancel();
+    }
+
+    @Override
+    public List<Step> play() {
+        Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "CompleteEffectVibratorStep");
+        try {
+            if (VibrationThread.DEBUG) {
+                Slog.d(VibrationThread.TAG,
+                        "Running " + (mCancelled ? "cancel" : "complete") + " vibration"
+                                + " step on vibrator " + controller.getVibratorInfo().getId());
+            }
+            if (mVibratorCompleteCallbackReceived) {
+                // Vibration completion callback was received by this step, just turn if off
+                // and skip any clean-up.
+                stopVibrating();
+                return VibrationStepConductor.EMPTY_STEP_LIST;
+            }
+
+            float currentAmplitude = controller.getCurrentAmplitude();
+            long remainingOnDuration =
+                    previousStepVibratorOffTimeout - VibrationStepConductor.CALLBACKS_EXTRA_TIMEOUT
+                            - SystemClock.uptimeMillis();
+            long rampDownDuration =
+                    Math.min(remainingOnDuration,
+                            conductor.vibrationSettings.getRampDownDuration());
+            long stepDownDuration = conductor.vibrationSettings.getRampStepDuration();
+            if (currentAmplitude < VibrationStepConductor.RAMP_OFF_AMPLITUDE_MIN
+                    || rampDownDuration <= stepDownDuration) {
+                // No need to ramp down the amplitude, just wait to turn it off.
+                if (mCancelled) {
+                    // Vibration is completing because it was cancelled, turn off right away.
+                    stopVibrating();
+                    return VibrationStepConductor.EMPTY_STEP_LIST;
+                } else {
+                    return Arrays.asList(new TurnOffVibratorStep(
+                            conductor, previousStepVibratorOffTimeout, controller));
+                }
+            }
+
+            if (VibrationThread.DEBUG) {
+                Slog.d(VibrationThread.TAG,
+                        "Ramping down vibrator " + controller.getVibratorInfo().getId()
+                                + " from amplitude " + currentAmplitude
+                                + " for " + rampDownDuration + "ms");
+            }
+            float amplitudeDelta = currentAmplitude / (rampDownDuration / stepDownDuration);
+            float amplitudeTarget = currentAmplitude - amplitudeDelta;
+            long newVibratorOffTimeout =
+                    mCancelled ? rampDownDuration : previousStepVibratorOffTimeout;
+            return Arrays.asList(
+                    new RampOffVibratorStep(conductor, startTime, amplitudeTarget, amplitudeDelta,
+                            controller, newVibratorOffTimeout));
+        } finally {
+            Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR);
+        }
+    }
+}
diff --git a/services/core/java/com/android/server/vibrator/ComposePrimitivesVibratorStep.java b/services/core/java/com/android/server/vibrator/ComposePrimitivesVibratorStep.java
new file mode 100644
index 0000000..d1ea805
--- /dev/null
+++ b/services/core/java/com/android/server/vibrator/ComposePrimitivesVibratorStep.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2022 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 com.android.server.vibrator;
+
+import android.os.Trace;
+import android.os.VibrationEffect;
+import android.os.vibrator.PrimitiveSegment;
+import android.os.vibrator.VibrationEffectSegment;
+import android.util.Slog;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Represents a step to turn the vibrator on using a composition of primitives.
+ *
+ * <p>This step will use the maximum supported number of consecutive segments of type
+ * {@link PrimitiveSegment} starting at the current index.
+ */
+final class ComposePrimitivesVibratorStep extends AbstractVibratorStep {
+
+    ComposePrimitivesVibratorStep(VibrationStepConductor conductor, long startTime,
+            VibratorController controller, VibrationEffect.Composed effect, int index,
+            long previousStepVibratorOffTimeout) {
+        // This step should wait for the last vibration to finish (with the timeout) and for the
+        // intended step start time (to respect the effect delays).
+        super(conductor, Math.max(startTime, previousStepVibratorOffTimeout), controller, effect,
+                index, previousStepVibratorOffTimeout);
+    }
+
+    @Override
+    public List<Step> play() {
+        Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "ComposePrimitivesStep");
+        try {
+            // Load the next PrimitiveSegments to create a single compose call to the vibrator,
+            // limited to the vibrator composition maximum size.
+            int limit = controller.getVibratorInfo().getCompositionSizeMax();
+            int segmentCount = limit > 0
+                    ? Math.min(effect.getSegments().size(), segmentIndex + limit)
+                    : effect.getSegments().size();
+            List<PrimitiveSegment> primitives = new ArrayList<>();
+            for (int i = segmentIndex; i < segmentCount; i++) {
+                VibrationEffectSegment segment = effect.getSegments().get(i);
+                if (segment instanceof PrimitiveSegment) {
+                    primitives.add((PrimitiveSegment) segment);
+                } else {
+                    break;
+                }
+            }
+
+            if (primitives.isEmpty()) {
+                Slog.w(VibrationThread.TAG, "Ignoring wrong segment for a ComposePrimitivesStep: "
+                        + effect.getSegments().get(segmentIndex));
+                return skipToNextSteps(/* segmentsSkipped= */ 1);
+            }
+
+            if (VibrationThread.DEBUG) {
+                Slog.d(VibrationThread.TAG, "Compose " + primitives + " primitives on vibrator "
+                        + controller.getVibratorInfo().getId());
+            }
+            mVibratorOnResult = controller.on(
+                    primitives.toArray(new PrimitiveSegment[primitives.size()]),
+                    getVibration().id);
+
+            return nextSteps(/* segmentsPlayed= */ primitives.size());
+        } finally {
+            Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR);
+        }
+    }
+}
diff --git a/services/core/java/com/android/server/vibrator/ComposePwleVibratorStep.java b/services/core/java/com/android/server/vibrator/ComposePwleVibratorStep.java
new file mode 100644
index 0000000..73bf933
--- /dev/null
+++ b/services/core/java/com/android/server/vibrator/ComposePwleVibratorStep.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2022 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 com.android.server.vibrator;
+
+import android.os.Trace;
+import android.os.VibrationEffect;
+import android.os.vibrator.RampSegment;
+import android.os.vibrator.StepSegment;
+import android.os.vibrator.VibrationEffectSegment;
+import android.util.Slog;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Represents a step to turn the vibrator on using a composition of PWLE segments.
+ *
+ * <p>This step will use the maximum supported number of consecutive segments of type
+ * {@link StepSegment} or {@link RampSegment} starting at the current index.
+ */
+final class ComposePwleVibratorStep extends AbstractVibratorStep {
+
+    ComposePwleVibratorStep(VibrationStepConductor conductor, long startTime,
+            VibratorController controller, VibrationEffect.Composed effect, int index,
+            long previousStepVibratorOffTimeout) {
+        // This step should wait for the last vibration to finish (with the timeout) and for the
+        // intended step start time (to respect the effect delays).
+        super(conductor, Math.max(startTime, previousStepVibratorOffTimeout), controller, effect,
+                index, previousStepVibratorOffTimeout);
+    }
+
+    @Override
+    public List<Step> play() {
+        Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "ComposePwleStep");
+        try {
+            // Load the next RampSegments to create a single composePwle call to the vibrator,
+            // limited to the vibrator PWLE maximum size.
+            int limit = controller.getVibratorInfo().getPwleSizeMax();
+            int segmentCount = limit > 0
+                    ? Math.min(effect.getSegments().size(), segmentIndex + limit)
+                    : effect.getSegments().size();
+            List<RampSegment> pwles = new ArrayList<>();
+            for (int i = segmentIndex; i < segmentCount; i++) {
+                VibrationEffectSegment segment = effect.getSegments().get(i);
+                if (segment instanceof RampSegment) {
+                    pwles.add((RampSegment) segment);
+                } else {
+                    break;
+                }
+            }
+
+            if (pwles.isEmpty()) {
+                Slog.w(VibrationThread.TAG, "Ignoring wrong segment for a ComposePwleStep: "
+                        + effect.getSegments().get(segmentIndex));
+                return skipToNextSteps(/* segmentsSkipped= */ 1);
+            }
+
+            if (VibrationThread.DEBUG) {
+                Slog.d(VibrationThread.TAG, "Compose " + pwles + " PWLEs on vibrator "
+                        + controller.getVibratorInfo().getId());
+            }
+            mVibratorOnResult = controller.on(pwles.toArray(new RampSegment[pwles.size()]),
+                    getVibration().id);
+
+            return nextSteps(/* segmentsPlayed= */ pwles.size());
+        } finally {
+            Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR);
+        }
+    }
+}
diff --git a/services/core/java/com/android/server/vibrator/FinishSequentialEffectStep.java b/services/core/java/com/android/server/vibrator/FinishSequentialEffectStep.java
new file mode 100644
index 0000000..bbbca02
--- /dev/null
+++ b/services/core/java/com/android/server/vibrator/FinishSequentialEffectStep.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2022 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 com.android.server.vibrator;
+
+import android.os.Trace;
+import android.util.Slog;
+
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * Finish a sync vibration started by a {@link StartSequentialEffectStep}.
+ *
+ * <p>This only plays after all active vibrators steps have finished, and adds a {@link
+ * StartSequentialEffectStep} to the queue if the sequential effect isn't finished yet.
+ */
+final class FinishSequentialEffectStep extends Step {
+    public final StartSequentialEffectStep startedStep;
+
+    FinishSequentialEffectStep(StartSequentialEffectStep startedStep) {
+        // No predefined startTime, just wait for all steps in the queue.
+        super(startedStep.conductor, Long.MAX_VALUE);
+        this.startedStep = startedStep;
+    }
+
+    @Override
+    public boolean isCleanUp() {
+        // This step only notes that all the vibrators has been turned off.
+        return true;
+    }
+
+    @Override
+    public List<Step> play() {
+        Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "FinishSequentialEffectStep");
+        try {
+            if (VibrationThread.DEBUG) {
+                Slog.d(VibrationThread.TAG,
+                        "FinishSequentialEffectStep for effect #" + startedStep.currentIndex);
+            }
+            conductor.vibratorManagerHooks.noteVibratorOff(conductor.getVibration().uid);
+            Step nextStep = startedStep.nextStep();
+            return nextStep == null ? VibrationStepConductor.EMPTY_STEP_LIST
+                    : Arrays.asList(nextStep);
+        } finally {
+            Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR);
+        }
+    }
+
+    @Override
+    public List<Step> cancel() {
+        cancelImmediately();
+        return VibrationStepConductor.EMPTY_STEP_LIST;
+    }
+
+    @Override
+    public void cancelImmediately() {
+        conductor.vibratorManagerHooks.noteVibratorOff(conductor.getVibration().uid);
+    }
+}
diff --git a/services/core/java/com/android/server/vibrator/PerformPrebakedVibratorStep.java b/services/core/java/com/android/server/vibrator/PerformPrebakedVibratorStep.java
new file mode 100644
index 0000000..601ae97
--- /dev/null
+++ b/services/core/java/com/android/server/vibrator/PerformPrebakedVibratorStep.java
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2022 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 com.android.server.vibrator;
+
+import android.os.Trace;
+import android.os.VibrationEffect;
+import android.os.vibrator.PrebakedSegment;
+import android.os.vibrator.VibrationEffectSegment;
+import android.util.Slog;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Represents a step to turn the vibrator on with a single prebaked effect.
+ *
+ * <p>This step automatically falls back by replacing the prebaked segment with
+ * {@link VibrationSettings#getFallbackEffect(int)}, if available.
+ */
+final class PerformPrebakedVibratorStep extends AbstractVibratorStep {
+
+    PerformPrebakedVibratorStep(VibrationStepConductor conductor, long startTime,
+            VibratorController controller, VibrationEffect.Composed effect, int index,
+            long previousStepVibratorOffTimeout) {
+        // This step should wait for the last vibration to finish (with the timeout) and for the
+        // intended step start time (to respect the effect delays).
+        super(conductor, Math.max(startTime, previousStepVibratorOffTimeout), controller, effect,
+                index, previousStepVibratorOffTimeout);
+    }
+
+    @Override
+    public List<Step> play() {
+        Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "PerformPrebakedVibratorStep");
+        try {
+            VibrationEffectSegment segment = effect.getSegments().get(segmentIndex);
+            if (!(segment instanceof PrebakedSegment)) {
+                Slog.w(VibrationThread.TAG, "Ignoring wrong segment for a "
+                        + "PerformPrebakedVibratorStep: " + segment);
+                return skipToNextSteps(/* segmentsSkipped= */ 1);
+            }
+
+            PrebakedSegment prebaked = (PrebakedSegment) segment;
+            if (VibrationThread.DEBUG) {
+                Slog.d(VibrationThread.TAG, "Perform " + VibrationEffect.effectIdToString(
+                        prebaked.getEffectId()) + " on vibrator "
+                        + controller.getVibratorInfo().getId());
+            }
+
+            VibrationEffect fallback = getVibration().getFallback(prebaked.getEffectId());
+            mVibratorOnResult = controller.on(prebaked, getVibration().id);
+
+            if (mVibratorOnResult == 0 && prebaked.shouldFallback()
+                    && (fallback instanceof VibrationEffect.Composed)) {
+                if (VibrationThread.DEBUG) {
+                    Slog.d(VibrationThread.TAG, "Playing fallback for effect "
+                            + VibrationEffect.effectIdToString(prebaked.getEffectId()));
+                }
+                AbstractVibratorStep fallbackStep = conductor.nextVibrateStep(startTime, controller,
+                        replaceCurrentSegment((VibrationEffect.Composed) fallback),
+                        segmentIndex, previousStepVibratorOffTimeout);
+                List<Step> fallbackResult = fallbackStep.play();
+                // Update the result with the fallback result so this step is seamlessly
+                // replaced by the fallback to any outer application of this.
+                mVibratorOnResult = fallbackStep.getVibratorOnDuration();
+                return fallbackResult;
+            }
+
+            return nextSteps(/* segmentsPlayed= */ 1);
+        } finally {
+            Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR);
+        }
+    }
+
+    /**
+     * Replace segment at {@link #segmentIndex} in {@link #effect} with given fallback segments.
+     *
+     * @return a copy of {@link #effect} with replaced segment.
+     */
+    private VibrationEffect.Composed replaceCurrentSegment(VibrationEffect.Composed fallback) {
+        List<VibrationEffectSegment> newSegments = new ArrayList<>(effect.getSegments());
+        int newRepeatIndex = effect.getRepeatIndex();
+        newSegments.remove(segmentIndex);
+        newSegments.addAll(segmentIndex, fallback.getSegments());
+        if (segmentIndex < effect.getRepeatIndex()) {
+            newRepeatIndex += fallback.getSegments().size() - 1;
+        }
+        return new VibrationEffect.Composed(newSegments, newRepeatIndex);
+    }
+}
diff --git a/services/core/java/com/android/server/vibrator/RampOffVibratorStep.java b/services/core/java/com/android/server/vibrator/RampOffVibratorStep.java
new file mode 100644
index 0000000..8cf5fb3
--- /dev/null
+++ b/services/core/java/com/android/server/vibrator/RampOffVibratorStep.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2022 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 com.android.server.vibrator;
+
+import android.os.SystemClock;
+import android.os.Trace;
+import android.util.Slog;
+
+import java.util.Arrays;
+import java.util.List;
+
+/** Represents a step to ramp down the vibrator amplitude before turning it off. */
+final class RampOffVibratorStep extends AbstractVibratorStep {
+    private final float mAmplitudeTarget;
+    private final float mAmplitudeDelta;
+
+    RampOffVibratorStep(VibrationStepConductor conductor, long startTime, float amplitudeTarget,
+            float amplitudeDelta, VibratorController controller,
+            long previousStepVibratorOffTimeout) {
+        super(conductor, startTime, controller, /* effect= */ null, /* index= */ -1,
+                previousStepVibratorOffTimeout);
+        mAmplitudeTarget = amplitudeTarget;
+        mAmplitudeDelta = amplitudeDelta;
+    }
+
+    @Override
+    public boolean isCleanUp() {
+        return true;
+    }
+
+    @Override
+    public List<Step> cancel() {
+        return Arrays.asList(
+                new TurnOffVibratorStep(conductor, SystemClock.uptimeMillis(), controller));
+    }
+
+    @Override
+    public List<Step> play() {
+        Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "RampOffVibratorStep");
+        try {
+            if (VibrationThread.DEBUG) {
+                long latency = SystemClock.uptimeMillis() - startTime;
+                Slog.d(VibrationThread.TAG, "Ramp down the vibrator amplitude, step with "
+                        + latency + "ms latency.");
+            }
+            if (mVibratorCompleteCallbackReceived) {
+                // Vibration completion callback was received by this step, just turn if off
+                // and skip the rest of the steps to ramp down the vibrator amplitude.
+                stopVibrating();
+                return VibrationStepConductor.EMPTY_STEP_LIST;
+            }
+
+            changeAmplitude(mAmplitudeTarget);
+
+            float newAmplitudeTarget = mAmplitudeTarget - mAmplitudeDelta;
+            if (newAmplitudeTarget < VibrationStepConductor.RAMP_OFF_AMPLITUDE_MIN) {
+                // Vibrator amplitude cannot go further down, just turn it off.
+                return Arrays.asList(new TurnOffVibratorStep(
+                        conductor, previousStepVibratorOffTimeout, controller));
+            }
+            return Arrays.asList(new RampOffVibratorStep(
+                    conductor,
+                    startTime + conductor.vibrationSettings.getRampStepDuration(),
+                    newAmplitudeTarget, mAmplitudeDelta, controller,
+                    previousStepVibratorOffTimeout));
+        } finally {
+            Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR);
+        }
+    }
+}
diff --git a/services/core/java/com/android/server/vibrator/SetAmplitudeVibratorStep.java b/services/core/java/com/android/server/vibrator/SetAmplitudeVibratorStep.java
new file mode 100644
index 0000000..d5c1116
--- /dev/null
+++ b/services/core/java/com/android/server/vibrator/SetAmplitudeVibratorStep.java
@@ -0,0 +1,186 @@
+/*
+ * Copyright (C) 2022 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 com.android.server.vibrator;
+
+import android.os.SystemClock;
+import android.os.Trace;
+import android.os.VibrationEffect;
+import android.os.vibrator.StepSegment;
+import android.os.vibrator.VibrationEffectSegment;
+import android.util.Slog;
+
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * Represents a step to turn the vibrator on and change its amplitude.
+ *
+ * <p>This step ignores vibration completion callbacks and control the vibrator on/off state
+ * and amplitude to simulate waveforms represented by a sequence of {@link StepSegment}.
+ */
+final class SetAmplitudeVibratorStep extends AbstractVibratorStep {
+    private long mNextOffTime;
+
+    SetAmplitudeVibratorStep(VibrationStepConductor conductor, long startTime,
+            VibratorController controller, VibrationEffect.Composed effect, int index,
+            long previousStepVibratorOffTimeout) {
+        // This step has a fixed startTime coming from the timings of the waveform it's playing.
+        super(conductor, startTime, controller, effect, index, previousStepVibratorOffTimeout);
+        mNextOffTime = previousStepVibratorOffTimeout;
+    }
+
+    @Override
+    public boolean acceptVibratorCompleteCallback(int vibratorId) {
+        if (controller.getVibratorInfo().getId() == vibratorId) {
+            mVibratorCompleteCallbackReceived = true;
+            mNextOffTime = SystemClock.uptimeMillis();
+        }
+        // Timings are tightly controlled here, so only trigger this step if the vibrator was
+        // supposed to be ON but has completed prematurely, to turn it back on as soon as
+        // possible.
+        return mNextOffTime < startTime && controller.getCurrentAmplitude() > 0;
+    }
+
+    @Override
+    public List<Step> play() {
+        // TODO: consider separating the "on" steps at the start into a separate Step.
+        // TODO: consider instantiating the step with the required amplitude, rather than
+        // needing to dig into the effect.
+        Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "SetAmplitudeVibratorStep");
+        try {
+            long now = SystemClock.uptimeMillis();
+            long latency = now - startTime;
+            if (VibrationThread.DEBUG) {
+                Slog.d(VibrationThread.TAG,
+                        "Running amplitude step with " + latency + "ms latency.");
+            }
+
+            if (mVibratorCompleteCallbackReceived && latency < 0) {
+                // This step was run early because the vibrator turned off prematurely.
+                // Turn it back on and return this same step to run at the exact right time.
+                mNextOffTime = turnVibratorBackOn(/* remainingDuration= */ -latency);
+                return Arrays.asList(new SetAmplitudeVibratorStep(conductor, startTime, controller,
+                        effect, segmentIndex, mNextOffTime));
+            }
+
+            VibrationEffectSegment segment = effect.getSegments().get(segmentIndex);
+            if (!(segment instanceof StepSegment)) {
+                Slog.w(VibrationThread.TAG,
+                        "Ignoring wrong segment for a SetAmplitudeVibratorStep: " + segment);
+                return skipToNextSteps(/* segmentsSkipped= */ 1);
+            }
+
+            StepSegment stepSegment = (StepSegment) segment;
+            if (stepSegment.getDuration() == 0) {
+                // Skip waveform entries with zero timing.
+                return skipToNextSteps(/* segmentsSkipped= */ 1);
+            }
+
+            float amplitude = stepSegment.getAmplitude();
+            if (amplitude == 0) {
+                if (previousStepVibratorOffTimeout > now) {
+                    // Amplitude cannot be set to zero, so stop the vibrator.
+                    stopVibrating();
+                    mNextOffTime = now;
+                }
+            } else {
+                if (startTime >= mNextOffTime) {
+                    // Vibrator is OFF. Turn vibrator back on for the duration of another
+                    // cycle before setting the amplitude.
+                    long onDuration = getVibratorOnDuration(effect, segmentIndex);
+                    if (onDuration > 0) {
+                        mVibratorOnResult = startVibrating(onDuration);
+                        mNextOffTime = now + onDuration
+                                + VibrationStepConductor.CALLBACKS_EXTRA_TIMEOUT;
+                    }
+                }
+                changeAmplitude(amplitude);
+            }
+
+            // Use original startTime to avoid propagating latencies to the waveform.
+            long nextStartTime = startTime + segment.getDuration();
+            return nextSteps(nextStartTime, mNextOffTime, /* segmentsPlayed= */ 1);
+        } finally {
+            Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR);
+        }
+    }
+
+    private long turnVibratorBackOn(long remainingDuration) {
+        long onDuration = getVibratorOnDuration(effect, segmentIndex);
+        if (onDuration <= 0) {
+            // Vibrator is supposed to go back off when this step starts, so just leave it off.
+            return previousStepVibratorOffTimeout;
+        }
+        onDuration += remainingDuration;
+        float expectedAmplitude = controller.getCurrentAmplitude();
+        mVibratorOnResult = startVibrating(onDuration);
+        if (mVibratorOnResult > 0) {
+            // Set the amplitude back to the value it was supposed to be playing at.
+            changeAmplitude(expectedAmplitude);
+        }
+        return SystemClock.uptimeMillis() + onDuration
+                + VibrationStepConductor.CALLBACKS_EXTRA_TIMEOUT;
+    }
+
+    private long startVibrating(long duration) {
+        if (VibrationThread.DEBUG) {
+            Slog.d(VibrationThread.TAG,
+                    "Turning on vibrator " + controller.getVibratorInfo().getId() + " for "
+                            + duration + "ms");
+        }
+        return controller.on(duration, getVibration().id);
+    }
+
+    /**
+     * Get the duration the vibrator will be on for a waveform, starting at {@code startIndex}
+     * until the next time it's vibrating amplitude is zero or a different type of segment is
+     * found.
+     */
+    private long getVibratorOnDuration(VibrationEffect.Composed effect, int startIndex) {
+        List<VibrationEffectSegment> segments = effect.getSegments();
+        int segmentCount = segments.size();
+        int repeatIndex = effect.getRepeatIndex();
+        int i = startIndex;
+        long timing = 0;
+        while (i < segmentCount) {
+            VibrationEffectSegment segment = segments.get(i);
+            if (!(segment instanceof StepSegment)
+                    || ((StepSegment) segment).getAmplitude() == 0) {
+                break;
+            }
+            timing += segment.getDuration();
+            i++;
+            if (i == segmentCount && repeatIndex >= 0) {
+                i = repeatIndex;
+                // prevent infinite loop
+                repeatIndex = -1;
+            }
+            if (i == startIndex) {
+                // The repeating waveform keeps the vibrator ON all the time. Use a minimum
+                // of 1s duration to prevent short patterns from turning the vibrator ON too
+                // frequently.
+                return Math.max(timing, 1000);
+            }
+        }
+        if (i == segmentCount && effect.getRepeatIndex() < 0) {
+            // Vibration ending at non-zero amplitude, add extra timings to ramp down after
+            // vibration is complete.
+            timing += conductor.vibrationSettings.getRampDownDuration();
+        }
+        return timing;
+    }
+}
diff --git a/services/core/java/com/android/server/vibrator/StartSequentialEffectStep.java b/services/core/java/com/android/server/vibrator/StartSequentialEffectStep.java
new file mode 100644
index 0000000..8ed002a
--- /dev/null
+++ b/services/core/java/com/android/server/vibrator/StartSequentialEffectStep.java
@@ -0,0 +1,371 @@
+/*
+ * Copyright (C) 2022 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 com.android.server.vibrator;
+
+import android.annotation.Nullable;
+import android.hardware.vibrator.IVibratorManager;
+import android.os.CombinedVibration;
+import android.os.SystemClock;
+import android.os.Trace;
+import android.os.VibrationEffect;
+import android.os.VibratorInfo;
+import android.os.vibrator.PrebakedSegment;
+import android.os.vibrator.PrimitiveSegment;
+import android.os.vibrator.StepSegment;
+import android.os.vibrator.VibrationEffectSegment;
+import android.util.Slog;
+import android.util.SparseArray;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Starts a sync vibration.
+ *
+ * <p>If this step has successfully started playing a vibration on any vibrator, it will always
+ * add a {@link FinishSequentialEffectStep} to the queue, to be played after all vibrators
+ * have finished all their individual steps.
+ *
+ * <p>If this step does not start any vibrator, it will add a {@link StartSequentialEffectStep} if
+ * the sequential effect isn't finished yet.
+ *
+ * <p>TODO: this step actually does several things: multiple HAL calls to sync the vibrators,
+ * as well as dispatching the underlying vibrator instruction calls (which need to be done before
+ * triggering the synced effects). This role/encapsulation could probably be improved to split up
+ * the grouped HAL calls here, as well as to clarify the role of dispatching VibratorSteps between
+ * this class and the controller.
+ */
+final class StartSequentialEffectStep extends Step {
+    public final CombinedVibration.Sequential sequentialEffect;
+    public final int currentIndex;
+
+    private long mVibratorsOnMaxDuration;
+
+    StartSequentialEffectStep(VibrationStepConductor conductor,
+            CombinedVibration.Sequential effect) {
+        this(conductor, SystemClock.uptimeMillis() + effect.getDelays().get(0), effect,
+                /* index= */ 0);
+    }
+
+    StartSequentialEffectStep(VibrationStepConductor conductor, long startTime,
+            CombinedVibration.Sequential effect, int index) {
+        super(conductor, startTime);
+        sequentialEffect = effect;
+        currentIndex = index;
+    }
+
+    @Override
+    public long getVibratorOnDuration() {
+        return mVibratorsOnMaxDuration;
+    }
+
+    @Override
+    public List<Step> play() {
+        Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "StartSequentialEffectStep");
+        List<Step> nextSteps = new ArrayList<>();
+        mVibratorsOnMaxDuration = -1;
+        try {
+            if (VibrationThread.DEBUG) {
+                Slog.d(VibrationThread.TAG,
+                        "StartSequentialEffectStep for effect #" + currentIndex);
+            }
+            CombinedVibration effect = sequentialEffect.getEffects().get(currentIndex);
+            DeviceEffectMap effectMapping = createEffectToVibratorMapping(effect);
+            if (effectMapping == null) {
+                // Unable to map effects to vibrators, ignore this step.
+                return nextSteps;
+            }
+
+            mVibratorsOnMaxDuration = startVibrating(effectMapping, nextSteps);
+            if (mVibratorsOnMaxDuration > 0) {
+                conductor.vibratorManagerHooks.noteVibratorOn(conductor.getVibration().uid,
+                        mVibratorsOnMaxDuration);
+            }
+        } finally {
+            if (mVibratorsOnMaxDuration >= 0) {
+                // It least one vibrator was started then add a finish step to wait for all
+                // active vibrators to finish their individual steps before going to the next.
+                // Otherwise this step was ignored so just go to the next one.
+                Step nextStep =
+                        mVibratorsOnMaxDuration > 0 ? new FinishSequentialEffectStep(this)
+                                : nextStep();
+                if (nextStep != null) {
+                    nextSteps.add(nextStep);
+                }
+            }
+            Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR);
+        }
+        return nextSteps;
+    }
+
+    @Override
+    public List<Step> cancel() {
+        return VibrationStepConductor.EMPTY_STEP_LIST;
+    }
+
+    @Override
+    public void cancelImmediately() {
+    }
+
+    /**
+     * Create the next {@link StartSequentialEffectStep} to play this sequential effect, starting at
+     * the
+     * time this method is called, or null if sequence is complete.
+     */
+    @Nullable
+    Step nextStep() {
+        int nextIndex = currentIndex + 1;
+        if (nextIndex >= sequentialEffect.getEffects().size()) {
+            return null;
+        }
+        long nextEffectDelay = sequentialEffect.getDelays().get(nextIndex);
+        long nextStartTime = SystemClock.uptimeMillis() + nextEffectDelay;
+        return new StartSequentialEffectStep(conductor, nextStartTime, sequentialEffect,
+                nextIndex);
+    }
+
+    /** Create a mapping of individual {@link VibrationEffect} to available vibrators. */
+    @Nullable
+    private DeviceEffectMap createEffectToVibratorMapping(
+            CombinedVibration effect) {
+        if (effect instanceof CombinedVibration.Mono) {
+            return new DeviceEffectMap((CombinedVibration.Mono) effect);
+        }
+        if (effect instanceof CombinedVibration.Stereo) {
+            return new DeviceEffectMap((CombinedVibration.Stereo) effect);
+        }
+        return null;
+    }
+
+    /**
+     * Starts playing effects on designated vibrators, in sync.
+     *
+     * @param effectMapping The {@link CombinedVibration} mapped to this device vibrators
+     * @param nextSteps     An output list to accumulate the future {@link Step
+     *                      Steps} created
+     *                      by this method, typically one for each vibrator that has
+     *                      successfully started vibrating on this step.
+     * @return The duration, in millis, of the {@link CombinedVibration}. Repeating
+     * waveforms return {@link Long#MAX_VALUE}. Zero or negative values indicate the vibrators
+     * have ignored all effects.
+     */
+    private long startVibrating(
+            DeviceEffectMap effectMapping, List<Step> nextSteps) {
+        int vibratorCount = effectMapping.size();
+        if (vibratorCount == 0) {
+            // No effect was mapped to any available vibrator.
+            return 0;
+        }
+
+        AbstractVibratorStep[] steps = new AbstractVibratorStep[vibratorCount];
+        long vibrationStartTime = SystemClock.uptimeMillis();
+        for (int i = 0; i < vibratorCount; i++) {
+            steps[i] = conductor.nextVibrateStep(vibrationStartTime,
+                    conductor.getVibrators().get(effectMapping.vibratorIdAt(i)),
+                    effectMapping.effectAt(i),
+                    /* segmentIndex= */ 0, /* vibratorOffTimeout= */ 0);
+        }
+
+        if (steps.length == 1) {
+            // No need to prepare and trigger sync effects on a single vibrator.
+            return startVibrating(steps[0], nextSteps);
+        }
+
+        // This synchronization of vibrators should be executed one at a time, even if we are
+        // vibrating different sets of vibrators in parallel. The manager can only prepareSynced
+        // one set of vibrators at a time.
+        // This property is guaranteed by there only being one thread (VibrationThread) executing
+        // one Step at a time, so there's no need to hold the state lock.
+        // TODO: remove the large locked block in a dedicated change.
+        synchronized (conductor.mLock) {
+            boolean hasPrepared = false;
+            boolean hasTriggered = false;
+            long maxDuration = 0;
+            try {
+                hasPrepared = conductor.vibratorManagerHooks.prepareSyncedVibration(
+                        effectMapping.getRequiredSyncCapabilities(),
+                        effectMapping.getVibratorIds());
+
+                for (AbstractVibratorStep step : steps) {
+                    long duration = startVibrating(step, nextSteps);
+                    if (duration < 0) {
+                        // One vibrator has failed, fail this entire sync attempt.
+                        return maxDuration = -1;
+                    }
+                    maxDuration = Math.max(maxDuration, duration);
+                }
+
+                // Check if sync was prepared and if any step was accepted by a vibrator,
+                // otherwise there is nothing to trigger here.
+                if (hasPrepared && maxDuration > 0) {
+                    hasTriggered = conductor.vibratorManagerHooks.triggerSyncedVibration(
+                            getVibration().id);
+                }
+                return maxDuration;
+            } finally {
+                if (hasPrepared && !hasTriggered) {
+                    // Trigger has failed or all steps were ignored by the vibrators.
+                    conductor.vibratorManagerHooks.cancelSyncedVibration();
+                    nextSteps.clear();
+                } else if (maxDuration < 0) {
+                    // Some vibrator failed without being prepared so other vibrators might be
+                    // active. Cancel and remove every pending step from output list.
+                    for (int i = nextSteps.size() - 1; i >= 0; i--) {
+                        nextSteps.remove(i).cancelImmediately();
+                    }
+                }
+            }
+        }
+    }
+
+    private long startVibrating(AbstractVibratorStep step, List<Step> nextSteps) {
+        nextSteps.addAll(step.play());
+        long stepDuration = step.getVibratorOnDuration();
+        if (stepDuration < 0) {
+            // Step failed, so return negative duration to propagate failure.
+            return stepDuration;
+        }
+        // Return the longest estimation for the entire effect.
+        return Math.max(stepDuration, step.effect.getDuration());
+    }
+
+    /**
+     * Map a {@link CombinedVibration} to the vibrators available on the device.
+     *
+     * <p>This contains the logic to find the capabilities required from {@link IVibratorManager} to
+     * play all of the effects in sync.
+     */
+    final class DeviceEffectMap {
+        private final SparseArray<VibrationEffect.Composed> mVibratorEffects;
+        private final int[] mVibratorIds;
+        private final long mRequiredSyncCapabilities;
+
+        DeviceEffectMap(CombinedVibration.Mono mono) {
+            SparseArray<VibratorController> vibrators = conductor.getVibrators();
+            mVibratorEffects = new SparseArray<>(vibrators.size());
+            mVibratorIds = new int[vibrators.size()];
+            for (int i = 0; i < vibrators.size(); i++) {
+                int vibratorId = vibrators.keyAt(i);
+                VibratorInfo vibratorInfo = vibrators.valueAt(i).getVibratorInfo();
+                VibrationEffect effect = conductor.deviceEffectAdapter.apply(
+                        mono.getEffect(), vibratorInfo);
+                if (effect instanceof VibrationEffect.Composed) {
+                    mVibratorEffects.put(vibratorId, (VibrationEffect.Composed) effect);
+                    mVibratorIds[i] = vibratorId;
+                }
+            }
+            mRequiredSyncCapabilities = calculateRequiredSyncCapabilities(mVibratorEffects);
+        }
+
+        DeviceEffectMap(CombinedVibration.Stereo stereo) {
+            SparseArray<VibratorController> vibrators = conductor.getVibrators();
+            SparseArray<VibrationEffect> stereoEffects = stereo.getEffects();
+            mVibratorEffects = new SparseArray<>();
+            for (int i = 0; i < stereoEffects.size(); i++) {
+                int vibratorId = stereoEffects.keyAt(i);
+                if (vibrators.contains(vibratorId)) {
+                    VibratorInfo vibratorInfo = vibrators.valueAt(i).getVibratorInfo();
+                    VibrationEffect effect = conductor.deviceEffectAdapter.apply(
+                            stereoEffects.valueAt(i), vibratorInfo);
+                    if (effect instanceof VibrationEffect.Composed) {
+                        mVibratorEffects.put(vibratorId, (VibrationEffect.Composed) effect);
+                    }
+                }
+            }
+            mVibratorIds = new int[mVibratorEffects.size()];
+            for (int i = 0; i < mVibratorEffects.size(); i++) {
+                mVibratorIds[i] = mVibratorEffects.keyAt(i);
+            }
+            mRequiredSyncCapabilities = calculateRequiredSyncCapabilities(mVibratorEffects);
+        }
+
+        /**
+         * Return the number of vibrators mapped to play the {@link CombinedVibration} on this
+         * device.
+         */
+        public int size() {
+            return mVibratorIds.length;
+        }
+
+        /**
+         * Return all capabilities required to play the {@link CombinedVibration} in
+         * between calls to {@link IVibratorManager#prepareSynced} and
+         * {@link IVibratorManager#triggerSynced}.
+         */
+        public long getRequiredSyncCapabilities() {
+            return mRequiredSyncCapabilities;
+        }
+
+        /** Return all vibrator ids mapped to play the {@link CombinedVibration}. */
+        public int[] getVibratorIds() {
+            return mVibratorIds;
+        }
+
+        /** Return the id of the vibrator at given index. */
+        public int vibratorIdAt(int index) {
+            return mVibratorEffects.keyAt(index);
+        }
+
+        /** Return the {@link VibrationEffect} at given index. */
+        public VibrationEffect.Composed effectAt(int index) {
+            return mVibratorEffects.valueAt(index);
+        }
+
+        /**
+         * Return all capabilities required from the {@link IVibratorManager} to prepare and
+         * trigger all given effects in sync.
+         *
+         * @return {@link IVibratorManager#CAP_SYNC} together with all required
+         * IVibratorManager.CAP_PREPARE_* and IVibratorManager.CAP_MIXED_TRIGGER_* capabilities.
+         */
+        private long calculateRequiredSyncCapabilities(
+                SparseArray<VibrationEffect.Composed> effects) {
+            long prepareCap = 0;
+            for (int i = 0; i < effects.size(); i++) {
+                VibrationEffectSegment firstSegment = effects.valueAt(i).getSegments().get(0);
+                if (firstSegment instanceof StepSegment) {
+                    prepareCap |= IVibratorManager.CAP_PREPARE_ON;
+                } else if (firstSegment instanceof PrebakedSegment) {
+                    prepareCap |= IVibratorManager.CAP_PREPARE_PERFORM;
+                } else if (firstSegment instanceof PrimitiveSegment) {
+                    prepareCap |= IVibratorManager.CAP_PREPARE_COMPOSE;
+                }
+            }
+            int triggerCap = 0;
+            if (requireMixedTriggerCapability(prepareCap, IVibratorManager.CAP_PREPARE_ON)) {
+                triggerCap |= IVibratorManager.CAP_MIXED_TRIGGER_ON;
+            }
+            if (requireMixedTriggerCapability(prepareCap, IVibratorManager.CAP_PREPARE_PERFORM)) {
+                triggerCap |= IVibratorManager.CAP_MIXED_TRIGGER_PERFORM;
+            }
+            if (requireMixedTriggerCapability(prepareCap, IVibratorManager.CAP_PREPARE_COMPOSE)) {
+                triggerCap |= IVibratorManager.CAP_MIXED_TRIGGER_COMPOSE;
+            }
+            return IVibratorManager.CAP_SYNC | prepareCap | triggerCap;
+        }
+
+        /**
+         * Return true if {@code prepareCapabilities} contains this {@code capability} mixed with
+         * different ones, requiring a mixed trigger capability from the vibrator manager for
+         * syncing all effects.
+         */
+        private boolean requireMixedTriggerCapability(long prepareCapabilities, long capability) {
+            return (prepareCapabilities & capability) != 0
+                    && (prepareCapabilities & ~capability) != 0;
+        }
+    }
+}
diff --git a/services/core/java/com/android/server/vibrator/Step.java b/services/core/java/com/android/server/vibrator/Step.java
new file mode 100644
index 0000000..042e8a0
--- /dev/null
+++ b/services/core/java/com/android/server/vibrator/Step.java
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2022 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 com.android.server.vibrator;
+
+import android.annotation.NonNull;
+import android.os.CombinedVibration;
+import android.os.SystemClock;
+import android.os.VibrationEffect;
+
+import java.util.List;
+
+/**
+ * Represent a single step for playing a vibration.
+ *
+ * <p>Every step has a start time, which can be used to apply delays between steps while
+ * executing them in sequence.
+ */
+abstract class Step implements Comparable<Step> {
+    public final VibrationStepConductor conductor;
+    public final long startTime;
+
+    Step(VibrationStepConductor conductor, long startTime) {
+        this.conductor = conductor;
+        this.startTime = startTime;
+    }
+
+    protected Vibration getVibration() {
+        return conductor.getVibration();
+    }
+
+    /**
+     * Returns true if this step is a clean up step and not part of a {@link VibrationEffect} or
+     * {@link CombinedVibration}.
+     */
+    public boolean isCleanUp() {
+        return false;
+    }
+
+    /** Play this step, returning a (possibly empty) list of next steps. */
+    @NonNull
+    public abstract List<Step> play();
+
+    /**
+     * Cancel this pending step and return a (possibly empty) list of clean-up steps that should
+     * be played to gracefully cancel this step.
+     */
+    @NonNull
+    public abstract List<Step> cancel();
+
+    /** Cancel this pending step immediately, skipping any clean-up. */
+    public abstract void cancelImmediately();
+
+    /**
+     * Return the duration the vibrator was turned on when this step was played.
+     *
+     * @return A positive duration that the vibrator was turned on for by this step;
+     * Zero if the segment is not supported, the step was not played yet or vibrator was never
+     * turned on by this step; A negative value if the vibrator call has failed.
+     */
+    public long getVibratorOnDuration() {
+        return 0;
+    }
+
+    /**
+     * Return true to run this step right after a vibrator has notified vibration completed,
+     * used to resume steps waiting on vibrator callbacks with a timeout.
+     */
+    public boolean acceptVibratorCompleteCallback(int vibratorId) {
+        return false;
+    }
+
+    /**
+     * Returns the time in millis to wait before playing this step. This is performed
+     * while holding the queue lock, so should not rely on potentially slow operations.
+     */
+    public long calculateWaitTime() {
+        if (startTime == Long.MAX_VALUE) {
+            // This step don't have a predefined start time, it's just marked to be executed
+            // after all other steps have finished.
+            return 0;
+        }
+        return Math.max(0, startTime - SystemClock.uptimeMillis());
+    }
+
+    @Override
+    public int compareTo(Step o) {
+        return Long.compare(startTime, o.startTime);
+    }
+}
diff --git a/services/core/java/com/android/server/vibrator/TurnOffVibratorStep.java b/services/core/java/com/android/server/vibrator/TurnOffVibratorStep.java
new file mode 100644
index 0000000..297ef56
--- /dev/null
+++ b/services/core/java/com/android/server/vibrator/TurnOffVibratorStep.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2022 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 com.android.server.vibrator;
+
+import android.os.SystemClock;
+import android.os.Trace;
+
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * Represents a step to turn the vibrator off.
+ *
+ * <p>This runs after a timeout on the expected time the vibrator should have finished playing,
+ * and can be brought forward by vibrator complete callbacks. The step shouldn't be skipped, even
+ * if the vibrator-complete callback was received, as some implementations still rely on the
+ * "off" call to actually stop.
+ */
+final class TurnOffVibratorStep extends AbstractVibratorStep {
+
+    TurnOffVibratorStep(VibrationStepConductor conductor, long startTime,
+            VibratorController controller) {
+        super(conductor, startTime, controller, /* effect= */ null, /* index= */ -1, startTime);
+    }
+
+    @Override
+    public boolean isCleanUp() {
+        return true;
+    }
+
+    @Override
+    public List<Step> cancel() {
+        return Arrays.asList(
+                new TurnOffVibratorStep(conductor, SystemClock.uptimeMillis(), controller));
+    }
+
+    @Override
+    public void cancelImmediately() {
+        stopVibrating();
+    }
+
+    @Override
+    public List<Step> play() {
+        Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "TurnOffVibratorStep");
+        try {
+            stopVibrating();
+            return VibrationStepConductor.EMPTY_STEP_LIST;
+        } finally {
+            Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR);
+        }
+    }
+}
diff --git a/services/core/java/com/android/server/vibrator/VibrationStepConductor.java b/services/core/java/com/android/server/vibrator/VibrationStepConductor.java
new file mode 100644
index 0000000..51691fb
--- /dev/null
+++ b/services/core/java/com/android/server/vibrator/VibrationStepConductor.java
@@ -0,0 +1,355 @@
+/*
+ * Copyright (C) 2022 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 com.android.server.vibrator;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.os.CombinedVibration;
+import android.os.VibrationEffect;
+import android.os.WorkSource;
+import android.os.vibrator.PrebakedSegment;
+import android.os.vibrator.PrimitiveSegment;
+import android.os.vibrator.RampSegment;
+import android.os.vibrator.VibrationEffectSegment;
+import android.util.Slog;
+import android.util.SparseArray;
+
+import com.android.internal.annotations.GuardedBy;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.PriorityQueue;
+import java.util.Queue;
+
+/**
+ * Creates and manages a queue of steps for performing a VibrationEffect, as well as coordinating
+ * dispatch of callbacks.
+ */
+final class VibrationStepConductor {
+    /**
+     * Extra timeout added to the end of each vibration step to ensure it finishes even when
+     * vibrator callbacks are lost.
+     */
+    static final long CALLBACKS_EXTRA_TIMEOUT = 1_000;
+    /** Threshold to prevent the ramp off steps from trying to set extremely low amplitudes. */
+    static final float RAMP_OFF_AMPLITUDE_MIN = 1e-3f;
+    static final List<Step> EMPTY_STEP_LIST = new ArrayList<>();
+
+    final Object mLock = new Object();
+
+    // Used within steps.
+    public final VibrationSettings vibrationSettings;
+    public final DeviceVibrationEffectAdapter deviceEffectAdapter;
+    public final VibrationThread.VibratorManagerHooks vibratorManagerHooks;
+
+    private final WorkSource mWorkSource;
+    private final Vibration mVibration;
+    private final SparseArray<VibratorController> mVibrators = new SparseArray<>();
+
+    @GuardedBy("mLock")
+    private final PriorityQueue<Step> mNextSteps = new PriorityQueue<>();
+    @GuardedBy("mLock")
+    private final Queue<Step> mPendingOnVibratorCompleteSteps = new LinkedList<>();
+    @GuardedBy("mLock")
+    private final Queue<Integer> mCompletionNotifiedVibrators = new LinkedList<>();
+
+    @GuardedBy("mLock")
+    private int mPendingVibrateSteps;
+    @GuardedBy("mLock")
+    private int mConsumedStartVibrateSteps;
+    @GuardedBy("mLock")
+    private int mSuccessfulVibratorOnSteps;
+    @GuardedBy("mLock")
+    private boolean mWaitToProcessVibratorCompleteCallbacks;
+
+    VibrationStepConductor(Vibration vib, VibrationSettings vibrationSettings,
+            DeviceVibrationEffectAdapter effectAdapter,
+            SparseArray<VibratorController> availableVibrators,
+            VibrationThread.VibratorManagerHooks vibratorManagerHooks) {
+        this.mVibration = vib;
+        this.vibrationSettings = vibrationSettings;
+        this.deviceEffectAdapter = effectAdapter;
+        this.vibratorManagerHooks = vibratorManagerHooks;
+        this.mWorkSource = new WorkSource(mVibration.uid);
+
+        CombinedVibration effect = vib.getEffect();
+        for (int i = 0; i < availableVibrators.size(); i++) {
+            if (effect.hasVibrator(availableVibrators.keyAt(i))) {
+                mVibrators.put(availableVibrators.keyAt(i), availableVibrators.valueAt(i));
+            }
+        }
+    }
+
+    @Nullable
+    AbstractVibratorStep nextVibrateStep(long startTime, VibratorController controller,
+            VibrationEffect.Composed effect, int segmentIndex,
+            long previousStepVibratorOffTimeout) {
+        if (segmentIndex >= effect.getSegments().size()) {
+            segmentIndex = effect.getRepeatIndex();
+        }
+        if (segmentIndex < 0) {
+            // No more segments to play, last step is to complete the vibration on this vibrator.
+            return new CompleteEffectVibratorStep(this, startTime, /* cancelled= */ false,
+                    controller, previousStepVibratorOffTimeout);
+        }
+
+        VibrationEffectSegment segment = effect.getSegments().get(segmentIndex);
+        if (segment instanceof PrebakedSegment) {
+            return new PerformPrebakedVibratorStep(this, startTime, controller, effect,
+                    segmentIndex, previousStepVibratorOffTimeout);
+        }
+        if (segment instanceof PrimitiveSegment) {
+            return new ComposePrimitivesVibratorStep(this, startTime, controller, effect,
+                    segmentIndex, previousStepVibratorOffTimeout);
+        }
+        if (segment instanceof RampSegment) {
+            return new ComposePwleVibratorStep(this, startTime, controller, effect, segmentIndex,
+                    previousStepVibratorOffTimeout);
+        }
+        return new SetAmplitudeVibratorStep(this, startTime, controller, effect, segmentIndex,
+                previousStepVibratorOffTimeout);
+    }
+
+    public void initializeForEffect(@NonNull CombinedVibration.Sequential vibration) {
+        synchronized (mLock) {
+            mPendingVibrateSteps++;
+            mNextSteps.offer(new StartSequentialEffectStep(this, vibration));
+        }
+    }
+
+    public Vibration getVibration() {
+        return mVibration;
+    }
+
+    public WorkSource getWorkSource() {
+        return mWorkSource;
+    }
+
+    SparseArray<VibratorController> getVibrators() {
+        return mVibrators;
+    }
+
+    public boolean isFinished() {
+        synchronized (mLock) {
+            return mPendingOnVibratorCompleteSteps.isEmpty() && mNextSteps.isEmpty();
+        }
+    }
+
+    /**
+     * Calculate the {@link Vibration.Status} based on the current queue state and the expected
+     * number of {@link StartSequentialEffectStep} to be played.
+     */
+    public Vibration.Status calculateVibrationStatus(int expectedStartVibrateSteps) {
+        synchronized (mLock) {
+            if (mPendingVibrateSteps > 0
+                    || mConsumedStartVibrateSteps < expectedStartVibrateSteps) {
+                return Vibration.Status.RUNNING;
+            }
+            if (mSuccessfulVibratorOnSteps > 0) {
+                return Vibration.Status.FINISHED;
+            }
+            // If no step was able to turn the vibrator ON successfully.
+            return Vibration.Status.IGNORED_UNSUPPORTED;
+        }
+    }
+
+    /** Returns the time in millis to wait before calling {@link #runNextStep()}. */
+    @GuardedBy("mLock")
+    public long getWaitMillisBeforeNextStepLocked() {
+        if (!mPendingOnVibratorCompleteSteps.isEmpty()) {
+            // Steps resumed by vibrator complete callback should be played right away.
+            return 0;
+        }
+        Step nextStep = mNextSteps.peek();
+        return nextStep == null ? 0 : nextStep.calculateWaitTime();
+    }
+
+    /**
+     * Play and remove the step at the top of this queue, and also adds the next steps generated
+     * to be played next.
+     */
+    public void runNextStep() {
+        // Vibrator callbacks should wait until the polled step is played and the next steps are
+        // added back to the queue, so they can handle the callback.
+        markWaitToProcessVibratorCallbacks();
+        try {
+            Step nextStep = pollNext();
+            if (nextStep != null) {
+                // This might turn on the vibrator and have a HAL latency. Execute this outside
+                // any lock to avoid blocking other interactions with the thread.
+                List<Step> nextSteps = nextStep.play();
+                synchronized (mLock) {
+                    if (nextStep.getVibratorOnDuration() > 0) {
+                        mSuccessfulVibratorOnSteps++;
+                    }
+                    if (nextStep instanceof StartSequentialEffectStep) {
+                        mConsumedStartVibrateSteps++;
+                    }
+                    if (!nextStep.isCleanUp()) {
+                        mPendingVibrateSteps--;
+                    }
+                    for (int i = 0; i < nextSteps.size(); i++) {
+                        mPendingVibrateSteps += nextSteps.get(i).isCleanUp() ? 0 : 1;
+                    }
+                    mNextSteps.addAll(nextSteps);
+                }
+            }
+        } finally {
+            synchronized (mLock) {
+                processVibratorCompleteCallbacksLocked();
+            }
+        }
+    }
+
+    /**
+     * Notify the vibrator completion.
+     *
+     * <p>This is a lightweight method that do not trigger any operation from {@link
+     * VibratorController}, so it can be called directly from a native callback.
+     */
+    @GuardedBy("mLock")
+    private void notifyVibratorCompleteLocked(int vibratorId) {
+        mCompletionNotifiedVibrators.offer(vibratorId);
+        if (!mWaitToProcessVibratorCompleteCallbacks) {
+            // No step is being played or cancelled now, process the callback right away.
+            processVibratorCompleteCallbacksLocked();
+        }
+    }
+
+    public void notifyVibratorComplete(int vibratorId) {
+        synchronized (mLock) {
+            if (VibrationThread.DEBUG) {
+                Slog.d(VibrationThread.TAG,
+                        "Vibration complete reported by vibrator " + vibratorId);
+            }
+            notifyVibratorCompleteLocked(vibratorId);
+            mLock.notify();
+        }
+    }
+
+    public void notifySyncedVibrationComplete() {
+        synchronized (mLock) {
+            if (VibrationThread.DEBUG) {
+                Slog.d(VibrationThread.TAG,
+                        "Synced vibration complete reported by vibrator manager");
+            }
+            for (int i = 0; i < mVibrators.size(); i++) {
+                notifyVibratorCompleteLocked(mVibrators.keyAt(i));
+            }
+            mLock.notify();
+        }
+    }
+
+    /**
+     * Cancel the current queue, replacing all remaining steps with respective clean-up steps.
+     *
+     * <p>This will remove all steps and replace them with respective
+     * {@link Step#cancel()}.
+     */
+    public void cancel() {
+        // Vibrator callbacks should wait until all steps from the queue are properly cancelled
+        // and clean up steps are added back to the queue, so they can handle the callback.
+        markWaitToProcessVibratorCallbacks();
+        try {
+            List<Step> cleanUpSteps = new ArrayList<>();
+            Step step;
+            while ((step = pollNext()) != null) {
+                cleanUpSteps.addAll(step.cancel());
+            }
+            synchronized (mLock) {
+                // All steps generated by Step.cancel() should be clean-up steps.
+                mPendingVibrateSteps = 0;
+                mNextSteps.addAll(cleanUpSteps);
+            }
+        } finally {
+            synchronized (mLock) {
+                processVibratorCompleteCallbacksLocked();
+            }
+        }
+    }
+
+    /**
+     * Cancel the current queue immediately, clearing all remaining steps and skipping clean-up.
+     *
+     * <p>This will remove and trigger {@link Step#cancelImmediately()} in all steps, in order.
+     */
+    public void cancelImmediately() {
+        // Vibrator callbacks should wait until all steps from the queue are properly cancelled.
+        markWaitToProcessVibratorCallbacks();
+        try {
+            Step step;
+            while ((step = pollNext()) != null) {
+                // This might turn off the vibrator and have a HAL latency. Execute this outside
+                // any lock to avoid blocking other interactions with the thread.
+                step.cancelImmediately();
+            }
+            synchronized (mLock) {
+                mPendingVibrateSteps = 0;
+            }
+        } finally {
+            synchronized (mLock) {
+                processVibratorCompleteCallbacksLocked();
+            }
+        }
+    }
+
+    @Nullable
+    private Step pollNext() {
+        synchronized (mLock) {
+            // Prioritize the steps resumed by a vibrator complete callback.
+            if (!mPendingOnVibratorCompleteSteps.isEmpty()) {
+                return mPendingOnVibratorCompleteSteps.poll();
+            }
+            return mNextSteps.poll();
+        }
+    }
+
+    private void markWaitToProcessVibratorCallbacks() {
+        synchronized (mLock) {
+            mWaitToProcessVibratorCompleteCallbacks = true;
+        }
+    }
+
+    /**
+     * Notify the step in this queue that should be resumed by the vibrator completion
+     * callback and keep it separate to be consumed by {@link #runNextStep()}.
+     *
+     * <p>This is a lightweight method that do not trigger any operation from {@link
+     * VibratorController}, so it can be called directly from a native callback.
+     *
+     * <p>This assumes only one of the next steps is waiting on this given vibrator, so the
+     * first step found will be resumed by this method, in no particular order.
+     */
+    @GuardedBy("mLock")
+    private void processVibratorCompleteCallbacksLocked() {
+        mWaitToProcessVibratorCompleteCallbacks = false;
+        while (!mCompletionNotifiedVibrators.isEmpty()) {
+            int vibratorId = mCompletionNotifiedVibrators.poll();
+            Iterator<Step> it = mNextSteps.iterator();
+            while (it.hasNext()) {
+                Step step = it.next();
+                if (step.acceptVibratorCompleteCallback(vibratorId)) {
+                    it.remove();
+                    mPendingOnVibratorCompleteSteps.offer(step);
+                    break;
+                }
+            }
+        }
+    }
+}
diff --git a/services/core/java/com/android/server/vibrator/VibrationThread.java b/services/core/java/com/android/server/vibrator/VibrationThread.java
index 1f1f40b..1b8e4c5b 100644
--- a/services/core/java/com/android/server/vibrator/VibrationThread.java
+++ b/services/core/java/com/android/server/vibrator/VibrationThread.java
@@ -16,59 +16,23 @@
 
 package com.android.server.vibrator;
 
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.hardware.vibrator.IVibratorManager;
 import android.os.CombinedVibration;
 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.VibrationEffect;
-import android.os.VibratorInfo;
-import android.os.WorkSource;
-import android.os.vibrator.PrebakedSegment;
-import android.os.vibrator.PrimitiveSegment;
-import android.os.vibrator.RampSegment;
-import android.os.vibrator.StepSegment;
-import android.os.vibrator.VibrationEffectSegment;
 import android.util.Slog;
 import android.util.SparseArray;
 
-import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.app.IBatteryStats;
-import com.android.internal.util.FrameworkStatsLog;
 
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
 import java.util.NoSuchElementException;
-import java.util.PriorityQueue;
-import java.util.Queue;
 
 /** Plays a {@link Vibration} in dedicated thread. */
 final class VibrationThread extends Thread implements IBinder.DeathRecipient {
-    private static final String TAG = "VibrationThread";
-    private static final boolean DEBUG = false;
-
-    /**
-     * Extra timeout added to the end of each vibration step to ensure it finishes even when
-     * vibrator callbacks are lost.
-     */
-    private static final long CALLBACKS_EXTRA_TIMEOUT = 1_000;
-
-    /** Threshold to prevent the ramp off steps from trying to set extremely low amplitudes. */
-    private static final float RAMP_OFF_AMPLITUDE_MIN = 1e-3f;
-
-    /** Fixed large duration used to note repeating vibrations to {@link IBatteryStats}. */
-    private static final long BATTERY_STATS_REPEATING_VIBRATION_DURATION = 5_000;
-
-    private static final List<Step> EMPTY_STEP_LIST = new ArrayList<>();
+    static final String TAG = "VibrationThread";
+    static final boolean DEBUG = false;
 
     /** Calls into VibratorManager functionality needed for playing a {@link Vibration}. */
     interface VibratorManagerHooks {
@@ -94,6 +58,15 @@
         void cancelSyncedVibration();
 
         /**
+         * Record that a vibrator was turned on, and may remain on for the specified duration,
+         * on behalf of the given uid.
+         */
+        void noteVibratorOn(int uid, long duration);
+
+        /** Record that a vibrator was turned off, on behalf of the given uid. */
+        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}
@@ -108,16 +81,10 @@
         void onVibrationThreadReleased();
     }
 
-    private final Object mLock = new Object();
-    private final WorkSource mWorkSource;
     private final PowerManager.WakeLock mWakeLock;
-    private final IBatteryStats mBatteryStatsService;
-    private final VibrationSettings mVibrationSettings;
-    private final DeviceVibrationEffectAdapter mDeviceEffectAdapter;
-    private final Vibration mVibration;
-    private final VibratorManagerHooks mVibratorManagerHooks;
-    private final SparseArray<VibratorController> mVibrators = new SparseArray<>();
-    private final StepQueue mStepQueue = new StepQueue();
+    private final VibrationThread.VibratorManagerHooks mVibratorManagerHooks;
+
+    private final VibrationStepConductor mStepConductor;
 
     private volatile boolean mStop;
     private volatile boolean mForceStop;
@@ -127,30 +94,20 @@
     VibrationThread(Vibration vib, VibrationSettings vibrationSettings,
             DeviceVibrationEffectAdapter effectAdapter,
             SparseArray<VibratorController> availableVibrators, PowerManager.WakeLock wakeLock,
-            IBatteryStats batteryStatsService, VibratorManagerHooks vibratorManagerHooks) {
-        mVibration = vib;
-        mVibrationSettings = vibrationSettings;
-        mDeviceEffectAdapter = effectAdapter;
+            VibratorManagerHooks vibratorManagerHooks) {
         mVibratorManagerHooks = vibratorManagerHooks;
-        mWorkSource = new WorkSource(mVibration.uid);
         mWakeLock = wakeLock;
-        mBatteryStatsService = batteryStatsService;
-
-        CombinedVibration effect = vib.getEffect();
-        for (int i = 0; i < availableVibrators.size(); i++) {
-            if (effect.hasVibrator(availableVibrators.keyAt(i))) {
-                mVibrators.put(availableVibrators.keyAt(i), availableVibrators.valueAt(i));
-            }
-        }
+        mStepConductor = new VibrationStepConductor(vib, vibrationSettings, effectAdapter,
+                availableVibrators, vibratorManagerHooks);
     }
 
     Vibration getVibration() {
-        return mVibration;
+        return mStepConductor.getVibration();
     }
 
     @VisibleForTesting
     SparseArray<VibratorController> getVibrators() {
-        return mVibrators;
+        return mStepConductor.getVibrators();
     }
 
     @Override
@@ -179,7 +136,7 @@
 
     /** Runs the VibrationThread ensuring that the wake lock is acquired and released. */
     private void runWithWakeLock() {
-        mWakeLock.setWorkSource(mWorkSource);
+        mWakeLock.setWorkSource(mStepConductor.getWorkSource());
         mWakeLock.acquire();
         try {
             runWithWakeLockAndDeathLink();
@@ -193,8 +150,9 @@
      * Called from within runWithWakeLock.
      */
     private void runWithWakeLockAndDeathLink() {
+        IBinder vibrationBinderToken = mStepConductor.getVibration().token;
         try {
-            mVibration.token.linkToDeath(this, 0);
+            vibrationBinderToken.linkToDeath(this, 0);
         } catch (RemoteException e) {
             Slog.e(TAG, "Error linking vibration to token death", e);
             clientVibrationCompleteIfNotAlready(Vibration.Status.IGNORED_ERROR_TOKEN);
@@ -206,7 +164,7 @@
             playVibration();
         } finally {
             try {
-                mVibration.token.unlinkToDeath(this, 0);
+                vibrationBinderToken.unlinkToDeath(this, 0);
             } catch (NoSuchElementException e) {
                 Slog.wtf(TAG, "Failed to unlink token", e);
             }
@@ -220,11 +178,11 @@
             return;
         }
         mStop = true;
-        synchronized (mLock) {
+        synchronized (mStepConductor.mLock) {
             if (DEBUG) {
                 Slog.d(TAG, "Vibration cancelled");
             }
-            mLock.notify();
+            mStepConductor.mLock.notify();
         }
     }
 
@@ -235,36 +193,22 @@
             return;
         }
         mStop = mForceStop = true;
-        synchronized (mLock) {
+        synchronized (mStepConductor.mLock) {
             if (DEBUG) {
                 Slog.d(TAG, "Vibration cancelled immediately");
             }
-            mLock.notify();
+            mStepConductor.mLock.notify();
         }
     }
 
     /** Notify current vibration that a synced step has completed. */
     public void syncedVibrationComplete() {
-        synchronized (mLock) {
-            if (DEBUG) {
-                Slog.d(TAG, "Synced vibration complete reported by vibrator manager");
-            }
-            for (int i = 0; i < mVibrators.size(); i++) {
-                mStepQueue.notifyVibratorComplete(mVibrators.keyAt(i));
-            }
-            mLock.notify();
-        }
+        mStepConductor.notifySyncedVibrationComplete();
     }
 
     /** Notify current vibration that a step has completed on given vibrator. */
     public void vibratorComplete(int vibratorId) {
-        synchronized (mLock) {
-            if (DEBUG) {
-                Slog.d(TAG, "Vibration complete reported by vibrator " + vibratorId);
-            }
-            mStepQueue.notifyVibratorComplete(vibratorId);
-            mLock.notify();
-        }
+        mStepConductor.notifyVibratorComplete(vibratorId);
     }
 
     // Indicate that the vibration is complete. This can be called multiple times only for
@@ -273,24 +217,26 @@
     private void clientVibrationCompleteIfNotAlready(Vibration.Status completedStatus) {
         if (!mCalledVibrationCompleteCallback) {
             mCalledVibrationCompleteCallback = true;
-            mVibratorManagerHooks.onVibrationCompleted(mVibration.id, completedStatus);
+            mVibratorManagerHooks.onVibrationCompleted(
+                    mStepConductor.getVibration().id, completedStatus);
         }
     }
 
     private void playVibration() {
         Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "playVibration");
         try {
-            CombinedVibration.Sequential sequentialEffect = toSequential(mVibration.getEffect());
+            CombinedVibration.Sequential sequentialEffect =
+                    toSequential(mStepConductor.getVibration().getEffect());
             final int sequentialEffectSize = sequentialEffect.getEffects().size();
-            mStepQueue.initializeForEffect(sequentialEffect);
+            mStepConductor.initializeForEffect(sequentialEffect);
 
-            while (!mStepQueue.isFinished()) {
+            while (!mStepConductor.isFinished()) {
                 long waitMillisBeforeNextStep;
-                synchronized (mLock) {
-                    waitMillisBeforeNextStep = mStepQueue.getWaitMillisBeforeNextStep();
+                synchronized (mStepConductor.mLock) {
+                    waitMillisBeforeNextStep = mStepConductor.getWaitMillisBeforeNextStepLocked();
                     if (waitMillisBeforeNextStep > 0) {
                         try {
-                            mLock.wait(waitMillisBeforeNextStep);
+                            mStepConductor.mLock.wait(waitMillisBeforeNextStep);
                         } catch (InterruptedException e) {
                         }
                     }
@@ -304,21 +250,21 @@
                     }
                     // Run the step without holding the main lock, to avoid HAL interactions from
                     // blocking the thread.
-                    mStepQueue.runNextStep();
+                    mStepConductor.runNextStep();
                 }
                 Vibration.Status status = mStop ? Vibration.Status.CANCELLED
-                        : mStepQueue.calculateVibrationStatus(sequentialEffectSize);
+                        : mStepConductor.calculateVibrationStatus(sequentialEffectSize);
                 if (status != Vibration.Status.RUNNING && !mCalledVibrationCompleteCallback) {
                     // First time vibration stopped running, start clean-up tasks and notify
                     // callback immediately.
                     clientVibrationCompleteIfNotAlready(status);
                     if (status == Vibration.Status.CANCELLED) {
-                        mStepQueue.cancel();
+                        mStepConductor.cancel();
                     }
                 }
                 if (mForceStop) {
                     // Cancel every step and stop playing them right away, even clean-up steps.
-                    mStepQueue.cancelImmediately();
+                    mStepConductor.cancelImmediately();
                     clientVibrationCompleteIfNotAlready(Vibration.Status.CANCELLED);
                     break;
                 }
@@ -328,61 +274,6 @@
         }
     }
 
-    private void noteVibratorOn(long duration) {
-        try {
-            if (duration <= 0) {
-                return;
-            }
-            if (duration == Long.MAX_VALUE) {
-                // Repeating duration has started. Report a fixed duration here, noteVibratorOff
-                // should be called when this is cancelled.
-                duration = BATTERY_STATS_REPEATING_VIBRATION_DURATION;
-            }
-            mBatteryStatsService.noteVibratorOn(mVibration.uid, duration);
-            FrameworkStatsLog.write_non_chained(FrameworkStatsLog.VIBRATOR_STATE_CHANGED,
-                    mVibration.uid, null, FrameworkStatsLog.VIBRATOR_STATE_CHANGED__STATE__ON,
-                    duration);
-        } catch (RemoteException e) {
-        }
-    }
-
-    private void noteVibratorOff() {
-        try {
-            mBatteryStatsService.noteVibratorOff(mVibration.uid);
-            FrameworkStatsLog.write_non_chained(FrameworkStatsLog.VIBRATOR_STATE_CHANGED,
-                    mVibration.uid, null, FrameworkStatsLog.VIBRATOR_STATE_CHANGED__STATE__OFF,
-                    /* duration= */ 0);
-        } catch (RemoteException e) {
-        }
-    }
-
-    @Nullable
-    private SingleVibratorStep nextVibrateStep(long startTime, VibratorController controller,
-            VibrationEffect.Composed effect, int segmentIndex, long vibratorOffTimeout) {
-        if (segmentIndex >= effect.getSegments().size()) {
-            segmentIndex = effect.getRepeatIndex();
-        }
-        if (segmentIndex < 0) {
-            // No more segments to play, last step is to complete the vibration on this vibrator.
-            return new EffectCompleteStep(startTime, /* cancelled= */ false, controller,
-                    vibratorOffTimeout);
-        }
-
-        VibrationEffectSegment segment = effect.getSegments().get(segmentIndex);
-        if (segment instanceof PrebakedSegment) {
-            return new PerformStep(startTime, controller, effect, segmentIndex, vibratorOffTimeout);
-        }
-        if (segment instanceof PrimitiveSegment) {
-            return new ComposePrimitivesStep(startTime, controller, effect, segmentIndex,
-                    vibratorOffTimeout);
-        }
-        if (segment instanceof RampSegment) {
-            return new ComposePwleStep(startTime, controller, effect, segmentIndex,
-                    vibratorOffTimeout);
-        }
-        return new AmplitudeStep(startTime, controller, effect, segmentIndex, vibratorOffTimeout);
-    }
-
     private static CombinedVibration.Sequential toSequential(CombinedVibration effect) {
         if (effect instanceof CombinedVibration.Sequential) {
             return (CombinedVibration.Sequential) effect;
@@ -392,1268 +283,4 @@
                 .combine();
     }
 
-    /** Queue for {@link Step Steps}, sorted by their start time. */
-    private final class StepQueue {
-        @GuardedBy("mLock")
-        private final PriorityQueue<Step> mNextSteps = new PriorityQueue<>();
-        @GuardedBy("mLock")
-        private final Queue<Step> mPendingOnVibratorCompleteSteps = new LinkedList<>();
-        @GuardedBy("mLock")
-        private final Queue<Integer> mCompletionNotifiedVibrators = new LinkedList<>();
-
-        @GuardedBy("mLock")
-        private int mPendingVibrateSteps;
-        @GuardedBy("mLock")
-        private int mConsumedStartVibrateSteps;
-        @GuardedBy("mLock")
-        private int mSuccessfulVibratorOnSteps;
-        @GuardedBy("mLock")
-        private boolean mWaitToProcessVibratorCompleteCallbacks;
-
-        public void initializeForEffect(@NonNull CombinedVibration.Sequential vibration) {
-            synchronized (mLock) {
-                mPendingVibrateSteps++;
-                mNextSteps.offer(new StartVibrateStep(vibration));
-            }
-        }
-
-        public boolean isFinished() {
-            synchronized (mLock) {
-                return mPendingOnVibratorCompleteSteps.isEmpty() && mNextSteps.isEmpty();
-            }
-        }
-
-        /**
-         * Calculate the {@link Vibration.Status} based on the current queue state and the expected
-         * number of {@link StartVibrateStep} to be played.
-         */
-        public Vibration.Status calculateVibrationStatus(int expectedStartVibrateSteps) {
-            synchronized (mLock) {
-                if (mPendingVibrateSteps > 0
-                        || mConsumedStartVibrateSteps < expectedStartVibrateSteps) {
-                    return Vibration.Status.RUNNING;
-                }
-                if (mSuccessfulVibratorOnSteps > 0) {
-                    return Vibration.Status.FINISHED;
-                }
-                // If no step was able to turn the vibrator ON successfully.
-                return Vibration.Status.IGNORED_UNSUPPORTED;
-            }
-        }
-
-        /** Returns the time in millis to wait before calling {@link #runNextStep()}. */
-        @GuardedBy("VibrationThread.this.mLock")
-        public long getWaitMillisBeforeNextStep() {
-            if (!mPendingOnVibratorCompleteSteps.isEmpty()) {
-                // Steps resumed by vibrator complete callback should be played right away.
-                return 0;
-            }
-            Step nextStep = mNextSteps.peek();
-            return nextStep == null ? 0 : nextStep.calculateWaitTime();
-        }
-
-        /**
-         * Play and remove the step at the top of this queue, and also adds the next steps generated
-         * to be played next.
-         */
-        public void runNextStep() {
-            // Vibrator callbacks should wait until the polled step is played and the next steps are
-            // added back to the queue, so they can handle the callback.
-            markWaitToProcessVibratorCallbacks();
-            try {
-                Step nextStep = pollNext();
-                if (nextStep != null) {
-                    // This might turn on the vibrator and have a HAL latency. Execute this outside
-                    // any lock to avoid blocking other interactions with the thread.
-                    List<Step> nextSteps = nextStep.play();
-                    synchronized (mLock) {
-                        if (nextStep.getVibratorOnDuration() > 0) {
-                            mSuccessfulVibratorOnSteps++;
-                        }
-                        if (nextStep instanceof StartVibrateStep) {
-                            mConsumedStartVibrateSteps++;
-                        }
-                        if (!nextStep.isCleanUp()) {
-                            mPendingVibrateSteps--;
-                        }
-                        for (int i = 0; i < nextSteps.size(); i++) {
-                            mPendingVibrateSteps += nextSteps.get(i).isCleanUp() ? 0 : 1;
-                        }
-                        mNextSteps.addAll(nextSteps);
-                    }
-                }
-            } finally {
-                synchronized (mLock) {
-                    processVibratorCompleteCallbacks();
-                }
-            }
-        }
-
-        /**
-         * Notify the vibrator completion.
-         *
-         * <p>This is a lightweight method that do not trigger any operation from {@link
-         * VibratorController}, so it can be called directly from a native callback.
-         */
-        @GuardedBy("mLock")
-        public void notifyVibratorComplete(int vibratorId) {
-            mCompletionNotifiedVibrators.offer(vibratorId);
-            if (!mWaitToProcessVibratorCompleteCallbacks) {
-                // No step is being played or cancelled now, process the callback right away.
-                processVibratorCompleteCallbacks();
-            }
-        }
-
-        /**
-         * Cancel the current queue, replacing all remaining steps with respective clean-up steps.
-         *
-         * <p>This will remove all steps and replace them with respective
-         * {@link Step#cancel()}.
-         */
-        public void cancel() {
-            // Vibrator callbacks should wait until all steps from the queue are properly cancelled
-            // and clean up steps are added back to the queue, so they can handle the callback.
-            markWaitToProcessVibratorCallbacks();
-            try {
-                List<Step> cleanUpSteps = new ArrayList<>();
-                Step step;
-                while ((step = pollNext()) != null) {
-                    cleanUpSteps.addAll(step.cancel());
-                }
-                synchronized (mLock) {
-                    // All steps generated by Step.cancel() should be clean-up steps.
-                    mPendingVibrateSteps = 0;
-                    mNextSteps.addAll(cleanUpSteps);
-                }
-            } finally {
-                synchronized (mLock) {
-                    processVibratorCompleteCallbacks();
-                }
-            }
-        }
-
-        /**
-         * Cancel the current queue immediately, clearing all remaining steps and skipping clean-up.
-         *
-         * <p>This will remove and trigger {@link Step#cancelImmediately()} in all steps, in order.
-         */
-        public void cancelImmediately() {
-            // Vibrator callbacks should wait until all steps from the queue are properly cancelled.
-            markWaitToProcessVibratorCallbacks();
-            try {
-                Step step;
-                while ((step = pollNext()) != null) {
-                    // This might turn off the vibrator and have a HAL latency. Execute this outside
-                    // any lock to avoid blocking other interactions with the thread.
-                    step.cancelImmediately();
-                }
-                synchronized (mLock) {
-                    mPendingVibrateSteps = 0;
-                }
-            } finally {
-                synchronized (mLock) {
-                    processVibratorCompleteCallbacks();
-                }
-            }
-        }
-
-        @Nullable
-        private Step pollNext() {
-            synchronized (mLock) {
-                // Prioritize the steps resumed by a vibrator complete callback.
-                if (!mPendingOnVibratorCompleteSteps.isEmpty()) {
-                    return mPendingOnVibratorCompleteSteps.poll();
-                }
-                return mNextSteps.poll();
-            }
-        }
-
-        private void markWaitToProcessVibratorCallbacks() {
-            synchronized (mLock) {
-                mWaitToProcessVibratorCompleteCallbacks = true;
-            }
-        }
-
-        /**
-         * Notify the step in this queue that should be resumed by the vibrator completion
-         * callback and keep it separate to be consumed by {@link #runNextStep()}.
-         *
-         * <p>This is a lightweight method that do not trigger any operation from {@link
-         * VibratorController}, so it can be called directly from a native callback.
-         *
-         * <p>This assumes only one of the next steps is waiting on this given vibrator, so the
-         * first step found will be resumed by this method, in no particular order.
-         */
-        @GuardedBy("mLock")
-        private void processVibratorCompleteCallbacks() {
-            mWaitToProcessVibratorCompleteCallbacks = false;
-            while (!mCompletionNotifiedVibrators.isEmpty()) {
-                int vibratorId = mCompletionNotifiedVibrators.poll();
-                Iterator<Step> it = mNextSteps.iterator();
-                while (it.hasNext()) {
-                    Step step = it.next();
-                    if (step.acceptVibratorCompleteCallback(vibratorId)) {
-                        it.remove();
-                        mPendingOnVibratorCompleteSteps.offer(step);
-                        break;
-                    }
-                }
-            }
-        }
-    }
-
-    /**
-     * Represent a single step for playing a vibration.
-     *
-     * <p>Every step has a start time, which can be used to apply delays between steps while
-     * executing them in sequence.
-     */
-    private abstract class Step implements Comparable<Step> {
-        public final long startTime;
-
-        Step(long startTime) {
-            this.startTime = startTime;
-        }
-
-        /**
-         * Returns true if this step is a clean up step and not part of a {@link VibrationEffect} or
-         * {@link CombinedVibration}.
-         */
-        public boolean isCleanUp() {
-            return false;
-        }
-
-        /** Play this step, returning a (possibly empty) list of next steps. */
-        @NonNull
-        public abstract List<Step> play();
-
-        /**
-         * Cancel this pending step and return a (possibly empty) list of clean-up steps that should
-         * be played to gracefully cancel this step.
-         */
-        @NonNull
-        public abstract List<Step> cancel();
-
-        /** Cancel this pending step immediately, skipping any clean-up. */
-        public abstract void cancelImmediately();
-
-        /**
-         * Return the duration the vibrator was turned on when this step was played.
-         *
-         * @return A positive duration that the vibrator was turned on for by this step;
-         * Zero if the segment is not supported, the step was not played yet or vibrator was never
-         * turned on by this step; A negative value if the vibrator call has failed.
-         */
-        public long getVibratorOnDuration() {
-            return 0;
-        }
-
-        /**
-         * Return true to run this step right after a vibrator has notified vibration completed,
-         * used to resume steps waiting on vibrator callbacks with a timeout.
-         */
-        public boolean acceptVibratorCompleteCallback(int vibratorId) {
-            return false;
-        }
-
-        /**
-         * Returns the time in millis to wait before playing this step. This is performed
-         * while holding the queue lock, so should not rely on potentially slow operations.
-         */
-        public long calculateWaitTime() {
-            if (startTime == Long.MAX_VALUE) {
-                // This step don't have a predefined start time, it's just marked to be executed
-                // after all other steps have finished.
-                return 0;
-            }
-            return Math.max(0, startTime - SystemClock.uptimeMillis());
-        }
-
-        @Override
-        public int compareTo(Step o) {
-            return Long.compare(startTime, o.startTime);
-        }
-    }
-
-    /**
-     * Starts a sync vibration.
-     *
-     * <p>If this step has successfully started playing a vibration on any vibrator, it will always
-     * add a {@link FinishVibrateStep} to the queue, to be played after all vibrators have finished
-     * all their individual steps.
-     *
-     * <p>If this step does not start any vibrator, it will add a {@link StartVibrateStep} if the
-     * sequential effect isn't finished yet.
-     */
-    private final class StartVibrateStep extends Step {
-        public final CombinedVibration.Sequential sequentialEffect;
-        public final int currentIndex;
-
-        private long mVibratorsOnMaxDuration;
-
-        StartVibrateStep(CombinedVibration.Sequential effect) {
-            this(SystemClock.uptimeMillis() + effect.getDelays().get(0), effect, /* index= */ 0);
-        }
-
-        StartVibrateStep(long startTime, CombinedVibration.Sequential effect, int index) {
-            super(startTime);
-            sequentialEffect = effect;
-            currentIndex = index;
-        }
-
-        @Override
-        public long getVibratorOnDuration() {
-            return mVibratorsOnMaxDuration;
-        }
-
-        @Override
-        public List<Step> play() {
-            Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "StartVibrateStep");
-            List<Step> nextSteps = new ArrayList<>();
-            mVibratorsOnMaxDuration = -1;
-            try {
-                if (DEBUG) {
-                    Slog.d(TAG, "StartVibrateStep for effect #" + currentIndex);
-                }
-                CombinedVibration effect = sequentialEffect.getEffects().get(currentIndex);
-                DeviceEffectMap effectMapping = createEffectToVibratorMapping(effect);
-                if (effectMapping == null) {
-                    // Unable to map effects to vibrators, ignore this step.
-                    return nextSteps;
-                }
-
-                mVibratorsOnMaxDuration = startVibrating(effectMapping, nextSteps);
-                noteVibratorOn(mVibratorsOnMaxDuration);
-            } finally {
-                if (mVibratorsOnMaxDuration >= 0) {
-                    // It least one vibrator was started then add a finish step to wait for all
-                    // active vibrators to finish their individual steps before going to the next.
-                    // Otherwise this step was ignored so just go to the next one.
-                    Step nextStep =
-                            mVibratorsOnMaxDuration > 0 ? new FinishVibrateStep(this) : nextStep();
-                    if (nextStep != null) {
-                        nextSteps.add(nextStep);
-                    }
-                }
-                Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR);
-            }
-            return nextSteps;
-        }
-
-        @Override
-        public List<Step> cancel() {
-            return EMPTY_STEP_LIST;
-        }
-
-        @Override
-        public void cancelImmediately() {
-        }
-
-        /**
-         * Create the next {@link StartVibrateStep} to play this sequential effect, starting at the
-         * time this method is called, or null if sequence is complete.
-         */
-        @Nullable
-        private Step nextStep() {
-            int nextIndex = currentIndex + 1;
-            if (nextIndex >= sequentialEffect.getEffects().size()) {
-                return null;
-            }
-            long nextEffectDelay = sequentialEffect.getDelays().get(nextIndex);
-            long nextStartTime = SystemClock.uptimeMillis() + nextEffectDelay;
-            return new StartVibrateStep(nextStartTime, sequentialEffect, nextIndex);
-        }
-
-        /** Create a mapping of individual {@link VibrationEffect} to available vibrators. */
-        @Nullable
-        private DeviceEffectMap createEffectToVibratorMapping(
-                CombinedVibration effect) {
-            if (effect instanceof CombinedVibration.Mono) {
-                return new DeviceEffectMap((CombinedVibration.Mono) effect);
-            }
-            if (effect instanceof CombinedVibration.Stereo) {
-                return new DeviceEffectMap((CombinedVibration.Stereo) effect);
-            }
-            return null;
-        }
-
-        /**
-         * Starts playing effects on designated vibrators, in sync.
-         *
-         * @param effectMapping The {@link CombinedVibration} mapped to this device vibrators
-         * @param nextSteps     An output list to accumulate the future {@link Step Steps} created
-         *                      by this method, typically one for each vibrator that has
-         *                      successfully started vibrating on this step.
-         * @return The duration, in millis, of the {@link CombinedVibration}. Repeating
-         * waveforms return {@link Long#MAX_VALUE}. Zero or negative values indicate the vibrators
-         * have ignored all effects.
-         */
-        private long startVibrating(DeviceEffectMap effectMapping, List<Step> nextSteps) {
-            int vibratorCount = effectMapping.size();
-            if (vibratorCount == 0) {
-                // No effect was mapped to any available vibrator.
-                return 0;
-            }
-
-            SingleVibratorStep[] steps = new SingleVibratorStep[vibratorCount];
-            long vibrationStartTime = SystemClock.uptimeMillis();
-            for (int i = 0; i < vibratorCount; i++) {
-                steps[i] = nextVibrateStep(vibrationStartTime,
-                        mVibrators.get(effectMapping.vibratorIdAt(i)),
-                        effectMapping.effectAt(i),
-                        /* segmentIndex= */ 0, /* vibratorOffTimeout= */ 0);
-            }
-
-            if (steps.length == 1) {
-                // No need to prepare and trigger sync effects on a single vibrator.
-                return startVibrating(steps[0], nextSteps);
-            }
-
-            // This synchronization of vibrators should be executed one at a time, even if we are
-            // vibrating different sets of vibrators in parallel. The manager can only prepareSynced
-            // one set of vibrators at a time.
-            synchronized (mLock) {
-                boolean hasPrepared = false;
-                boolean hasTriggered = false;
-                long maxDuration = 0;
-                try {
-                    hasPrepared = mVibratorManagerHooks.prepareSyncedVibration(
-                            effectMapping.getRequiredSyncCapabilities(),
-                            effectMapping.getVibratorIds());
-
-                    for (SingleVibratorStep step : steps) {
-                        long duration = startVibrating(step, nextSteps);
-                        if (duration < 0) {
-                            // One vibrator has failed, fail this entire sync attempt.
-                            return maxDuration = -1;
-                        }
-                        maxDuration = Math.max(maxDuration, duration);
-                    }
-
-                    // Check if sync was prepared and if any step was accepted by a vibrator,
-                    // otherwise there is nothing to trigger here.
-                    if (hasPrepared && maxDuration > 0) {
-                        hasTriggered = mVibratorManagerHooks.triggerSyncedVibration(mVibration.id);
-                    }
-                    return maxDuration;
-                } finally {
-                    if (hasPrepared && !hasTriggered) {
-                        // Trigger has failed or all steps were ignored by the vibrators.
-                        mVibratorManagerHooks.cancelSyncedVibration();
-                        nextSteps.clear();
-                    } else if (maxDuration < 0) {
-                        // Some vibrator failed without being prepared so other vibrators might be
-                        // active. Cancel and remove every pending step from output list.
-                        for (int i = nextSteps.size() - 1; i >= 0; i--) {
-                            nextSteps.remove(i).cancelImmediately();
-                        }
-                    }
-                }
-            }
-        }
-
-        private long startVibrating(SingleVibratorStep step, List<Step> nextSteps) {
-            nextSteps.addAll(step.play());
-            long stepDuration = step.getVibratorOnDuration();
-            if (stepDuration < 0) {
-                // Step failed, so return negative duration to propagate failure.
-                return stepDuration;
-            }
-            // Return the longest estimation for the entire effect.
-            return Math.max(stepDuration, step.effect.getDuration());
-        }
-    }
-
-    /**
-     * Finish a sync vibration started by a {@link StartVibrateStep}.
-     *
-     * <p>This only plays after all active vibrators steps have finished, and adds a {@link
-     * StartVibrateStep} to the queue if the sequential effect isn't finished yet.
-     */
-    private final class FinishVibrateStep extends Step {
-        public final StartVibrateStep startedStep;
-
-        FinishVibrateStep(StartVibrateStep startedStep) {
-            super(Long.MAX_VALUE); // No predefined startTime, just wait for all steps in the queue.
-            this.startedStep = startedStep;
-        }
-
-        @Override
-        public boolean isCleanUp() {
-            // This step only notes that all the vibrators has been turned off.
-            return true;
-        }
-
-        @Override
-        public List<Step> play() {
-            Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "FinishVibrateStep");
-            try {
-                if (DEBUG) {
-                    Slog.d(TAG, "FinishVibrateStep for effect #" + startedStep.currentIndex);
-                }
-                noteVibratorOff();
-                Step nextStep = startedStep.nextStep();
-                return nextStep == null ? EMPTY_STEP_LIST : Arrays.asList(nextStep);
-            } finally {
-                Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR);
-            }
-        }
-
-        @Override
-        public List<Step> cancel() {
-            cancelImmediately();
-            return EMPTY_STEP_LIST;
-        }
-
-        @Override
-        public void cancelImmediately() {
-            noteVibratorOff();
-        }
-    }
-
-    /**
-     * Represent a step on a single vibrator that plays one or more segments from a
-     * {@link VibrationEffect.Composed} effect.
-     */
-    private abstract class SingleVibratorStep extends Step {
-        public final VibratorController controller;
-        public final VibrationEffect.Composed effect;
-        public final int segmentIndex;
-        public final long vibratorOffTimeout;
-
-        long mVibratorOnResult;
-        boolean mVibratorCompleteCallbackReceived;
-
-        /**
-         * @param startTime          The time to schedule this step in the {@link StepQueue}.
-         * @param controller         The vibrator that is playing the effect.
-         * @param effect             The effect being played in this step.
-         * @param index              The index of the next segment to be played by this step
-         * @param vibratorOffTimeout The time the vibrator is expected to complete any previous
-         *                           vibration and turn off. This is used to allow this step to be
-         *                           triggered when the completion callback is received, and can
-         *                           be used play effects back-to-back.
-         */
-        SingleVibratorStep(long startTime, VibratorController controller,
-                VibrationEffect.Composed effect, int index, long vibratorOffTimeout) {
-            super(startTime);
-            this.controller = controller;
-            this.effect = effect;
-            this.segmentIndex = index;
-            this.vibratorOffTimeout = vibratorOffTimeout;
-        }
-
-        @Override
-        public long getVibratorOnDuration() {
-            return mVibratorOnResult;
-        }
-
-        @Override
-        public boolean acceptVibratorCompleteCallback(int vibratorId) {
-            boolean isSameVibrator = controller.getVibratorInfo().getId() == vibratorId;
-            mVibratorCompleteCallbackReceived |= isSameVibrator;
-            // Only activate this step if a timeout was set to wait for the vibration to complete,
-            // otherwise we are waiting for the correct time to play the next step.
-            return isSameVibrator && (vibratorOffTimeout > SystemClock.uptimeMillis());
-        }
-
-        @Override
-        public List<Step> cancel() {
-            return Arrays.asList(new EffectCompleteStep(SystemClock.uptimeMillis(),
-                    /* cancelled= */ true, controller, vibratorOffTimeout));
-        }
-
-        @Override
-        public void cancelImmediately() {
-            if (vibratorOffTimeout > SystemClock.uptimeMillis()) {
-                // Vibrator might be running from previous steps, so turn it off while canceling.
-                stopVibrating();
-            }
-        }
-
-        void stopVibrating() {
-            if (DEBUG) {
-                Slog.d(TAG, "Turning off vibrator " + controller.getVibratorInfo().getId());
-            }
-            controller.off();
-        }
-
-        void changeAmplitude(float amplitude) {
-            if (DEBUG) {
-                Slog.d(TAG, "Amplitude changed on vibrator " + controller.getVibratorInfo().getId()
-                        + " to " + amplitude);
-            }
-            controller.setAmplitude(amplitude);
-        }
-
-        /** Return the {@link #nextVibrateStep} with same timings, only jumping the segments. */
-        public List<Step> skipToNextSteps(int segmentsSkipped) {
-            return nextSteps(startTime, vibratorOffTimeout, segmentsSkipped);
-        }
-
-        /**
-         * Return the {@link #nextVibrateStep} with same start and off timings calculated from
-         * {@link #getVibratorOnDuration()}, jumping all played segments.
-         *
-         * <p>This method has same behavior as {@link #skipToNextSteps(int)} when the vibrator
-         * result is non-positive, meaning the vibrator has either ignored or failed to turn on.
-         */
-        public List<Step> nextSteps(int segmentsPlayed) {
-            if (mVibratorOnResult <= 0) {
-                // Vibration was not started, so just skip the played segments and keep timings.
-                return skipToNextSteps(segmentsPlayed);
-            }
-            long nextStartTime = SystemClock.uptimeMillis() + mVibratorOnResult;
-            long nextVibratorOffTimeout = nextStartTime + CALLBACKS_EXTRA_TIMEOUT;
-            return nextSteps(nextStartTime, nextVibratorOffTimeout, segmentsPlayed);
-        }
-
-        /**
-         * Return the {@link #nextVibrateStep} with given start and off timings, which might be
-         * calculated independently, jumping all played segments.
-         *
-         * <p>This should be used when the vibrator on/off state is not responsible for the steps
-         * execution timings, e.g. while playing the vibrator amplitudes.
-         */
-        public List<Step> nextSteps(long nextStartTime, long vibratorOffTimeout,
-                int segmentsPlayed) {
-            Step nextStep = nextVibrateStep(nextStartTime, controller, effect,
-                    segmentIndex + segmentsPlayed, vibratorOffTimeout);
-            return nextStep == null ? EMPTY_STEP_LIST : Arrays.asList(nextStep);
-        }
-    }
-
-    /**
-     * Represent a step turn the vibrator on with a single prebaked effect.
-     *
-     * <p>This step automatically falls back by replacing the prebaked segment with
-     * {@link VibrationSettings#getFallbackEffect(int)}, if available.
-     */
-    private final class PerformStep extends SingleVibratorStep {
-
-        PerformStep(long startTime, VibratorController controller,
-                VibrationEffect.Composed effect, int index, long vibratorOffTimeout) {
-            // This step should wait for the last vibration to finish (with the timeout) and for the
-            // intended step start time (to respect the effect delays).
-            super(Math.max(startTime, vibratorOffTimeout), controller, effect, index,
-                    vibratorOffTimeout);
-        }
-
-        @Override
-        public List<Step> play() {
-            Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "PerformStep");
-            try {
-                VibrationEffectSegment segment = effect.getSegments().get(segmentIndex);
-                if (!(segment instanceof PrebakedSegment)) {
-                    Slog.w(TAG, "Ignoring wrong segment for a PerformStep: " + segment);
-                    return skipToNextSteps(/* segmentsSkipped= */ 1);
-                }
-
-                PrebakedSegment prebaked = (PrebakedSegment) segment;
-                if (DEBUG) {
-                    Slog.d(TAG, "Perform " + VibrationEffect.effectIdToString(
-                            prebaked.getEffectId()) + " on vibrator "
-                            + controller.getVibratorInfo().getId());
-                }
-
-                VibrationEffect fallback = mVibration.getFallback(prebaked.getEffectId());
-                mVibratorOnResult = controller.on(prebaked, mVibration.id);
-
-                if (mVibratorOnResult == 0 && prebaked.shouldFallback()
-                        && (fallback instanceof VibrationEffect.Composed)) {
-                    if (DEBUG) {
-                        Slog.d(TAG, "Playing fallback for effect "
-                                + VibrationEffect.effectIdToString(prebaked.getEffectId()));
-                    }
-                    SingleVibratorStep fallbackStep = nextVibrateStep(startTime, controller,
-                            replaceCurrentSegment((VibrationEffect.Composed) fallback),
-                            segmentIndex, vibratorOffTimeout);
-                    List<Step> fallbackResult = fallbackStep.play();
-                    // Update the result with the fallback result so this step is seamlessly
-                    // replaced by the fallback to any outer application of this.
-                    mVibratorOnResult = fallbackStep.getVibratorOnDuration();
-                    return fallbackResult;
-                }
-
-                return nextSteps(/* segmentsPlayed= */ 1);
-            } finally {
-                Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR);
-            }
-        }
-
-        /**
-         * Replace segment at {@link #segmentIndex} in {@link #effect} with given fallback segments.
-         *
-         * @return a copy of {@link #effect} with replaced segment.
-         */
-        private VibrationEffect.Composed replaceCurrentSegment(VibrationEffect.Composed fallback) {
-            List<VibrationEffectSegment> newSegments = new ArrayList<>(effect.getSegments());
-            int newRepeatIndex = effect.getRepeatIndex();
-            newSegments.remove(segmentIndex);
-            newSegments.addAll(segmentIndex, fallback.getSegments());
-            if (segmentIndex < effect.getRepeatIndex()) {
-                newRepeatIndex += fallback.getSegments().size() - 1;
-            }
-            return new VibrationEffect.Composed(newSegments, newRepeatIndex);
-        }
-    }
-
-    /**
-     * Represent a step turn the vibrator on using a composition of primitives.
-     *
-     * <p>This step will use the maximum supported number of consecutive segments of type
-     * {@link PrimitiveSegment} starting at the current index.
-     */
-    private final class ComposePrimitivesStep extends SingleVibratorStep {
-
-        ComposePrimitivesStep(long startTime, VibratorController controller,
-                VibrationEffect.Composed effect, int index, long vibratorOffTimeout) {
-            // This step should wait for the last vibration to finish (with the timeout) and for the
-            // intended step start time (to respect the effect delays).
-            super(Math.max(startTime, vibratorOffTimeout), controller, effect, index,
-                    vibratorOffTimeout);
-        }
-
-        @Override
-        public List<Step> play() {
-            Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "ComposePrimitivesStep");
-            try {
-                // Load the next PrimitiveSegments to create a single compose call to the vibrator,
-                // limited to the vibrator composition maximum size.
-                int limit = controller.getVibratorInfo().getCompositionSizeMax();
-                int segmentCount = limit > 0
-                        ? Math.min(effect.getSegments().size(), segmentIndex + limit)
-                        : effect.getSegments().size();
-                List<PrimitiveSegment> primitives = new ArrayList<>();
-                for (int i = segmentIndex; i < segmentCount; i++) {
-                    VibrationEffectSegment segment = effect.getSegments().get(i);
-                    if (segment instanceof PrimitiveSegment) {
-                        primitives.add((PrimitiveSegment) segment);
-                    } else {
-                        break;
-                    }
-                }
-
-                if (primitives.isEmpty()) {
-                    Slog.w(TAG, "Ignoring wrong segment for a ComposePrimitivesStep: "
-                            + effect.getSegments().get(segmentIndex));
-                    return skipToNextSteps(/* segmentsSkipped= */ 1);
-                }
-
-                if (DEBUG) {
-                    Slog.d(TAG, "Compose " + primitives + " primitives on vibrator "
-                            + controller.getVibratorInfo().getId());
-                }
-                mVibratorOnResult = controller.on(
-                        primitives.toArray(new PrimitiveSegment[primitives.size()]),
-                        mVibration.id);
-
-                return nextSteps(/* segmentsPlayed= */ primitives.size());
-            } finally {
-                Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR);
-            }
-        }
-    }
-
-    /**
-     * Represent a step turn the vibrator on using a composition of PWLE segments.
-     *
-     * <p>This step will use the maximum supported number of consecutive segments of type
-     * {@link StepSegment} or {@link RampSegment} starting at the current index.
-     */
-    private final class ComposePwleStep extends SingleVibratorStep {
-
-        ComposePwleStep(long startTime, VibratorController controller,
-                VibrationEffect.Composed effect, int index, long vibratorOffTimeout) {
-            // This step should wait for the last vibration to finish (with the timeout) and for the
-            // intended step start time (to respect the effect delays).
-            super(Math.max(startTime, vibratorOffTimeout), controller, effect, index,
-                    vibratorOffTimeout);
-        }
-
-        @Override
-        public List<Step> play() {
-            Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "ComposePwleStep");
-            try {
-                // Load the next RampSegments to create a single composePwle call to the vibrator,
-                // limited to the vibrator PWLE maximum size.
-                int limit = controller.getVibratorInfo().getPwleSizeMax();
-                int segmentCount = limit > 0
-                        ? Math.min(effect.getSegments().size(), segmentIndex + limit)
-                        : effect.getSegments().size();
-                List<RampSegment> pwles = new ArrayList<>();
-                for (int i = segmentIndex; i < segmentCount; i++) {
-                    VibrationEffectSegment segment = effect.getSegments().get(i);
-                    if (segment instanceof RampSegment) {
-                        pwles.add((RampSegment) segment);
-                    } else {
-                        break;
-                    }
-                }
-
-                if (pwles.isEmpty()) {
-                    Slog.w(TAG, "Ignoring wrong segment for a ComposePwleStep: "
-                            + effect.getSegments().get(segmentIndex));
-                    return skipToNextSteps(/* segmentsSkipped= */ 1);
-                }
-
-                if (DEBUG) {
-                    Slog.d(TAG, "Compose " + pwles + " PWLEs on vibrator "
-                            + controller.getVibratorInfo().getId());
-                }
-                mVibratorOnResult = controller.on(pwles.toArray(new RampSegment[pwles.size()]),
-                        mVibration.id);
-
-                return nextSteps(/* segmentsPlayed= */ pwles.size());
-            } finally {
-                Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR);
-            }
-        }
-    }
-
-    /**
-     * Represents a step to complete a {@link VibrationEffect}.
-     *
-     * <p>This runs right at the time the vibration is considered to end and will update the pending
-     * vibrators count. This can turn off the vibrator or slowly ramp it down to zero amplitude.
-     */
-    private final class EffectCompleteStep extends SingleVibratorStep {
-        private final boolean mCancelled;
-
-        EffectCompleteStep(long startTime, boolean cancelled, VibratorController controller,
-                long vibratorOffTimeout) {
-            super(startTime, controller, /* effect= */ null, /* index= */ -1, vibratorOffTimeout);
-            mCancelled = cancelled;
-        }
-
-        @Override
-        public boolean isCleanUp() {
-            // If the vibration was cancelled then this is just a clean up to ramp off the vibrator.
-            // Otherwise this step is part of the vibration.
-            return mCancelled;
-        }
-
-        @Override
-        public List<Step> cancel() {
-            if (mCancelled) {
-                // Double cancelling will just turn off the vibrator right away.
-                return Arrays.asList(new OffStep(SystemClock.uptimeMillis(), controller));
-            }
-            return super.cancel();
-        }
-
-        @Override
-        public List<Step> play() {
-            Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "EffectCompleteStep");
-            try {
-                if (DEBUG) {
-                    Slog.d(TAG, "Running " + (mCancelled ? "cancel" : "complete") + " vibration"
-                            + " step on vibrator " + controller.getVibratorInfo().getId());
-                }
-                if (mVibratorCompleteCallbackReceived) {
-                    // Vibration completion callback was received by this step, just turn if off
-                    // and skip any clean-up.
-                    stopVibrating();
-                    return EMPTY_STEP_LIST;
-                }
-
-                float currentAmplitude = controller.getCurrentAmplitude();
-                long remainingOnDuration =
-                        vibratorOffTimeout - CALLBACKS_EXTRA_TIMEOUT - SystemClock.uptimeMillis();
-                long rampDownDuration =
-                        Math.min(remainingOnDuration, mVibrationSettings.getRampDownDuration());
-                long stepDownDuration = mVibrationSettings.getRampStepDuration();
-                if (currentAmplitude < RAMP_OFF_AMPLITUDE_MIN
-                        || rampDownDuration <= stepDownDuration) {
-                    // No need to ramp down the amplitude, just wait to turn it off.
-                    if (mCancelled) {
-                        // Vibration is completing because it was cancelled, turn off right away.
-                        stopVibrating();
-                        return EMPTY_STEP_LIST;
-                    } else {
-                        return Arrays.asList(new OffStep(vibratorOffTimeout, controller));
-                    }
-                }
-
-                if (DEBUG) {
-                    Slog.d(TAG, "Ramping down vibrator " + controller.getVibratorInfo().getId()
-                            + " from amplitude " + currentAmplitude
-                            + " for " + rampDownDuration + "ms");
-                }
-                float amplitudeDelta = currentAmplitude / (rampDownDuration / stepDownDuration);
-                float amplitudeTarget = currentAmplitude - amplitudeDelta;
-                long newVibratorOffTimeout = mCancelled ? rampDownDuration : vibratorOffTimeout;
-                return Arrays.asList(new RampOffStep(startTime, amplitudeTarget, amplitudeDelta,
-                        controller, newVibratorOffTimeout));
-            } finally {
-                Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR);
-            }
-        }
-    }
-
-    /** Represents a step to ramp down the vibrator amplitude before turning it off. */
-    private final class RampOffStep extends SingleVibratorStep {
-        private final float mAmplitudeTarget;
-        private final float mAmplitudeDelta;
-
-        RampOffStep(long startTime, float amplitudeTarget, float amplitudeDelta,
-                VibratorController controller, long vibratorOffTimeout) {
-            super(startTime, controller, /* effect= */ null, /* index= */ -1, vibratorOffTimeout);
-            mAmplitudeTarget = amplitudeTarget;
-            mAmplitudeDelta = amplitudeDelta;
-        }
-
-        @Override
-        public boolean isCleanUp() {
-            return true;
-        }
-
-        @Override
-        public List<Step> cancel() {
-            return Arrays.asList(new OffStep(SystemClock.uptimeMillis(), controller));
-        }
-
-        @Override
-        public List<Step> play() {
-            Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "RampOffStep");
-            try {
-                if (DEBUG) {
-                    long latency = SystemClock.uptimeMillis() - startTime;
-                    Slog.d(TAG, "Ramp down the vibrator amplitude, step with "
-                            + latency + "ms latency.");
-                }
-                if (mVibratorCompleteCallbackReceived) {
-                    // Vibration completion callback was received by this step, just turn if off
-                    // and skip the rest of the steps to ramp down the vibrator amplitude.
-                    stopVibrating();
-                    return EMPTY_STEP_LIST;
-                }
-
-                changeAmplitude(mAmplitudeTarget);
-
-                float newAmplitudeTarget = mAmplitudeTarget - mAmplitudeDelta;
-                if (newAmplitudeTarget < RAMP_OFF_AMPLITUDE_MIN) {
-                    // Vibrator amplitude cannot go further down, just turn it off.
-                    return Arrays.asList(new OffStep(vibratorOffTimeout, controller));
-                }
-                return Arrays.asList(new RampOffStep(
-                        startTime + mVibrationSettings.getRampStepDuration(), newAmplitudeTarget,
-                        mAmplitudeDelta, controller, vibratorOffTimeout));
-            } finally {
-                Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR);
-            }
-        }
-    }
-
-    /**
-     * Represents a step to turn the vibrator off.
-     *
-     * <p>This runs after a timeout on the expected time the vibrator should have finished playing,
-     * and can be brought forward by vibrator complete callbacks.
-     */
-    private final class OffStep extends SingleVibratorStep {
-
-        OffStep(long startTime, VibratorController controller) {
-            super(startTime, controller, /* effect= */ null, /* index= */ -1, startTime);
-        }
-
-        @Override
-        public boolean isCleanUp() {
-            return true;
-        }
-
-        @Override
-        public List<Step> cancel() {
-            return Arrays.asList(new OffStep(SystemClock.uptimeMillis(), controller));
-        }
-
-        @Override
-        public void cancelImmediately() {
-            stopVibrating();
-        }
-
-        @Override
-        public List<Step> play() {
-            Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "OffStep");
-            try {
-                stopVibrating();
-                return EMPTY_STEP_LIST;
-            } finally {
-                Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR);
-            }
-        }
-    }
-
-    /**
-     * Represents a step to turn the vibrator on and change its amplitude.
-     *
-     * <p>This step ignores vibration completion callbacks and control the vibrator on/off state
-     * and amplitude to simulate waveforms represented by a sequence of {@link StepSegment}.
-     */
-    private final class AmplitudeStep extends SingleVibratorStep {
-        private long mNextOffTime;
-
-        AmplitudeStep(long startTime, VibratorController controller,
-                VibrationEffect.Composed effect, int index, long vibratorOffTimeout) {
-            // This step has a fixed startTime coming from the timings of the waveform it's playing.
-            super(startTime, controller, effect, index, vibratorOffTimeout);
-            mNextOffTime = vibratorOffTimeout;
-        }
-
-        @Override
-        public boolean acceptVibratorCompleteCallback(int vibratorId) {
-            if (controller.getVibratorInfo().getId() == vibratorId) {
-                mVibratorCompleteCallbackReceived = true;
-                mNextOffTime = SystemClock.uptimeMillis();
-            }
-            // Timings are tightly controlled here, so only trigger this step if the vibrator was
-            // supposed to be ON but has completed prematurely, to turn it back on as soon as
-            // possible.
-            return mNextOffTime < startTime && controller.getCurrentAmplitude() > 0;
-        }
-
-        @Override
-        public List<Step> play() {
-            Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "AmplitudeStep");
-            try {
-                long now = SystemClock.uptimeMillis();
-                long latency = now - startTime;
-                if (DEBUG) {
-                    Slog.d(TAG, "Running amplitude step with " + latency + "ms latency.");
-                }
-
-                if (mVibratorCompleteCallbackReceived && latency < 0) {
-                    // This step was run early because the vibrator turned off prematurely.
-                    // Turn it back on and return this same step to run at the exact right time.
-                    mNextOffTime = turnVibratorBackOn(/* remainingDuration= */ -latency);
-                    return Arrays.asList(new AmplitudeStep(startTime, controller, effect,
-                            segmentIndex, mNextOffTime));
-                }
-
-                VibrationEffectSegment segment = effect.getSegments().get(segmentIndex);
-                if (!(segment instanceof StepSegment)) {
-                    Slog.w(TAG, "Ignoring wrong segment for a AmplitudeStep: " + segment);
-                    return skipToNextSteps(/* segmentsSkipped= */ 1);
-                }
-
-                StepSegment stepSegment = (StepSegment) segment;
-                if (stepSegment.getDuration() == 0) {
-                    // Skip waveform entries with zero timing.
-                    return skipToNextSteps(/* segmentsSkipped= */ 1);
-                }
-
-                float amplitude = stepSegment.getAmplitude();
-                if (amplitude == 0) {
-                    if (vibratorOffTimeout > now) {
-                        // Amplitude cannot be set to zero, so stop the vibrator.
-                        stopVibrating();
-                        mNextOffTime = now;
-                    }
-                } else {
-                    if (startTime >= mNextOffTime) {
-                        // Vibrator is OFF. Turn vibrator back on for the duration of another
-                        // cycle before setting the amplitude.
-                        long onDuration = getVibratorOnDuration(effect, segmentIndex);
-                        if (onDuration > 0) {
-                            mVibratorOnResult = startVibrating(onDuration);
-                            mNextOffTime = now + onDuration + CALLBACKS_EXTRA_TIMEOUT;
-                        }
-                    }
-                    changeAmplitude(amplitude);
-                }
-
-                // Use original startTime to avoid propagating latencies to the waveform.
-                long nextStartTime = startTime + segment.getDuration();
-                return nextSteps(nextStartTime, mNextOffTime, /* segmentsPlayed= */ 1);
-            } finally {
-                Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR);
-            }
-        }
-
-        private long turnVibratorBackOn(long remainingDuration) {
-            long onDuration = getVibratorOnDuration(effect, segmentIndex);
-            if (onDuration <= 0) {
-                // Vibrator is supposed to go back off when this step starts, so just leave it off.
-                return vibratorOffTimeout;
-            }
-            onDuration += remainingDuration;
-            float expectedAmplitude = controller.getCurrentAmplitude();
-            mVibratorOnResult = startVibrating(onDuration);
-            if (mVibratorOnResult > 0) {
-                // Set the amplitude back to the value it was supposed to be playing at.
-                changeAmplitude(expectedAmplitude);
-            }
-            return SystemClock.uptimeMillis() + onDuration + CALLBACKS_EXTRA_TIMEOUT;
-        }
-
-        private long startVibrating(long duration) {
-            if (DEBUG) {
-                Slog.d(TAG, "Turning on vibrator " + controller.getVibratorInfo().getId() + " for "
-                        + duration + "ms");
-            }
-            return controller.on(duration, mVibration.id);
-        }
-
-        /**
-         * Get the duration the vibrator will be on for a waveform, starting at {@code startIndex}
-         * until the next time it's vibrating amplitude is zero or a different type of segment is
-         * found.
-         */
-        private long getVibratorOnDuration(VibrationEffect.Composed effect, int startIndex) {
-            List<VibrationEffectSegment> segments = effect.getSegments();
-            int segmentCount = segments.size();
-            int repeatIndex = effect.getRepeatIndex();
-            int i = startIndex;
-            long timing = 0;
-            while (i < segmentCount) {
-                VibrationEffectSegment segment = segments.get(i);
-                if (!(segment instanceof StepSegment)
-                        || ((StepSegment) segment).getAmplitude() == 0) {
-                    break;
-                }
-                timing += segment.getDuration();
-                i++;
-                if (i == segmentCount && repeatIndex >= 0) {
-                    i = repeatIndex;
-                    // prevent infinite loop
-                    repeatIndex = -1;
-                }
-                if (i == startIndex) {
-                    // The repeating waveform keeps the vibrator ON all the time. Use a minimum
-                    // of 1s duration to prevent short patterns from turning the vibrator ON too
-                    // frequently.
-                    return Math.max(timing, 1000);
-                }
-            }
-            if (i == segmentCount && effect.getRepeatIndex() < 0) {
-                // Vibration ending at non-zero amplitude, add extra timings to ramp down after
-                // vibration is complete.
-                timing += mVibrationSettings.getRampDownDuration();
-            }
-            return timing;
-        }
-    }
-
-    /**
-     * Map a {@link CombinedVibration} to the vibrators available on the device.
-     *
-     * <p>This contains the logic to find the capabilities required from {@link IVibratorManager} to
-     * play all of the effects in sync.
-     */
-    private final class DeviceEffectMap {
-        private final SparseArray<VibrationEffect.Composed> mVibratorEffects;
-        private final int[] mVibratorIds;
-        private final long mRequiredSyncCapabilities;
-
-        DeviceEffectMap(CombinedVibration.Mono mono) {
-            mVibratorEffects = new SparseArray<>(mVibrators.size());
-            mVibratorIds = new int[mVibrators.size()];
-            for (int i = 0; i < mVibrators.size(); i++) {
-                int vibratorId = mVibrators.keyAt(i);
-                VibratorInfo vibratorInfo = mVibrators.valueAt(i).getVibratorInfo();
-                VibrationEffect effect = mDeviceEffectAdapter.apply(mono.getEffect(), vibratorInfo);
-                if (effect instanceof VibrationEffect.Composed) {
-                    mVibratorEffects.put(vibratorId, (VibrationEffect.Composed) effect);
-                    mVibratorIds[i] = vibratorId;
-                }
-            }
-            mRequiredSyncCapabilities = calculateRequiredSyncCapabilities(mVibratorEffects);
-        }
-
-        DeviceEffectMap(CombinedVibration.Stereo stereo) {
-            SparseArray<VibrationEffect> stereoEffects = stereo.getEffects();
-            mVibratorEffects = new SparseArray<>();
-            for (int i = 0; i < stereoEffects.size(); i++) {
-                int vibratorId = stereoEffects.keyAt(i);
-                if (mVibrators.contains(vibratorId)) {
-                    VibratorInfo vibratorInfo = mVibrators.valueAt(i).getVibratorInfo();
-                    VibrationEffect effect = mDeviceEffectAdapter.apply(
-                            stereoEffects.valueAt(i), vibratorInfo);
-                    if (effect instanceof VibrationEffect.Composed) {
-                        mVibratorEffects.put(vibratorId, (VibrationEffect.Composed) effect);
-                    }
-                }
-            }
-            mVibratorIds = new int[mVibratorEffects.size()];
-            for (int i = 0; i < mVibratorEffects.size(); i++) {
-                mVibratorIds[i] = mVibratorEffects.keyAt(i);
-            }
-            mRequiredSyncCapabilities = calculateRequiredSyncCapabilities(mVibratorEffects);
-        }
-
-        /**
-         * Return the number of vibrators mapped to play the {@link CombinedVibration} on this
-         * device.
-         */
-        public int size() {
-            return mVibratorIds.length;
-        }
-
-        /**
-         * Return all capabilities required to play the {@link CombinedVibration} in
-         * between calls to {@link IVibratorManager#prepareSynced} and
-         * {@link IVibratorManager#triggerSynced}.
-         */
-        public long getRequiredSyncCapabilities() {
-            return mRequiredSyncCapabilities;
-        }
-
-        /** Return all vibrator ids mapped to play the {@link CombinedVibration}. */
-        public int[] getVibratorIds() {
-            return mVibratorIds;
-        }
-
-        /** Return the id of the vibrator at given index. */
-        public int vibratorIdAt(int index) {
-            return mVibratorEffects.keyAt(index);
-        }
-
-        /** Return the {@link VibrationEffect} at given index. */
-        public VibrationEffect.Composed effectAt(int index) {
-            return mVibratorEffects.valueAt(index);
-        }
-
-        /**
-         * Return all capabilities required from the {@link IVibratorManager} to prepare and
-         * trigger all given effects in sync.
-         *
-         * @return {@link IVibratorManager#CAP_SYNC} together with all required
-         * IVibratorManager.CAP_PREPARE_* and IVibratorManager.CAP_MIXED_TRIGGER_* capabilities.
-         */
-        private long calculateRequiredSyncCapabilities(
-                SparseArray<VibrationEffect.Composed> effects) {
-            long prepareCap = 0;
-            for (int i = 0; i < effects.size(); i++) {
-                VibrationEffectSegment firstSegment = effects.valueAt(i).getSegments().get(0);
-                if (firstSegment instanceof StepSegment) {
-                    prepareCap |= IVibratorManager.CAP_PREPARE_ON;
-                } else if (firstSegment instanceof PrebakedSegment) {
-                    prepareCap |= IVibratorManager.CAP_PREPARE_PERFORM;
-                } else if (firstSegment instanceof PrimitiveSegment) {
-                    prepareCap |= IVibratorManager.CAP_PREPARE_COMPOSE;
-                }
-            }
-            int triggerCap = 0;
-            if (requireMixedTriggerCapability(prepareCap, IVibratorManager.CAP_PREPARE_ON)) {
-                triggerCap |= IVibratorManager.CAP_MIXED_TRIGGER_ON;
-            }
-            if (requireMixedTriggerCapability(prepareCap, IVibratorManager.CAP_PREPARE_PERFORM)) {
-                triggerCap |= IVibratorManager.CAP_MIXED_TRIGGER_PERFORM;
-            }
-            if (requireMixedTriggerCapability(prepareCap, IVibratorManager.CAP_PREPARE_COMPOSE)) {
-                triggerCap |= IVibratorManager.CAP_MIXED_TRIGGER_COMPOSE;
-            }
-            return IVibratorManager.CAP_SYNC | prepareCap | triggerCap;
-        }
-
-        /**
-         * Return true if {@code prepareCapabilities} contains this {@code capability} mixed with
-         * different ones, requiring a mixed trigger capability from the vibrator manager for
-         * syncing all effects.
-         */
-        private boolean requireMixedTriggerCapability(long prepareCapabilities, long capability) {
-            return (prepareCapabilities & capability) != 0
-                    && (prepareCapabilities & ~capability) != 0;
-        }
-    }
 }
diff --git a/services/core/java/com/android/server/vibrator/VibratorManagerService.java b/services/core/java/com/android/server/vibrator/VibratorManagerService.java
index 63f3af3..01f9d0b9 100644
--- a/services/core/java/com/android/server/vibrator/VibratorManagerService.java
+++ b/services/core/java/com/android/server/vibrator/VibratorManagerService.java
@@ -42,6 +42,7 @@
 import android.os.Looper;
 import android.os.PowerManager;
 import android.os.Process;
+import android.os.RemoteException;
 import android.os.ResultReceiver;
 import android.os.ServiceManager;
 import android.os.ShellCallback;
@@ -60,6 +61,7 @@
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.app.IBatteryStats;
 import com.android.internal.util.DumpUtils;
+import com.android.internal.util.FrameworkStatsLog;
 import com.android.server.LocalServices;
 import com.android.server.SystemService;
 
@@ -88,6 +90,9 @@
             VibrationAttributes.FLAG_BYPASS_INTERRUPTION_POLICY
                     | VibrationAttributes.FLAG_BYPASS_USER_VIBRATION_INTENSITY_OFF;
 
+    /** Fixed large duration used to note repeating vibrations to {@link IBatteryStats}. */
+    private static final long BATTERY_STATS_REPEATING_VIBRATION_DURATION = 5_000;
+
     /** Lifecycle responsible for initializing this class at the right system server phases. */
     public static class Lifecycle extends SystemService {
         private VibratorManagerService mService;
@@ -201,8 +206,7 @@
         mSystemUiPackage = LocalServices.getService(PackageManagerInternal.class)
                 .getSystemUiServiceComponent().getPackageName();
 
-        mBatteryStatsService = IBatteryStats.Stub.asInterface(ServiceManager.getService(
-                BatteryStats.SERVICE_NAME));
+        mBatteryStatsService = injector.getBatteryStatsService();
 
         mAppOps = mContext.getSystemService(AppOpsManager.class);
 
@@ -634,7 +638,7 @@
             }
 
             VibrationThread vibThread = new VibrationThread(vib, mVibrationSettings,
-                    mDeviceVibrationEffectAdapter, mVibrators, mWakeLock, mBatteryStatsService,
+                    mDeviceVibrationEffectAdapter, mVibrators, mWakeLock,
                     mVibrationThreadCallbacks);
 
             if (mCurrentVibration == null) {
@@ -1105,6 +1109,11 @@
             return new Handler(looper);
         }
 
+        IBatteryStats getBatteryStatsService() {
+            return IBatteryStats.Stub.asInterface(ServiceManager.getService(
+                    BatteryStats.SERVICE_NAME));
+        }
+
         VibratorController createVibratorController(int vibratorId,
                 VibratorController.OnVibrationCompleteListener listener) {
             return new VibratorController(vibratorId, listener);
@@ -1141,6 +1150,36 @@
         }
 
         @Override
+        public void noteVibratorOn(int uid, long duration) {
+            try {
+                if (duration <= 0) {
+                    return;
+                }
+                if (duration == Long.MAX_VALUE) {
+                    // Repeating duration has started. Report a fixed duration here, noteVibratorOff
+                    // should be called when this is cancelled.
+                    duration = BATTERY_STATS_REPEATING_VIBRATION_DURATION;
+                }
+                mBatteryStatsService.noteVibratorOn(uid, duration);
+                FrameworkStatsLog.write_non_chained(FrameworkStatsLog.VIBRATOR_STATE_CHANGED,
+                        uid, null, FrameworkStatsLog.VIBRATOR_STATE_CHANGED__STATE__ON,
+                        duration);
+            } catch (RemoteException e) {
+            }
+        }
+
+        @Override
+        public void noteVibratorOff(int uid) {
+            try {
+                mBatteryStatsService.noteVibratorOff(uid);
+                FrameworkStatsLog.write_non_chained(FrameworkStatsLog.VIBRATOR_STATE_CHANGED,
+                        uid, null, FrameworkStatsLog.VIBRATOR_STATE_CHANGED__STATE__OFF,
+                        /* duration= */ 0);
+            } catch (RemoteException e) {
+            }
+        }
+
+        @Override
         public void onVibrationCompleted(long vibrationId, Vibration.Status status) {
             if (DEBUG) {
                 Slog.d(TAG, "Vibration " + vibrationId + " finished with status " + status);
diff --git a/services/tests/servicestests/src/com/android/server/vibrator/VibrationThreadTest.java b/services/tests/servicestests/src/com/android/server/vibrator/VibrationThreadTest.java
index e1a4989..01e306e 100644
--- a/services/tests/servicestests/src/com/android/server/vibrator/VibrationThreadTest.java
+++ b/services/tests/servicestests/src/com/android/server/vibrator/VibrationThreadTest.java
@@ -61,8 +61,6 @@
 
 import androidx.test.InstrumentationRegistry;
 
-import com.android.internal.app.IBatteryStats;
-
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Rule;
@@ -106,8 +104,6 @@
     @Mock
     private IBinder mVibrationToken;
     @Mock
-    private IBatteryStats mIBatteryStatsMock;
-    @Mock
     private VibrationConfig mVibrationConfigMock;
 
     private final Map<Integer, FakeVibratorControllerProvider> mVibratorProviders = new HashMap<>();
@@ -178,8 +174,8 @@
         VibrationThread thread = startThreadAndDispatcher(vibrationId, effect);
         waitForCompletion(thread);
 
-        verify(mIBatteryStatsMock).noteVibratorOn(eq(UID), eq(10L));
-        verify(mIBatteryStatsMock).noteVibratorOff(eq(UID));
+        verify(mManagerHooks).noteVibratorOn(eq(UID), eq(10L));
+        verify(mManagerHooks).noteVibratorOff(eq(UID));
         verify(mControllerCallbacks).onComplete(eq(VIBRATOR_ID), eq(vibrationId));
         verifyCallbacksTriggered(vibrationId, Vibration.Status.FINISHED);
         assertFalse(thread.getVibrators().get(VIBRATOR_ID).isVibrating());
@@ -197,8 +193,8 @@
         VibrationThread thread = startThreadAndDispatcher(vibrationId, effect);
         waitForCompletion(thread);
 
-        verify(mIBatteryStatsMock).noteVibratorOn(eq(UID), eq(10L));
-        verify(mIBatteryStatsMock).noteVibratorOff(eq(UID));
+        verify(mManagerHooks).noteVibratorOn(eq(UID), eq(10L));
+        verify(mManagerHooks).noteVibratorOff(eq(UID));
         verify(mControllerCallbacks).onComplete(eq(VIBRATOR_ID), eq(vibrationId));
         verifyCallbacksTriggered(vibrationId, Vibration.Status.FINISHED);
         assertFalse(thread.getVibrators().get(VIBRATOR_ID).isVibrating());
@@ -219,8 +215,8 @@
         VibrationThread thread = startThreadAndDispatcher(vibrationId, effect);
         waitForCompletion(thread);
 
-        verify(mIBatteryStatsMock).noteVibratorOn(eq(UID), eq(15L));
-        verify(mIBatteryStatsMock).noteVibratorOff(eq(UID));
+        verify(mManagerHooks).noteVibratorOn(eq(UID), eq(15L));
+        verify(mManagerHooks).noteVibratorOff(eq(UID));
         verify(mControllerCallbacks).onComplete(eq(VIBRATOR_ID), eq(vibrationId));
         verifyCallbacksTriggered(vibrationId, Vibration.Status.FINISHED);
         assertFalse(thread.getVibrators().get(VIBRATOR_ID).isVibrating());
@@ -252,8 +248,8 @@
         thread.cancel();
         waitForCompletion(thread);
 
-        verify(mIBatteryStatsMock).noteVibratorOn(eq(UID), anyLong());
-        verify(mIBatteryStatsMock).noteVibratorOff(eq(UID));
+        verify(mManagerHooks).noteVibratorOn(eq(UID), anyLong());
+        verify(mManagerHooks).noteVibratorOff(eq(UID));
         verifyCallbacksTriggered(vibrationId, Vibration.Status.CANCELLED);
         assertFalse(thread.getVibrators().get(VIBRATOR_ID).isVibrating());
 
@@ -404,8 +400,8 @@
         VibrationThread thread = startThreadAndDispatcher(vibrationId, effect);
         waitForCompletion(thread);
 
-        verify(mIBatteryStatsMock).noteVibratorOn(eq(UID), eq(20L));
-        verify(mIBatteryStatsMock).noteVibratorOff(eq(UID));
+        verify(mManagerHooks).noteVibratorOn(eq(UID), eq(20L));
+        verify(mManagerHooks).noteVibratorOff(eq(UID));
         verify(mControllerCallbacks).onComplete(eq(VIBRATOR_ID), eq(vibrationId));
         verifyCallbacksTriggered(vibrationId, Vibration.Status.FINISHED);
         assertFalse(thread.getVibrators().get(VIBRATOR_ID).isVibrating());
@@ -427,8 +423,8 @@
         VibrationThread thread = startThreadAndDispatcher(vibration);
         waitForCompletion(thread);
 
-        verify(mIBatteryStatsMock).noteVibratorOn(eq(UID), eq(10L));
-        verify(mIBatteryStatsMock).noteVibratorOff(eq(UID));
+        verify(mManagerHooks).noteVibratorOn(eq(UID), eq(10L));
+        verify(mManagerHooks).noteVibratorOff(eq(UID));
         verify(mControllerCallbacks).onComplete(eq(VIBRATOR_ID), eq(vibrationId));
         verifyCallbacksTriggered(vibrationId, Vibration.Status.FINISHED);
         assertFalse(thread.getVibrators().get(VIBRATOR_ID).isVibrating());
@@ -446,8 +442,8 @@
         VibrationThread thread = startThreadAndDispatcher(vibrationId, effect);
         waitForCompletion(thread);
 
-        verify(mIBatteryStatsMock, never()).noteVibratorOn(eq(UID), anyLong());
-        verify(mIBatteryStatsMock, never()).noteVibratorOff(eq(UID));
+        verify(mManagerHooks, never()).noteVibratorOn(eq(UID), anyLong());
+        verify(mManagerHooks, never()).noteVibratorOff(eq(UID));
         verify(mControllerCallbacks, never()).onComplete(eq(VIBRATOR_ID), eq(vibrationId));
         verifyCallbacksTriggered(vibrationId, Vibration.Status.IGNORED_UNSUPPORTED);
         assertTrue(mVibratorProviders.get(VIBRATOR_ID).getEffectSegments().isEmpty());
@@ -466,8 +462,8 @@
         VibrationThread thread = startThreadAndDispatcher(vibrationId, effect);
         waitForCompletion(thread);
 
-        verify(mIBatteryStatsMock).noteVibratorOn(eq(UID), eq(40L));
-        verify(mIBatteryStatsMock).noteVibratorOff(eq(UID));
+        verify(mManagerHooks).noteVibratorOn(eq(UID), eq(40L));
+        verify(mManagerHooks).noteVibratorOff(eq(UID));
         verify(mControllerCallbacks).onComplete(eq(VIBRATOR_ID), eq(vibrationId));
         verifyCallbacksTriggered(vibrationId, Vibration.Status.FINISHED);
         assertFalse(thread.getVibrators().get(VIBRATOR_ID).isVibrating());
@@ -486,8 +482,8 @@
         VibrationThread thread = startThreadAndDispatcher(vibrationId, effect);
         waitForCompletion(thread);
 
-        verify(mIBatteryStatsMock, never()).noteVibratorOn(eq(UID), anyLong());
-        verify(mIBatteryStatsMock, never()).noteVibratorOff(eq(UID));
+        verify(mManagerHooks, never()).noteVibratorOn(eq(UID), anyLong());
+        verify(mManagerHooks, never()).noteVibratorOff(eq(UID));
         verify(mControllerCallbacks, never()).onComplete(eq(VIBRATOR_ID), eq(vibrationId));
         verifyCallbacksTriggered(vibrationId, Vibration.Status.IGNORED_UNSUPPORTED);
         assertTrue(mVibratorProviders.get(VIBRATOR_ID).getEffectSegments().isEmpty());
@@ -536,8 +532,8 @@
         waitForCompletion(thread);
 
         // Use first duration the vibrator is turned on since we cannot estimate the clicks.
-        verify(mIBatteryStatsMock).noteVibratorOn(eq(UID), eq(10L));
-        verify(mIBatteryStatsMock).noteVibratorOff(eq(UID));
+        verify(mManagerHooks).noteVibratorOn(eq(UID), eq(10L));
+        verify(mManagerHooks).noteVibratorOff(eq(UID));
         verify(mControllerCallbacks, times(4)).onComplete(eq(VIBRATOR_ID), eq(vibrationId));
         verifyCallbacksTriggered(vibrationId, Vibration.Status.FINISHED);
         assertFalse(thread.getVibrators().get(VIBRATOR_ID).isVibrating());
@@ -573,8 +569,8 @@
         VibrationThread thread = startThreadAndDispatcher(vibrationId, effect);
         waitForCompletion(thread);
 
-        verify(mIBatteryStatsMock).noteVibratorOn(eq(UID), eq(100L));
-        verify(mIBatteryStatsMock).noteVibratorOff(eq(UID));
+        verify(mManagerHooks).noteVibratorOn(eq(UID), eq(100L));
+        verify(mManagerHooks).noteVibratorOff(eq(UID));
         verify(mControllerCallbacks).onComplete(eq(VIBRATOR_ID), eq(vibrationId));
         verifyCallbacksTriggered(vibrationId, Vibration.Status.FINISHED);
         assertFalse(thread.getVibrators().get(VIBRATOR_ID).isVibrating());
@@ -666,8 +662,8 @@
         VibrationThread thread = startThreadAndDispatcher(vibrationId, effect);
         waitForCompletion(thread);
 
-        verify(mIBatteryStatsMock).noteVibratorOn(eq(UID), eq(20L));
-        verify(mIBatteryStatsMock).noteVibratorOff(eq(UID));
+        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, Vibration.Status.FINISHED);
@@ -690,8 +686,8 @@
         VibrationThread thread = startThreadAndDispatcher(vibrationId, effect);
         waitForCompletion(thread);
 
-        verify(mIBatteryStatsMock).noteVibratorOn(eq(UID), eq(20L));
-        verify(mIBatteryStatsMock).noteVibratorOff(eq(UID));
+        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));
@@ -728,8 +724,8 @@
         VibrationThread thread = startThreadAndDispatcher(vibrationId, effect);
         waitForCompletion(thread);
 
-        verify(mIBatteryStatsMock).noteVibratorOn(eq(UID), eq(20L));
-        verify(mIBatteryStatsMock).noteVibratorOff(eq(UID));
+        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));
@@ -777,13 +773,13 @@
         controllerVerifier.verify(mControllerCallbacks).onComplete(eq(1), eq(vibrationId));
         controllerVerifier.verify(mControllerCallbacks).onComplete(eq(2), eq(vibrationId));
 
-        InOrder batterVerifier = inOrder(mIBatteryStatsMock);
-        batterVerifier.verify(mIBatteryStatsMock).noteVibratorOn(eq(UID), eq(20L));
-        batterVerifier.verify(mIBatteryStatsMock).noteVibratorOff(eq(UID));
-        batterVerifier.verify(mIBatteryStatsMock).noteVibratorOn(eq(UID), eq(10L));
-        batterVerifier.verify(mIBatteryStatsMock).noteVibratorOff(eq(UID));
-        batterVerifier.verify(mIBatteryStatsMock).noteVibratorOn(eq(UID), eq(20L));
-        batterVerifier.verify(mIBatteryStatsMock).noteVibratorOff(eq(UID));
+        InOrder batteryVerifier = inOrder(mManagerHooks);
+        batteryVerifier.verify(mManagerHooks).noteVibratorOn(eq(UID), eq(20L));
+        batteryVerifier.verify(mManagerHooks).noteVibratorOff(eq(UID));
+        batteryVerifier.verify(mManagerHooks).noteVibratorOn(eq(UID), eq(10L));
+        batteryVerifier.verify(mManagerHooks).noteVibratorOff(eq(UID));
+        batteryVerifier.verify(mManagerHooks).noteVibratorOn(eq(UID), eq(20L));
+        batteryVerifier.verify(mManagerHooks).noteVibratorOff(eq(UID));
 
         verifyCallbacksTriggered(vibrationId, Vibration.Status.FINISHED);
         assertFalse(thread.getVibrators().get(1).isVibrating());
@@ -952,8 +948,8 @@
 
         waitForCompletion(thread);
 
-        verify(mIBatteryStatsMock).noteVibratorOn(eq(UID), eq(80L));
-        verify(mIBatteryStatsMock).noteVibratorOff(eq(UID));
+        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));
@@ -1300,7 +1296,7 @@
 
     private VibrationThread startThreadAndDispatcher(Vibration vib) {
         VibrationThread thread = new VibrationThread(vib, mVibrationSettings, mEffectAdapter,
-                createVibratorControllers(), mWakeLock, mIBatteryStatsMock, mManagerHooks);
+                createVibratorControllers(), mWakeLock, mManagerHooks);
         doAnswer(answer -> {
             thread.vibratorComplete(answer.getArgument(0));
             return null;
diff --git a/services/tests/servicestests/src/com/android/server/vibrator/VibratorManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/vibrator/VibratorManagerServiceTest.java
index ccdb105..19111e5 100644
--- a/services/tests/servicestests/src/com/android/server/vibrator/VibratorManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/vibrator/VibratorManagerServiceTest.java
@@ -71,6 +71,7 @@
 import android.os.test.TestLooper;
 import android.os.vibrator.PrebakedSegment;
 import android.os.vibrator.PrimitiveSegment;
+import android.os.vibrator.VibrationConfig;
 import android.os.vibrator.VibrationEffectSegment;
 import android.platform.test.annotations.Presubmit;
 import android.provider.Settings;
@@ -78,6 +79,7 @@
 
 import androidx.test.InstrumentationRegistry;
 
+import com.android.internal.app.IBatteryStats;
 import com.android.internal.util.test.FakeSettingsProvider;
 import com.android.internal.util.test.FakeSettingsProviderRule;
 import com.android.server.LocalServices;
@@ -144,6 +146,8 @@
     private AppOpsManager mAppOpsManagerMock;
     @Mock
     private IInputManager mIInputManagerMock;
+    @Mock
+    private IBatteryStats mBatteryStatsMock;
 
     private final Map<Integer, FakeVibratorControllerProvider> mVibratorProviders = new HashMap<>();
 
@@ -152,12 +156,14 @@
     private FakeVibrator mVibrator;
     private PowerManagerInternal.LowPowerModeListener mRegisteredPowerModeListener;
     private VibratorManagerService.ExternalVibratorService mExternalVibratorService;
+    private VibrationConfig mVibrationConfig;
 
     @Before
     public void setUp() throws Exception {
         mTestLooper = new TestLooper();
         mContextSpy = spy(new ContextWrapper(InstrumentationRegistry.getContext()));
         InputManager inputManager = InputManager.resetInstance(mIInputManagerMock);
+        mVibrationConfig = new VibrationConfig(mContextSpy.getResources());
 
         ContentResolver contentResolver = mSettingsProviderRule.mockContentResolver(mContextSpy);
         when(mContextSpy.getContentResolver()).thenReturn(contentResolver);
@@ -222,6 +228,11 @@
                     }
 
                     @Override
+                    IBatteryStats getBatteryStatsService() {
+                        return mBatteryStatsMock;
+                    }
+
+                    @Override
                     VibratorController createVibratorController(int vibratorId,
                             VibratorController.OnVibrationCompleteListener listener) {
                         return mVibratorProviders.get(vibratorId)
@@ -382,6 +393,11 @@
         inOrderVerifier.verify(listenerMock).onVibrating(eq(true));
         inOrderVerifier.verify(listenerMock).onVibrating(eq(false));
         inOrderVerifier.verifyNoMoreInteractions();
+
+        InOrder batteryVerifier = inOrder(mBatteryStatsMock);
+        batteryVerifier.verify(mBatteryStatsMock)
+                .noteVibratorOn(UID, 40 + mVibrationConfig.getRampDownDurationMs());
+        batteryVerifier.verify(mBatteryStatsMock).noteVibratorOff(UID);
     }
 
     @Test
@@ -731,6 +747,12 @@
         // Wait before checking it never played a second effect.
         assertFalse(waitUntil(s -> mVibratorProviders.get(1).getEffectSegments().size() > 1,
                 service, /* timeout= */ 50));
+
+        // The time estimate is recorded when the vibration starts, repeating vibrations
+        // are capped at BATTERY_STATS_REPEATING_VIBRATION_DURATION (=5000).
+        verify(mBatteryStatsMock).noteVibratorOn(UID, 5000);
+        // The second vibration shouldn't have recorded that the vibrators were turned on.
+        verify(mBatteryStatsMock, times(1)).noteVibratorOn(anyInt(), anyLong());
     }
 
     @Test
