diff --git a/core/api/test-current.txt b/core/api/test-current.txt
index 08b73278..e885fd3 100644
--- a/core/api/test-current.txt
+++ b/core/api/test-current.txt
@@ -1366,11 +1366,10 @@
 
   public static class VibrationEffect.Prebaked extends android.os.VibrationEffect implements android.os.Parcelable {
     ctor public VibrationEffect.Prebaked(android.os.Parcel);
-    ctor public VibrationEffect.Prebaked(int, boolean);
+    ctor public VibrationEffect.Prebaked(int, boolean, int);
     method public long getDuration();
     method public int getEffectStrength();
     method public int getId();
-    method public void setEffectStrength(int);
     method public boolean shouldFallback();
     method public void writeToParcel(android.os.Parcel, int);
     field @NonNull public static final android.os.Parcelable.Creator<android.os.VibrationEffect.Prebaked> CREATOR;
diff --git a/core/java/android/os/CombinedVibrationEffect.java b/core/java/android/os/CombinedVibrationEffect.java
index 7ec7fff..869a727 100644
--- a/core/java/android/os/CombinedVibrationEffect.java
+++ b/core/java/android/os/CombinedVibrationEffect.java
@@ -87,8 +87,14 @@
     }
 
     /** @hide */
+    public abstract long getDuration();
+
+    /** @hide */
     public abstract void validate();
 
+    /** @hide */
+    public abstract boolean hasVibrator(int vibratorId);
+
     /**
      * A combination of haptic effects that should be played in multiple vibrators in sync.
      *
@@ -265,6 +271,11 @@
             return mEffect;
         }
 
+        @Override
+        public long getDuration() {
+            return mEffect.getDuration();
+        }
+
         /** @hide */
         @Override
         public void validate() {
@@ -272,12 +283,17 @@
         }
 
         @Override
+        public boolean hasVibrator(int vibratorId) {
+            return true;
+        }
+
+        @Override
         public boolean equals(Object o) {
             if (!(o instanceof Mono)) {
                 return false;
             }
             Mono other = (Mono) o;
-            return other.mEffect.equals(other.mEffect);
+            return mEffect.equals(other.mEffect);
         }
 
         @Override
@@ -345,6 +361,15 @@
             return mEffects;
         }
 
+        @Override
+        public long getDuration() {
+            long maxDuration = Long.MIN_VALUE;
+            for (int i = 0; i < mEffects.size(); i++) {
+                maxDuration = Math.max(maxDuration, mEffects.valueAt(i).getDuration());
+            }
+            return maxDuration;
+        }
+
         /** @hide */
         @Override
         public void validate() {
@@ -356,6 +381,11 @@
         }
 
         @Override
+        public boolean hasVibrator(int vibratorId) {
+            return mEffects.indexOfKey(vibratorId) >= 0;
+        }
+
+        @Override
         public boolean equals(Object o) {
             if (!(o instanceof Stereo)) {
                 return false;
@@ -445,6 +475,26 @@
             return mDelays;
         }
 
+        @Override
+        public long getDuration() {
+            long durations = 0;
+            final int effectCount = mEffects.size();
+            for (int i = 0; i < effectCount; i++) {
+                CombinedVibrationEffect effect = mEffects.get(i);
+                long duration = effect.getDuration();
+                if (duration < 0) {
+                    // If any duration is unknown, this combination duration is also unknown.
+                    return duration;
+                }
+                durations += duration;
+            }
+            long delays = 0;
+            for (int i = 0; i < effectCount; i++) {
+                delays += mDelays.get(i);
+            }
+            return durations + delays;
+        }
+
         /** @hide */
         @Override
         public void validate() {
@@ -452,13 +502,15 @@
                     "There should be at least one effect set for a combined effect");
             Preconditions.checkArgument(mEffects.size() == mDelays.size(),
                     "Effect and delays should have equal length");
-            for (long delay : mDelays) {
-                if (delay < 0) {
+            final int effectCount = mEffects.size();
+            for (int i = 0; i < effectCount; i++) {
+                if (mDelays.get(i) < 0) {
                     throw new IllegalArgumentException("Delays must all be >= 0"
                             + " (delays=" + mDelays + ")");
                 }
             }
-            for (CombinedVibrationEffect effect : mEffects) {
+            for (int i = 0; i < effectCount; i++) {
+                CombinedVibrationEffect effect = mEffects.get(i);
                 if (effect instanceof Sequential) {
                     throw new IllegalArgumentException(
                             "There should be no nested sequential effects in a combined effect");
@@ -468,6 +520,17 @@
         }
 
         @Override
+        public boolean hasVibrator(int vibratorId) {
+            final int effectCount = mEffects.size();
+            for (int i = 0; i < effectCount; i++) {
+                if (mEffects.get(i).hasVibrator(vibratorId)) {
+                    return true;
+                }
+            }
+            return false;
+        }
+
+        @Override
         public boolean equals(Object o) {
             if (!(o instanceof Sequential)) {
                 return false;
diff --git a/core/java/android/os/VibrationEffect.java b/core/java/android/os/VibrationEffect.java
index c0b2ada..df3beb2 100644
--- a/core/java/android/os/VibrationEffect.java
+++ b/core/java/android/os/VibrationEffect.java
@@ -317,7 +317,7 @@
      */
     @TestApi
     public static VibrationEffect get(int effectId, boolean fallback) {
-        VibrationEffect effect = new Prebaked(effectId, fallback);
+        VibrationEffect effect = new Prebaked(effectId, fallback, EffectStrength.MEDIUM);
         effect.validate();
         return effect;
     }
@@ -792,22 +792,30 @@
     public static class Prebaked extends VibrationEffect implements Parcelable {
         private final int mEffectId;
         private final boolean mFallback;
-
-        private int mEffectStrength;
+        private final int mEffectStrength;
+        @Nullable
+        private final VibrationEffect mFallbackEffect;
 
         public Prebaked(Parcel in) {
-            this(in.readInt(), in.readByte() != 0, in.readInt());
+            mEffectId = in.readInt();
+            mFallback = in.readByte() != 0;
+            mEffectStrength = in.readInt();
+            mFallbackEffect = in.readParcelable(VibrationEffect.class.getClassLoader());
         }
 
-        public Prebaked(int effectId, boolean fallback) {
-            this(effectId, fallback, EffectStrength.MEDIUM);
-        }
-
-        /** @hide */
         public Prebaked(int effectId, boolean fallback, int effectStrength) {
             mEffectId = effectId;
             mFallback = fallback;
             mEffectStrength = effectStrength;
+            mFallbackEffect = null;
+        }
+
+        /** @hide */
+        public Prebaked(int effectId, int effectStrength, @NonNull VibrationEffect fallbackEffect) {
+            mEffectId = effectId;
+            mFallback = true;
+            mEffectStrength = effectStrength;
+            mFallbackEffect = fallbackEffect;
         }
 
         public int getId() {
@@ -829,26 +837,27 @@
 
         /** @hide */
         @Override
-        public VibrationEffect resolve(int defaultAmplitude) {
-            // Prebaked effects already have default amplitude set, so ignore this.
+        public Prebaked resolve(int defaultAmplitude) {
+            if (mFallbackEffect != null) {
+                VibrationEffect resolvedFallback = mFallbackEffect.resolve(defaultAmplitude);
+                if (!mFallbackEffect.equals(resolvedFallback)) {
+                    return new Prebaked(mEffectId, mEffectStrength, resolvedFallback);
+                }
+            }
             return this;
         }
 
         /** @hide */
         @Override
         public Prebaked scale(float scaleFactor) {
-            // Prebaked effects cannot be scaled, so ignore this.
-            return this;
-        }
-
-        /**
-         * Set the effect strength of the prebaked effect.
-         */
-        public void setEffectStrength(int strength) {
-            if (!isValidEffectStrength(strength)) {
-                throw new IllegalArgumentException("Invalid effect strength: " + strength);
+            if (mFallbackEffect != null) {
+                VibrationEffect scaledFallback = mFallbackEffect.scale(scaleFactor);
+                if (!mFallbackEffect.equals(scaledFallback)) {
+                    return new Prebaked(mEffectId, mEffectStrength, scaledFallback);
+                }
             }
-            mEffectStrength = strength;
+            // Prebaked effect strength cannot be scaled with this method.
+            return this;
         }
 
         /**
@@ -858,6 +867,16 @@
             return mEffectStrength;
         }
 
+        /**
+         * Return the fallback effect, if set.
+         *
+         * @hide
+         */
+        @Nullable
+        public VibrationEffect getFallbackEffect() {
+            return mFallbackEffect;
+        }
+
         private static boolean isValidEffectStrength(int strength) {
             switch (strength) {
                 case EffectStrength.LIGHT:
@@ -901,15 +920,13 @@
             VibrationEffect.Prebaked other = (VibrationEffect.Prebaked) o;
             return mEffectId == other.mEffectId
                 && mFallback == other.mFallback
-                && mEffectStrength == other.mEffectStrength;
+                && mEffectStrength == other.mEffectStrength
+                && Objects.equals(mFallbackEffect, other.mFallbackEffect);
         }
 
         @Override
         public int hashCode() {
-            int result = 17;
-            result += 37 * mEffectId;
-            result += 37 * mEffectStrength;
-            return result;
+            return Objects.hash(mEffectId, mFallback, mEffectStrength, mFallbackEffect);
         }
 
         @Override
@@ -917,6 +934,7 @@
             return "Prebaked{mEffectId=" + mEffectId
                 + ", mEffectStrength=" + mEffectStrength
                 + ", mFallback=" + mFallback
+                + ", mFallbackEffect=" + mFallbackEffect
                 + "}";
         }
 
@@ -927,6 +945,7 @@
             out.writeInt(mEffectId);
             out.writeByte((byte) (mFallback ? 1 : 0));
             out.writeInt(mEffectStrength);
+            out.writeParcelable(mFallbackEffect, flags);
         }
 
         public static final @NonNull Parcelable.Creator<Prebaked> CREATOR =
@@ -990,8 +1009,10 @@
                 // Just return this if there's no scaling to be done.
                 return this;
             }
+            final int primitiveCount = mPrimitiveEffects.size();
             List<Composition.PrimitiveEffect> scaledPrimitives = new ArrayList<>();
-            for (Composition.PrimitiveEffect primitive : mPrimitiveEffects) {
+            for (int i = 0; i < primitiveCount; i++) {
+                Composition.PrimitiveEffect primitive = mPrimitiveEffects.get(i);
                 scaledPrimitives.add(new Composition.PrimitiveEffect(
                         primitive.id, scale(primitive.scale, scaleFactor), primitive.delay));
             }
@@ -1001,11 +1022,12 @@
         /** @hide */
         @Override
         public void validate() {
-            for (Composition.PrimitiveEffect effect : mPrimitiveEffects) {
-                Composition.checkPrimitive(effect.id);
-                Preconditions.checkArgumentInRange(
-                        effect.scale, 0.0f, 1.0f, "scale");
-                Preconditions.checkArgumentNonNegative(effect.delay,
+            final int primitiveCount = mPrimitiveEffects.size();
+            for (int i = 0; i < primitiveCount; i++) {
+                Composition.PrimitiveEffect primitive = mPrimitiveEffects.get(i);
+                Composition.checkPrimitive(primitive.id);
+                Preconditions.checkArgumentInRange(primitive.scale, 0.0f, 1.0f, "scale");
+                Preconditions.checkArgumentNonNegative(primitive.delay,
                         "Primitive delay must be zero or positive");
             }
         }
diff --git a/core/tests/coretests/src/android/os/VibrationEffectTest.java b/core/tests/coretests/src/android/os/VibrationEffectTest.java
index c357414..1d56e17 100644
--- a/core/tests/coretests/src/android/os/VibrationEffectTest.java
+++ b/core/tests/coretests/src/android/os/VibrationEffectTest.java
@@ -39,6 +39,7 @@
 
 import com.android.internal.R;
 
+import org.junit.Assert;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.junit.MockitoJUnitRunner;
@@ -168,15 +169,30 @@
     }
 
     @Test
-    public void testScalePrebaked_ignoresScaleAndReturnsSameEffect() {
-        VibrationEffect initial = VibrationEffect.get(VibrationEffect.RINGTONES[1]);
-        assertSame(initial, initial.scale(0.5f));
+    public void testScalePrebaked_scalesFallbackEffect() {
+        VibrationEffect.Prebaked prebaked =
+                (VibrationEffect.Prebaked) VibrationEffect.get(VibrationEffect.RINGTONES[1]);
+        assertSame(prebaked, prebaked.scale(0.5f));
+
+        prebaked = new VibrationEffect.Prebaked(VibrationEffect.EFFECT_CLICK,
+                VibrationEffect.EFFECT_STRENGTH_MEDIUM, TEST_ONE_SHOT);
+        VibrationEffect.OneShot scaledFallback =
+                (VibrationEffect.OneShot) prebaked.scale(0.5f).getFallbackEffect();
+        assertEquals(34, scaledFallback.getAmplitude(), AMPLITUDE_SCALE_TOLERANCE);
     }
 
     @Test
-    public void testResolvePrebaked_ignoresDefaultAmplitudeAndReturnsSameEffect() {
-        VibrationEffect initial = VibrationEffect.get(VibrationEffect.RINGTONES[1]);
-        assertSame(initial, initial.resolve(1000));
+    public void testResolvePrebaked_resolvesFallbackEffectIfSet() {
+        VibrationEffect.Prebaked prebaked =
+                (VibrationEffect.Prebaked) VibrationEffect.get(VibrationEffect.RINGTONES[1]);
+        assertSame(prebaked, prebaked.resolve(1000));
+
+        prebaked = new VibrationEffect.Prebaked(VibrationEffect.EFFECT_CLICK,
+                VibrationEffect.EFFECT_STRENGTH_MEDIUM,
+                VibrationEffect.createOneShot(1, VibrationEffect.DEFAULT_AMPLITUDE));
+        VibrationEffect.OneShot resolvedFallback =
+                (VibrationEffect.OneShot) prebaked.resolve(10).getFallbackEffect();
+        assertEquals(10, resolvedFallback.getAmplitude());
     }
 
     @Test
@@ -352,6 +368,36 @@
                 INTENSITY_SCALE_TOLERANCE);
     }
 
+    @Test
+    public void getEffectStrength_returnsValueFromConstructor() {
+        VibrationEffect.Prebaked effect = new VibrationEffect.Prebaked(VibrationEffect.EFFECT_CLICK,
+                VibrationEffect.EFFECT_STRENGTH_LIGHT, null);
+        Assert.assertEquals(VibrationEffect.EFFECT_STRENGTH_LIGHT, effect.getEffectStrength());
+    }
+
+    @Test
+    public void getFallbackEffect_withFallbackDisabled_isNull() {
+        VibrationEffect fallback = VibrationEffect.createOneShot(100, 100);
+        VibrationEffect.Prebaked effect = new VibrationEffect.Prebaked(VibrationEffect.EFFECT_CLICK,
+                false, VibrationEffect.EFFECT_STRENGTH_LIGHT);
+        Assert.assertNull(effect.getFallbackEffect());
+    }
+
+    @Test
+    public void getFallbackEffect_withoutEffectSet_isNull() {
+        VibrationEffect.Prebaked effect = new VibrationEffect.Prebaked(VibrationEffect.EFFECT_CLICK,
+                true, VibrationEffect.EFFECT_STRENGTH_LIGHT);
+        Assert.assertNull(effect.getFallbackEffect());
+    }
+
+    @Test
+    public void getFallbackEffect_withFallback_returnsValueFromConstructor() {
+        VibrationEffect fallback = VibrationEffect.createOneShot(100, 100);
+        VibrationEffect.Prebaked effect = new VibrationEffect.Prebaked(VibrationEffect.EFFECT_CLICK,
+                VibrationEffect.EFFECT_STRENGTH_LIGHT, fallback);
+        Assert.assertEquals(fallback, effect.getFallbackEffect());
+    }
+
     private Resources mockRingtoneResources() {
         return mockRingtoneResources(new String[] {
                 RINGTONE_URI_1,
diff --git a/services/core/java/com/android/server/VibratorService.java b/services/core/java/com/android/server/VibratorService.java
index 6a9715e..2c83da5 100644
--- a/services/core/java/com/android/server/VibratorService.java
+++ b/services/core/java/com/android/server/VibratorService.java
@@ -28,6 +28,7 @@
 import android.hardware.vibrator.IVibrator;
 import android.os.BatteryStats;
 import android.os.Binder;
+import android.os.CombinedVibrationEffect;
 import android.os.ExternalVibration;
 import android.os.Handler;
 import android.os.IBinder;
@@ -37,18 +38,15 @@
 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;
 import android.os.ShellCommand;
-import android.os.SystemClock;
 import android.os.Trace;
 import android.os.VibrationAttributes;
 import android.os.VibrationEffect;
 import android.os.Vibrator;
 import android.os.VibratorInfo;
-import android.os.WorkSource;
 import android.util.Slog;
 import android.util.proto.ProtoOutputStream;
 
@@ -56,11 +54,11 @@
 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.vibrator.InputDeviceDelegate;
 import com.android.server.vibrator.Vibration;
 import com.android.server.vibrator.VibrationScaler;
 import com.android.server.vibrator.VibrationSettings;
+import com.android.server.vibrator.VibrationThread;
 import com.android.server.vibrator.VibratorController;
 import com.android.server.vibrator.VibratorController.OnVibrationCompleteListener;
 
@@ -90,10 +88,10 @@
     private final LinkedList<Vibration.DebugInfo> mPreviousExternalVibrations;
     private final LinkedList<Vibration.DebugInfo> mPreviousVibrations;
     private final int mPreviousVibrationsLimit;
-    private final WorkSource mTmpWorkSource = new WorkSource();
     private final Handler mH;
     private final Object mLock = new Object();
     private final VibratorController mVibratorController;
+    private final VibrationCallbacks mVibrationCallbacks = new VibrationCallbacks();
 
     private final Context mContext;
     private final PowerManager.WakeLock mWakeLock;
@@ -104,16 +102,40 @@
     private VibrationScaler mVibrationScaler;
     private InputDeviceDelegate mInputDeviceDelegate;
 
-    private volatile VibrateWaveformThread mThread;
+    private volatile VibrationThread mThread;
 
     @GuardedBy("mLock")
     private Vibration mCurrentVibration;
-    @GuardedBy("mLock")
-    private VibrationDeathRecipient mCurrentVibrationDeathRecipient;
     private int mCurVibUid = -1;
     private ExternalVibrationHolder mCurrentExternalVibration;
 
     /**
+     * Implementation of {@link VibrationThread.VibrationCallbacks} that reports finished
+     * vibrations.
+     */
+    private final class VibrationCallbacks implements VibrationThread.VibrationCallbacks {
+
+        @Override
+        public void prepareSyncedVibration(int requiredCapabilities, int[] vibratorIds) {
+        }
+
+        @Override
+        public void triggerSyncedVibration(long vibrationId) {
+        }
+
+        @Override
+        public void onVibrationEnded(long vibrationId, Vibration.Status status) {
+            if (DEBUG) {
+                Slog.d(TAG, "Vibration thread finished with status " + status);
+            }
+            synchronized (mLock) {
+                mThread = null;
+                reportFinishVibrationLocked(status);
+            }
+        }
+    }
+
+    /**
      * Implementation of {@link OnVibrationCompleteListener} with a weak reference to this service.
      */
     private static final class VibrationCompleteListener implements OnVibrationCompleteListener {
@@ -127,41 +149,11 @@
         public void onComplete(int vibratorId, long vibrationId) {
             VibratorService service = mServiceRef.get();
             if (service != null) {
-                service.onVibrationComplete(vibrationId);
+                service.onVibrationComplete(vibratorId, vibrationId);
             }
         }
     }
 
-    /** Death recipient to bind {@link Vibration}. */
-    private final class VibrationDeathRecipient implements IBinder.DeathRecipient {
-
-        private final Vibration mVibration;
-
-        private VibrationDeathRecipient(Vibration vibration) {
-            mVibration = vibration;
-        }
-
-        @Override
-        public void binderDied() {
-            synchronized (mLock) {
-                if (mVibration == mCurrentVibration) {
-                    if (DEBUG) {
-                        Slog.d(TAG, "Vibration finished because binder died, cleaning up");
-                    }
-                    doCancelVibrateLocked(Vibration.Status.CANCELLED);
-                }
-            }
-        }
-
-        private void linkToDeath() throws RemoteException {
-            mVibration.token.linkToDeath(this, 0);
-        }
-
-        private void unlinkToDeath() {
-            mVibration.token.unlinkToDeath(this, 0);
-        }
-    }
-
     /** Holder for a {@link ExternalVibration}. */
     private final class ExternalVibrationHolder {
 
@@ -262,13 +254,20 @@
 
     /** Callback for when vibration is complete, to be called by native. */
     @VisibleForTesting
-    public void onVibrationComplete(long vibrationId) {
+    public void onVibrationComplete(int vibratorId, long vibrationId) {
         synchronized (mLock) {
             if (mCurrentVibration != null && mCurrentVibration.id == vibrationId) {
                 if (DEBUG) {
-                    Slog.d(TAG, "Vibration finished by callback, cleaning up");
+                    Slog.d(TAG, "Vibration onComplete callback, notifying VibrationThread");
                 }
-                doCancelVibrateLocked(Vibration.Status.FINISHED);
+                if (mThread != null) {
+                    // Let the thread playing the vibration handle the callback, since it might be
+                    // expecting the vibrator to turn off multiple times during a single vibration.
+                    mThread.vibratorComplete(vibratorId);
+                } else {
+                    // No vibration is playing in the thread, but clean up service just in case.
+                    doCancelVibrateLocked(Vibration.Status.FINISHED);
+                }
             }
         }
     }
@@ -354,6 +353,17 @@
         return true;
     }
 
+    private VibrationEffect fixupVibrationEffect(VibrationEffect effect) {
+        if (effect instanceof VibrationEffect.Prebaked
+                && ((VibrationEffect.Prebaked) effect).shouldFallback()) {
+            VibrationEffect.Prebaked prebaked = (VibrationEffect.Prebaked) effect;
+            VibrationEffect fallback = mVibrationSettings.getFallbackEffect(prebaked.getId());
+            return new VibrationEffect.Prebaked(prebaked.getId(), prebaked.getEffectStrength(),
+                    fallback);
+        }
+        return effect;
+    }
+
     private VibrationAttributes fixupVibrationAttributes(VibrationAttributes attrs) {
         if (attrs == null) {
             attrs = DEFAULT_ATTRIBUTES;
@@ -388,16 +398,16 @@
             if (!verifyVibrationEffect(effect)) {
                 return;
             }
-
+            effect = fixupVibrationEffect(effect);
             attrs = fixupVibrationAttributes(attrs);
-            Vibration vib = new Vibration(token, mNextVibrationId.getAndIncrement(), effect, attrs,
-                    uid, opPkg, reason);
+            Vibration vib = new Vibration(token, mNextVibrationId.getAndIncrement(),
+                    CombinedVibrationEffect.createSynced(effect), attrs, uid, opPkg, reason);
 
             // If our current vibration is longer than the new vibration and is the same amplitude,
             // then just let the current one finish.
             synchronized (mLock) {
                 VibrationEffect currentEffect =
-                        mCurrentVibration == null ? null : mCurrentVibration.getEffect();
+                        mCurrentVibration == null ? null : getEffect(mCurrentVibration);
                 if (effect instanceof VibrationEffect.OneShot
                         && currentEffect instanceof VibrationEffect.OneShot) {
                     VibrationEffect.OneShot newOneShot = (VibrationEffect.OneShot) effect;
@@ -446,7 +456,6 @@
                     endVibrationLocked(vib, Vibration.Status.IGNORED_BACKGROUND);
                     return;
                 }
-                linkVibrationLocked(vib);
                 final long ident = Binder.clearCallingIdentity();
                 try {
                     doCancelVibrateLocked(Vibration.Status.CANCELLED);
@@ -474,6 +483,10 @@
         return effect.getDuration() == Long.MAX_VALUE;
     }
 
+    private static <T extends VibrationEffect> T getEffect(Vibration vib) {
+        return (T) ((CombinedVibrationEffect.Mono) vib.getEffect()).getEffect();
+    }
+
     private void endVibrationLocked(Vibration vib, Vibration.Status status) {
         final LinkedList<Vibration.DebugInfo> previousVibrations;
         switch (vib.attrs.getUsage()) {
@@ -527,7 +540,6 @@
 
     @GuardedBy("mLock")
     private void doCancelVibrateLocked(Vibration.Status status) {
-        Trace.asyncTraceEnd(Trace.TRACE_TAG_VIBRATOR, "vibration", 0);
         Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "doCancelVibrateLocked");
         try {
             if (mThread != null) {
@@ -547,18 +559,6 @@
         }
     }
 
-    // Callback for whenever the current vibration has finished played out
-    public void onVibrationFinished() {
-        if (DEBUG) {
-            Slog.d(TAG, "Vibration finished, cleaning up");
-        }
-        synchronized (mLock) {
-            // Make sure the vibration is really done. This also reports that the vibration is
-            // finished.
-            doCancelVibrateLocked(Vibration.Status.FINISHED);
-        }
-    }
-
     @GuardedBy("mLock")
     private void startVibrationLocked(final Vibration vib) {
         Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "startVibrationLocked");
@@ -579,24 +579,20 @@
         try {
             // Set current vibration before starting it, so callback will work.
             mCurrentVibration = vib;
-            VibrationEffect effect = vib.getEffect();
-            if (effect instanceof VibrationEffect.OneShot) {
-                Trace.asyncTraceBegin(Trace.TRACE_TAG_VIBRATOR, "vibration", 0);
-                doVibratorOn(vib);
-            } else if (effect instanceof VibrationEffect.Waveform) {
-                Trace.asyncTraceBegin(Trace.TRACE_TAG_VIBRATOR, "vibration", 0);
-                doVibratorWaveformEffectLocked(vib);
-            } else if (effect instanceof VibrationEffect.Prebaked) {
-                Trace.asyncTraceBegin(Trace.TRACE_TAG_VIBRATOR, "vibration", 0);
-                doVibratorPrebakedEffectLocked(vib);
-            } else if (effect instanceof VibrationEffect.Composed) {
-                Trace.asyncTraceBegin(Trace.TRACE_TAG_VIBRATOR, "vibration", 0);
-                doVibratorComposedEffectLocked(vib);
-            } else {
-                Slog.e(TAG, "Unknown vibration type, ignoring");
-                endVibrationLocked(vib, Vibration.Status.IGNORED_UNKNOWN_VIBRATION);
-                // The set current vibration is not actually playing, so drop it.
+            VibrationEffect effect = getEffect(vib);
+            Trace.asyncTraceBegin(Trace.TRACE_TAG_VIBRATOR, "vibration", 0);
+            boolean inputDevicesAvailable = mInputDeviceDelegate.vibrateIfAvailable(
+                    vib.uid, vib.opPkg, vib.getEffect(), vib.reason, vib.attrs);
+            if (inputDevicesAvailable) {
+                // The set current vibration is no longer being played by this service, so drop it.
                 mCurrentVibration = null;
+                endVibrationLocked(vib, Vibration.Status.FORWARDED_TO_INPUT_DEVICES);
+            } else {
+                // mThread better be null here. doCancelVibrate should always be
+                // called before startVibrationInnerLocked
+                mThread = new VibrationThread(vib, mVibratorController, mWakeLock,
+                        mBatteryStatsService, mVibrationCallbacks);
+                mThread.start();
             }
         } finally {
             Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR);
@@ -667,13 +663,13 @@
 
     @GuardedBy("mLock")
     private void reportFinishVibrationLocked(Vibration.Status status) {
+        Trace.asyncTraceEnd(Trace.TRACE_TAG_VIBRATOR, "vibration", 0);
         Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "reportFinishVibrationLocked");
         try {
             if (mCurrentVibration != null) {
                 endVibrationLocked(mCurrentVibration, status);
                 mAppOps.finishOp(AppOpsManager.OP_VIBRATE, mCurrentVibration.uid,
                         mCurrentVibration.opPkg);
-                unlinkVibrationLocked();
                 mCurrentVibration = null;
             }
         } finally {
@@ -681,30 +677,6 @@
         }
     }
 
-    @GuardedBy("mLock")
-    private void linkVibrationLocked(Vibration vib) {
-        // Unlink previously linked vibration, if any.
-        unlinkVibrationLocked();
-        // Only link against waveforms since they potentially don't have a finish if
-        // they're repeating. Let other effects just play out until they're done.
-        if (vib.getEffect() instanceof VibrationEffect.Waveform) {
-            try {
-                mCurrentVibrationDeathRecipient = new VibrationDeathRecipient(vib);
-                mCurrentVibrationDeathRecipient.linkToDeath();
-            } catch (RemoteException e) {
-                return;
-            }
-        }
-    }
-
-    @GuardedBy("mLock")
-    private void unlinkVibrationLocked() {
-        if (mCurrentVibrationDeathRecipient != null) {
-            mCurrentVibrationDeathRecipient.unlinkToDeath();
-            mCurrentVibrationDeathRecipient = null;
-        }
-    }
-
     private void updateVibrators() {
         synchronized (mLock) {
             mInputDeviceDelegate.updateInputDeviceVibrators(
@@ -715,40 +687,12 @@
         }
     }
 
-    private void doVibratorOn(Vibration vib) {
-        Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "doVibratorOn");
-        try {
-            final VibrationEffect.OneShot oneShot = (VibrationEffect.OneShot) vib.getEffect();
-            if (DEBUG) {
-                Slog.d(TAG, "Turning vibrator on for " + oneShot.getDuration() + " ms"
-                        + " with amplitude " + oneShot.getAmplitude() + ".");
-            }
-            boolean inputDevicesAvailable = mInputDeviceDelegate.vibrateIfAvailable(
-                    vib.uid, vib.opPkg, oneShot, vib.reason, vib.attrs);
-            if (inputDevicesAvailable) {
-                // The set current vibration is no longer being played by this service, so drop it.
-                mCurrentVibration = null;
-                endVibrationLocked(vib, Vibration.Status.FORWARDED_TO_INPUT_DEVICES);
-            } else {
-                noteVibratorOnLocked(vib.uid, oneShot.getDuration());
-                // Note: ordering is important here! Many haptic drivers will reset their
-                // amplitude when enabled, so we always have to enable first, then set the
-                // amplitude.
-                mVibratorController.on(oneShot.getDuration(), vib.id);
-                mVibratorController.setAmplitude(oneShot.getAmplitude());
-            }
-        } finally {
-            Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR);
-        }
-    }
-
     private void doVibratorOff() {
         Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "doVibratorOff");
         try {
             if (DEBUG) {
                 Slog.d(TAG, "Turning vibrator off.");
             }
-            noteVibratorOffLocked();
             boolean inputDevicesAvailable = mInputDeviceDelegate.cancelVibrateIfAvailable();
             if (!inputDevicesAvailable) {
                 mVibratorController.off();
@@ -758,95 +702,6 @@
         }
     }
 
-    @GuardedBy("mLock")
-    private void doVibratorWaveformEffectLocked(Vibration vib) {
-        Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "doVibratorWaveformEffectLocked");
-        try {
-            boolean inputDevicesAvailable = mInputDeviceDelegate.vibrateIfAvailable(
-                    vib.uid, vib.opPkg, vib.getEffect(), vib.reason, vib.attrs);
-            if (inputDevicesAvailable) {
-                // The set current vibration is no longer being played by this service, so drop it.
-                mCurrentVibration = null;
-                endVibrationLocked(vib, Vibration.Status.FORWARDED_TO_INPUT_DEVICES);
-            } else {
-                // mThread better be null here. doCancelVibrate should always be
-                // called before startNextVibrationLocked or startVibrationLocked.
-                mThread = new VibrateWaveformThread(vib);
-                mThread.start();
-            }
-        } finally {
-            Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR);
-        }
-    }
-
-    @GuardedBy("mLock")
-    private void doVibratorPrebakedEffectLocked(Vibration vib) {
-        Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "doVibratorPrebakedEffectLocked");
-        try {
-            final VibrationEffect.Prebaked prebaked = (VibrationEffect.Prebaked) vib.getEffect();
-            // Input devices don't support prebaked effect, so skip trying it with them and allow
-            // fallback to be attempted.
-            if (!mInputDeviceDelegate.isAvailable()) {
-                long duration = mVibratorController.on(prebaked, vib.id);
-                if (duration > 0) {
-                    noteVibratorOnLocked(vib.uid, duration);
-                    return;
-                }
-            }
-            endVibrationLocked(vib, Vibration.Status.IGNORED_UNSUPPORTED);
-            // The set current vibration is not actually playing, so drop it.
-            mCurrentVibration = null;
-
-            if (!prebaked.shouldFallback()) {
-                return;
-            }
-            VibrationEffect effect = mVibrationSettings.getFallbackEffect(prebaked.getId());
-            if (effect == null) {
-                Slog.w(TAG, "Failed to play prebaked effect, no fallback");
-                return;
-            }
-            Vibration fallbackVib = new Vibration(vib.token, mNextVibrationId.getAndIncrement(),
-                    effect, vib.attrs, vib.uid, vib.opPkg, vib.reason + " (fallback)");
-            // Set current vibration before starting it, so callback will work.
-            mCurrentVibration = fallbackVib;
-            linkVibrationLocked(fallbackVib);
-            applyVibrationIntensityScalingLocked(fallbackVib);
-            startVibrationInnerLocked(fallbackVib);
-        } finally {
-            Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR);
-        }
-    }
-
-    @GuardedBy("mLock")
-    private void doVibratorComposedEffectLocked(Vibration vib) {
-        Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "doVibratorComposedEffectLocked");
-
-        try {
-            final VibrationEffect.Composed composed = (VibrationEffect.Composed) vib.getEffect();
-            boolean inputDevicesAvailable = mInputDeviceDelegate.vibrateIfAvailable(
-                    vib.uid, vib.opPkg, composed, vib.reason, vib.attrs);
-            if (inputDevicesAvailable) {
-                // The set current vibration is no longer being played by this service, so drop it.
-                mCurrentVibration = null;
-                endVibrationLocked(vib, Vibration.Status.FORWARDED_TO_INPUT_DEVICES);
-                return;
-            } else if (!mVibratorController.hasCapability(IVibrator.CAP_COMPOSE_EFFECTS)) {
-                // The set current vibration is not actually playing, so drop it.
-                mCurrentVibration = null;
-                endVibrationLocked(vib, Vibration.Status.IGNORED_UNSUPPORTED);
-                return;
-            }
-
-            mVibratorController.on(composed, vib.id);
-
-            // Composed effects don't actually give us an estimated duration, so we just guess here.
-            noteVibratorOnLocked(vib.uid, 10 * composed.getPrimitiveEffects().size());
-        } finally {
-            Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR);
-        }
-
-    }
-
     private boolean isSystemHapticFeedback(Vibration vib) {
         if (vib.attrs.getUsage() != VibrationAttributes.USAGE_TOUCH) {
             return false;
@@ -854,27 +709,6 @@
         return vib.uid == Process.SYSTEM_UID || vib.uid == 0 || mSystemUiPackage.equals(vib.opPkg);
     }
 
-    private void noteVibratorOnLocked(int uid, long millis) {
-        try {
-            mBatteryStatsService.noteVibratorOn(uid, millis);
-            FrameworkStatsLog.write_non_chained(FrameworkStatsLog.VIBRATOR_STATE_CHANGED, uid, null,
-                    FrameworkStatsLog.VIBRATOR_STATE_CHANGED__STATE__ON, millis);
-            mCurVibUid = uid;
-        } catch (RemoteException e) {
-        }
-    }
-
-    private void noteVibratorOffLocked() {
-        if (mCurVibUid >= 0) {
-            try {
-                mBatteryStatsService.noteVibratorOff(mCurVibUid);
-                FrameworkStatsLog.write_non_chained(FrameworkStatsLog.VIBRATOR_STATE_CHANGED,
-                        mCurVibUid, null, FrameworkStatsLog.VIBRATOR_STATE_CHANGED__STATE__OFF, 0);
-            } catch (RemoteException e) { }
-            mCurVibUid = -1;
-        }
-    }
-
     private void dumpInternal(PrintWriter pw) {
         pw.println("Vibrator Service:");
         synchronized (mLock) {
@@ -972,156 +806,6 @@
         proto.flush();
     }
 
-    /** Thread that plays a single {@link VibrationEffect.Waveform}. */
-    private class VibrateWaveformThread extends Thread {
-        private final VibrationEffect.Waveform mWaveform;
-        private final Vibration mVibration;
-
-        private boolean mForceStop;
-
-        VibrateWaveformThread(Vibration vib) {
-            mWaveform = (VibrationEffect.Waveform) vib.getEffect();
-            mVibration = new Vibration(vib.token, /* id= */ 0, /* effect= */ null, vib.attrs,
-                    vib.uid, vib.opPkg, vib.reason);
-            mTmpWorkSource.set(vib.uid);
-            mWakeLock.setWorkSource(mTmpWorkSource);
-        }
-
-        private void delayLocked(long wakeUpTime) {
-            Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "delayLocked");
-            try {
-                long durationRemaining = wakeUpTime - SystemClock.uptimeMillis();
-                while (durationRemaining > 0) {
-                    try {
-                        this.wait(durationRemaining);
-                    } catch (InterruptedException e) {
-                    }
-                    if (mForceStop) {
-                        break;
-                    }
-                    durationRemaining = wakeUpTime - SystemClock.uptimeMillis();
-                }
-            } finally {
-                Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR);
-            }
-        }
-
-        public void run() {
-            Process.setThreadPriority(Process.THREAD_PRIORITY_URGENT_DISPLAY);
-            mWakeLock.acquire();
-            try {
-                boolean finished = playWaveform();
-                if (finished) {
-                    onVibrationFinished();
-                }
-            } finally {
-                mWakeLock.release();
-            }
-        }
-
-        /**
-         * Play the waveform.
-         *
-         * @return true if it finished naturally, false otherwise (e.g. it was canceled).
-         */
-        public boolean playWaveform() {
-            Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "playWaveform");
-            try {
-                synchronized (this) {
-                    final long[] timings = mWaveform.getTimings();
-                    final int[] amplitudes = mWaveform.getAmplitudes();
-                    final int len = timings.length;
-                    final int repeat = mWaveform.getRepeatIndex();
-
-                    int index = 0;
-                    long nextStepStartTime = SystemClock.uptimeMillis();
-                    long nextVibratorStopTime = 0;
-                    while (!mForceStop) {
-                        if (index < len) {
-                            final int amplitude = amplitudes[index];
-                            final long duration = timings[index++];
-                            if (duration <= 0) {
-                                continue;
-                            }
-                            if (amplitude != 0) {
-                                long now = SystemClock.uptimeMillis();
-                                if (nextVibratorStopTime <= now) {
-                                    // Telling the vibrator to start multiple times usually causes
-                                    // effects to feel "choppy" because the motor resets at every on
-                                    // command.  Instead we figure out how long our next "on" period
-                                    // is going to be, tell the motor to stay on for the full
-                                    // duration, and then wake up to change the amplitude at the
-                                    // appropriate intervals.
-                                    long onDuration = getTotalOnDuration(
-                                            timings, amplitudes, index - 1, repeat);
-                                    mVibration.updateEffect(
-                                            VibrationEffect.createOneShot(onDuration, amplitude));
-                                    doVibratorOn(mVibration);
-                                    nextVibratorStopTime = now + onDuration;
-                                } else {
-                                    // Vibrator is already ON, so just change its amplitude.
-                                    mVibratorController.setAmplitude(amplitude);
-                                }
-                            } else {
-                                // Previous vibration should have already finished, but we make sure
-                                // the vibrator will be off for the next step when amplitude is 0.
-                                doVibratorOff();
-                            }
-
-                            // We wait until the time this waveform step was supposed to end,
-                            // calculated from the time it was supposed to start. All start times
-                            // are calculated from the waveform original start time by adding the
-                            // input durations. Any scheduling or processing delay should not affect
-                            // this step's perceived total duration. They will be amortized here.
-                            nextStepStartTime += duration;
-                            delayLocked(nextStepStartTime);
-                        } else if (repeat < 0) {
-                            break;
-                        } else {
-                            index = repeat;
-                        }
-                    }
-                    return !mForceStop;
-                }
-            } finally {
-                Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR);
-            }
-        }
-
-        public void cancel() {
-            synchronized (this) {
-                mThread.mForceStop = true;
-                mThread.notify();
-            }
-        }
-
-        /**
-         * Get the duration the vibrator will be on starting at startIndex until the next time it's
-         * off.
-         */
-        private long getTotalOnDuration(
-                long[] timings, int[] amplitudes, int startIndex, int repeatIndex) {
-            int i = startIndex;
-            long timing = 0;
-            while (amplitudes[i] != 0) {
-                timing += timings[i++];
-                if (i >= timings.length) {
-                    if (repeatIndex >= 0) {
-                        i = repeatIndex;
-                        // prevent infinite loop
-                        repeatIndex = -1;
-                    } else {
-                        break;
-                    }
-                }
-                if (i == startIndex) {
-                    return 1000;
-                }
-            }
-            return timing;
-        }
-    }
-
     /** Point of injection for test dependencies */
     @VisibleForTesting
     static class Injector {
diff --git a/services/core/java/com/android/server/input/InputManagerService.java b/services/core/java/com/android/server/input/InputManagerService.java
index 3e0d040..23c70ee 100644
--- a/services/core/java/com/android/server/input/InputManagerService.java
+++ b/services/core/java/com/android/server/input/InputManagerService.java
@@ -1856,6 +1856,13 @@
         }
 
         VibrationInfo(VibrationEffect effect) {
+            // First replace prebaked effects with its fallback, if any available.
+            if (effect instanceof VibrationEffect.Prebaked) {
+                VibrationEffect fallback = ((VibrationEffect.Prebaked) effect).getFallbackEffect();
+                if (fallback != null) {
+                    effect = fallback;
+                }
+            }
             if (effect instanceof VibrationEffect.OneShot) {
                 VibrationEffect.OneShot oneShot = (VibrationEffect.OneShot) effect;
                 mPattern = new long[] { 0, oneShot.getDuration() };
@@ -1882,8 +1889,7 @@
                     throw new ArrayIndexOutOfBoundsException();
                 }
             } else {
-                // TODO: Add support for prebaked effects
-                Slog.w(TAG, "Pre-baked effects aren't supported on input devices");
+                Slog.w(TAG, "Pre-baked and composed effects aren't supported on input devices");
             }
         }
     }
diff --git a/services/core/java/com/android/server/vibrator/InputDeviceDelegate.java b/services/core/java/com/android/server/vibrator/InputDeviceDelegate.java
index edbc058..3968723 100644
--- a/services/core/java/com/android/server/vibrator/InputDeviceDelegate.java
+++ b/services/core/java/com/android/server/vibrator/InputDeviceDelegate.java
@@ -18,6 +18,7 @@
 
 import android.content.Context;
 import android.hardware.input.InputManager;
+import android.os.CombinedVibrationEffect;
 import android.os.Handler;
 import android.os.VibrationAttributes;
 import android.os.VibrationEffect;
@@ -84,11 +85,21 @@
      *
      * @return {@link #isAvailable()}
      */
-    public boolean vibrateIfAvailable(int uid, String opPkg, VibrationEffect effect,
+    public boolean vibrateIfAvailable(int uid, String opPkg, CombinedVibrationEffect effect,
             String reason, VibrationAttributes attrs) {
         synchronized (mLock) {
-            for (int i = 0; i < mInputDeviceVibrators.size(); i++) {
-                mInputDeviceVibrators.valueAt(i).vibrate(uid, opPkg, effect, reason, attrs);
+            // TODO(b/159207608): Pass on the combined vibration once InputManager is merged
+            if (effect instanceof CombinedVibrationEffect.Mono) {
+                VibrationEffect e = ((CombinedVibrationEffect.Mono) effect).getEffect();
+                if (e instanceof VibrationEffect.Prebaked) {
+                    VibrationEffect fallback = ((VibrationEffect.Prebaked) e).getFallbackEffect();
+                    if (fallback != null) {
+                        e = fallback;
+                    }
+                }
+                for (int i = 0; i < mInputDeviceVibrators.size(); i++) {
+                    mInputDeviceVibrators.valueAt(i).vibrate(uid, opPkg, e, reason, attrs);
+                }
             }
             return mInputDeviceVibrators.size() > 0;
         }
diff --git a/services/core/java/com/android/server/vibrator/Vibration.java b/services/core/java/com/android/server/vibrator/Vibration.java
index b0266d0..fe3b03ab 100644
--- a/services/core/java/com/android/server/vibrator/Vibration.java
+++ b/services/core/java/com/android/server/vibrator/Vibration.java
@@ -18,6 +18,7 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.os.CombinedVibrationEffect;
 import android.os.IBinder;
 import android.os.SystemClock;
 import android.os.VibrationAttributes;
@@ -72,14 +73,14 @@
 
     /** The actual effect to be played. */
     @Nullable
-    private VibrationEffect mEffect;
+    private CombinedVibrationEffect mEffect;
 
     /**
      * The original effect that was requested. Typically these two things differ because the effect
      * was scaled based on the users vibration intensity settings.
      */
     @Nullable
-    private VibrationEffect mOriginalEffect;
+    private CombinedVibrationEffect mOriginalEffect;
 
     /**
      * Start/end times in unix epoch time. Only to be used for debugging purposes and to correlate
@@ -90,7 +91,7 @@
     private long mEndTimeDebug;
     private Status mStatus;
 
-    public Vibration(IBinder token, int id, VibrationEffect effect,
+    public Vibration(IBinder token, int id, CombinedVibrationEffect effect,
             VibrationAttributes attrs, int uid, String opPkg, String reason) {
         this.token = token;
         this.mEffect = effect;
@@ -124,7 +125,7 @@
      * Replace this vibration effect if given {@code scaledEffect} is different, preserving the
      * original one for debug purposes.
      */
-    public void updateEffect(@NonNull VibrationEffect newEffect) {
+    public void updateEffect(@NonNull CombinedVibrationEffect newEffect) {
         if (newEffect.equals(mEffect)) {
             return;
         }
@@ -139,7 +140,7 @@
 
     /** Return the effect that should be played by this vibration. */
     @Nullable
-    public VibrationEffect getEffect() {
+    public CombinedVibrationEffect getEffect() {
         return mEffect;
     }
 
@@ -154,8 +155,8 @@
     public static final class DebugInfo {
         private final long mStartTimeDebug;
         private final long mEndTimeDebug;
-        private final VibrationEffect mEffect;
-        private final VibrationEffect mOriginalEffect;
+        private final CombinedVibrationEffect mEffect;
+        private final CombinedVibrationEffect mOriginalEffect;
         private final float mScale;
         private final VibrationAttributes mAttrs;
         private final int mUid;
@@ -163,8 +164,8 @@
         private final String mReason;
         private final Status mStatus;
 
-        public DebugInfo(long startTimeDebug, long endTimeDebug, VibrationEffect effect,
-                VibrationEffect originalEffect, float scale, VibrationAttributes attrs,
+        public DebugInfo(long startTimeDebug, long endTimeDebug, CombinedVibrationEffect effect,
+                CombinedVibrationEffect originalEffect, float scale, VibrationAttributes attrs,
                 int uid, String opPkg, String reason, Status status) {
             mStartTimeDebug = startTimeDebug;
             mEndTimeDebug = endTimeDebug;
@@ -228,7 +229,22 @@
             proto.end(token);
         }
 
-        private void dumpEffect(ProtoOutputStream proto, long fieldId, VibrationEffect effect) {
+        private void dumpEffect(
+                ProtoOutputStream proto, long fieldId, CombinedVibrationEffect combinedEffect) {
+            VibrationEffect effect;
+            // TODO(b/177805090): add proper support for dumping combined effects to proto
+            if (combinedEffect instanceof CombinedVibrationEffect.Mono) {
+                effect = ((CombinedVibrationEffect.Mono) combinedEffect).getEffect();
+            } else if (combinedEffect instanceof CombinedVibrationEffect.Stereo) {
+                effect = ((CombinedVibrationEffect.Stereo) combinedEffect).getEffects().valueAt(0);
+            } else if (combinedEffect instanceof CombinedVibrationEffect.Sequential) {
+                dumpEffect(proto, fieldId,
+                        ((CombinedVibrationEffect.Sequential) combinedEffect).getEffects().get(0));
+                return;
+            } else {
+                // Unknown combined effect, skip dump.
+                return;
+            }
             final long token = proto.start(fieldId);
             if (effect instanceof VibrationEffect.OneShot) {
                 dumpEffect(proto, VibrationEffectProto.ONESHOT, (VibrationEffect.OneShot) effect);
diff --git a/services/core/java/com/android/server/vibrator/VibrationScaler.java b/services/core/java/com/android/server/vibrator/VibrationScaler.java
index 5f7e47d..0fa4fe1 100644
--- a/services/core/java/com/android/server/vibrator/VibrationScaler.java
+++ b/services/core/java/com/android/server/vibrator/VibrationScaler.java
@@ -18,12 +18,16 @@
 
 import android.content.Context;
 import android.hardware.vibrator.V1_0.EffectStrength;
+import android.os.CombinedVibrationEffect;
 import android.os.IExternalVibratorService;
 import android.os.VibrationEffect;
 import android.os.Vibrator;
 import android.util.Slog;
 import android.util.SparseArray;
 
+import java.util.List;
+import java.util.Objects;
+
 /** Controls vibration scaling. */
 // TODO(b/159207608): Make this package-private once vibrator services are moved to this package
 public final class VibrationScaler {
@@ -87,6 +91,43 @@
     }
 
     /**
+     * Scale a {@link CombinedVibrationEffect} based on the given usage hint for this vibration.
+     *
+     * @param combinedEffect the effect to be scaled
+     * @param usageHint      one of VibrationAttributes.USAGE_*
+     * @return The same given effect, if no changes were made, or a new
+     * {@link CombinedVibrationEffect} with resolved and scaled amplitude
+     */
+    public <T extends CombinedVibrationEffect> T scale(CombinedVibrationEffect combinedEffect,
+            int usageHint) {
+        if (combinedEffect instanceof CombinedVibrationEffect.Mono) {
+            VibrationEffect effect = ((CombinedVibrationEffect.Mono) combinedEffect).getEffect();
+            return (T) CombinedVibrationEffect.createSynced(scale(effect, usageHint));
+        } else if (combinedEffect instanceof CombinedVibrationEffect.Stereo) {
+            SparseArray<VibrationEffect> effects =
+                    ((CombinedVibrationEffect.Stereo) combinedEffect).getEffects();
+            CombinedVibrationEffect.SyncedCombination combination =
+                    CombinedVibrationEffect.startSynced();
+            for (int i = 0; i < effects.size(); i++) {
+                combination.addVibrator(effects.keyAt(i), scale(effects.valueAt(i), usageHint));
+            }
+            return (T) combination.combine();
+        } else if (combinedEffect instanceof CombinedVibrationEffect.Sequential) {
+            List<CombinedVibrationEffect> effects =
+                    ((CombinedVibrationEffect.Sequential) combinedEffect).getEffects();
+            CombinedVibrationEffect.SequentialCombination combination =
+                    CombinedVibrationEffect.startSequential();
+            for (CombinedVibrationEffect effect : effects) {
+                combination.addNext(scale(effect, usageHint));
+            }
+            return (T) combination.combine();
+        } else {
+            // Unknown combination, return same effect.
+            return (T) combinedEffect;
+        }
+    }
+
+    /**
      * Scale a {@link VibrationEffect} based on the given usage hint for this vibration.
      *
      * @param effect    the effect to be scaled
@@ -100,13 +141,23 @@
             int intensity = mSettingsController.getCurrentIntensity(usageHint);
             int newStrength = intensityToEffectStrength(intensity);
             VibrationEffect.Prebaked prebaked = (VibrationEffect.Prebaked) effect;
+            int strength = prebaked.getEffectStrength();
+            VibrationEffect fallback = prebaked.getFallbackEffect();
 
-            if (prebaked.getEffectStrength() == newStrength) {
+            if (fallback != null) {
+                VibrationEffect scaledFallback = scale(fallback, usageHint);
+                if (strength == newStrength && Objects.equals(fallback, scaledFallback)) {
+                    return (T) prebaked;
+                }
+
+                return (T) new VibrationEffect.Prebaked(prebaked.getId(), newStrength,
+                        scaledFallback);
+            } else if (strength == newStrength) {
                 return (T) prebaked;
+            } else {
+                return (T) new VibrationEffect.Prebaked(prebaked.getId(), prebaked.shouldFallback(),
+                        newStrength);
             }
-
-            return (T) new VibrationEffect.Prebaked(
-                    prebaked.getId(), prebaked.shouldFallback(), newStrength);
         }
 
         effect = effect.resolve(mDefaultVibrationAmplitude);
@@ -124,8 +175,6 @@
         return effect.scale(scale.factor);
     }
 
-
-
     /** Mapping of Vibrator.VIBRATION_INTENSITY_* values to {@link EffectStrength}. */
     private static int intensityToEffectStrength(int intensity) {
         switch (intensity) {
diff --git a/services/core/java/com/android/server/vibrator/VibrationThread.java b/services/core/java/com/android/server/vibrator/VibrationThread.java
new file mode 100644
index 0000000..a4d888b
--- /dev/null
+++ b/services/core/java/com/android/server/vibrator/VibrationThread.java
@@ -0,0 +1,791 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.vibrator;
+
+import android.annotation.Nullable;
+import android.os.CombinedVibrationEffect;
+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.WorkSource;
+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 com.google.android.collect.Lists;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.PriorityQueue;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+/** Plays a {@link Vibration} in dedicated thread. */
+// TODO(b/159207608): Make this package-private once vibrator services are moved to this package
+public 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 synced vibration step as a timeout for the callback
+     * wait, to ensure it finishes even when callbacks from individual vibrators are lost.
+     */
+    private static final long CALLBACKS_EXTRA_TIMEOUT = 100;
+
+    /** Callbacks for playing a {@link Vibration}. */
+    public interface VibrationCallbacks {
+
+        /**
+         * Callback triggered before starting a synchronized vibration step. This will be called
+         * with {@code requiredCapabilities = 0} if no synchronization is required.
+         *
+         * @param requiredCapabilities The required syncing capabilities for this preparation step.
+         *                             Expects a combination of values from
+         *                             IVibratorManager.CAP_PREPARE_* and
+         *                             IVibratorManager.CAP_MIXED_TRIGGER_*.
+         * @param vibratorIds          The id of the vibrators to be prepared.
+         */
+        void prepareSyncedVibration(int requiredCapabilities, int[] vibratorIds);
+
+        /** Callback triggered after synchronized vibrations were prepared. */
+        void triggerSyncedVibration(long vibrationId);
+
+        /** Callback triggered when vibration thread is complete. */
+        void onVibrationEnded(long vibrationId, Vibration.Status status);
+    }
+
+    private final Object mLock = new Object();
+    private final WorkSource mWorkSource = new WorkSource();
+    private final PowerManager.WakeLock mWakeLock;
+    private final IBatteryStats mBatteryStatsService;
+    private final Vibration mVibration;
+    private final VibrationCallbacks mCallbacks;
+    private final SparseArray<VibratorController> mVibrators;
+
+    @GuardedBy("mLock")
+    @Nullable
+    private VibrateStep mCurrentVibrateStep;
+    @GuardedBy("this")
+    private boolean mForceStop;
+
+    // TODO(b/159207608): Remove this constructor once VibratorService is removed
+    public VibrationThread(Vibration vib, VibratorController vibrator,
+            PowerManager.WakeLock wakeLock, IBatteryStats batteryStatsService,
+            VibrationCallbacks callbacks) {
+        this(vib, toSparseArray(vibrator), wakeLock, batteryStatsService, callbacks);
+    }
+
+    public VibrationThread(Vibration vib, SparseArray<VibratorController> availableVibrators,
+            PowerManager.WakeLock wakeLock, IBatteryStats batteryStatsService,
+            VibrationCallbacks callbacks) {
+        mVibration = vib;
+        mCallbacks = callbacks;
+        mWakeLock = wakeLock;
+        mWorkSource.set(vib.uid);
+        mWakeLock.setWorkSource(mWorkSource);
+        mBatteryStatsService = batteryStatsService;
+
+        CombinedVibrationEffect effect = vib.getEffect();
+        mVibrators = new SparseArray<>();
+        for (int i = 0; i < availableVibrators.size(); i++) {
+            if (effect.hasVibrator(availableVibrators.keyAt(i))) {
+                mVibrators.put(availableVibrators.keyAt(i), availableVibrators.valueAt(i));
+            }
+        }
+    }
+
+    @Override
+    public void binderDied() {
+        cancel();
+    }
+
+    @Override
+    public void run() {
+        Process.setThreadPriority(Process.THREAD_PRIORITY_URGENT_DISPLAY);
+        mWakeLock.acquire();
+        try {
+            mVibration.token.linkToDeath(this, 0);
+            Vibration.Status status = playVibration();
+            mCallbacks.onVibrationEnded(mVibration.id, status);
+        } catch (RemoteException e) {
+            Slog.e(TAG, "Error linking vibration to token death", e);
+        } finally {
+            mVibration.token.unlinkToDeath(this, 0);
+            mWakeLock.release();
+        }
+    }
+
+    /** Cancel current vibration and shuts down the thread gracefully. */
+    public void cancel() {
+        synchronized (this) {
+            mForceStop = true;
+            notify();
+        }
+    }
+
+    /** Notify current vibration that a step has completed on given vibrator. */
+    public void vibratorComplete(int vibratorId) {
+        synchronized (mLock) {
+            if (mCurrentVibrateStep != null) {
+                mCurrentVibrateStep.vibratorComplete(vibratorId);
+            }
+        }
+    }
+
+    @VisibleForTesting
+    SparseArray<VibratorController> getVibrators() {
+        return mVibrators;
+    }
+
+    private Vibration.Status playVibration() {
+        Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "playVibration");
+        try {
+            List<Step> steps = generateSteps(mVibration.getEffect());
+            if (steps.isEmpty()) {
+                // No vibrator matching any incoming vibration effect.
+                return Vibration.Status.IGNORED;
+            }
+            Vibration.Status status = Vibration.Status.FINISHED;
+            final int stepCount = steps.size();
+            for (int i = 0; i < stepCount; i++) {
+                Step step = steps.get(i);
+                synchronized (mLock) {
+                    if (step instanceof VibrateStep) {
+                        mCurrentVibrateStep = (VibrateStep) step;
+                    } else {
+                        mCurrentVibrateStep = null;
+                    }
+                }
+                status = step.play();
+                if (status != Vibration.Status.FINISHED) {
+                    // This step was ignored by the vibrators, probably effects were unsupported.
+                    break;
+                }
+                if (mForceStop) {
+                    break;
+                }
+            }
+            if (mForceStop) {
+                return Vibration.Status.CANCELLED;
+            }
+            return status;
+        } finally {
+            Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR);
+        }
+    }
+
+    private List<Step> generateSteps(CombinedVibrationEffect effect) {
+        if (effect instanceof CombinedVibrationEffect.Sequential) {
+            CombinedVibrationEffect.Sequential sequential =
+                    (CombinedVibrationEffect.Sequential) effect;
+            List<Step> steps = new ArrayList<>();
+            final int sequentialEffectCount = sequential.getEffects().size();
+            for (int i = 0; i < sequentialEffectCount; i++) {
+                int delay = sequential.getDelays().get(i);
+                if (delay > 0) {
+                    steps.add(new DelayStep(delay));
+                }
+                steps.addAll(generateSteps(sequential.getEffects().get(i)));
+            }
+            final int stepCount = steps.size();
+            for (int i = 0; i < stepCount; i++) {
+                if (steps.get(i) instanceof VibrateStep) {
+                    return steps;
+                }
+            }
+            // No valid vibrate step was generated, ignore effect completely.
+            return Lists.newArrayList();
+        }
+        VibrateStep vibrateStep = null;
+        if (effect instanceof CombinedVibrationEffect.Mono) {
+            vibrateStep = createVibrateStep(mapToAvailableVibrators(
+                    ((CombinedVibrationEffect.Mono) effect).getEffect()));
+        } else if (effect instanceof CombinedVibrationEffect.Stereo) {
+            vibrateStep = createVibrateStep(filterByAvailableVibrators(
+                    ((CombinedVibrationEffect.Stereo) effect).getEffects()));
+        }
+        return vibrateStep == null ? Lists.newArrayList() : Lists.newArrayList(vibrateStep);
+    }
+
+    @Nullable
+    private VibrateStep createVibrateStep(SparseArray<VibrationEffect> effects) {
+        if (effects.size() == 0) {
+            return null;
+        }
+        if (effects.size() == 1) {
+            // Create simplified step that handles a single vibrator.
+            return new SingleVibrateStep(mVibrators.get(effects.keyAt(0)), effects.valueAt(0));
+        }
+        return new SyncedVibrateStep(effects);
+    }
+
+    private SparseArray<VibrationEffect> mapToAvailableVibrators(VibrationEffect effect) {
+        SparseArray<VibrationEffect> mappedEffects = new SparseArray<>(mVibrators.size());
+        for (int i = 0; i < mVibrators.size(); i++) {
+            mappedEffects.put(mVibrators.keyAt(i), effect);
+        }
+        return mappedEffects;
+    }
+
+    private SparseArray<VibrationEffect> filterByAvailableVibrators(
+            SparseArray<VibrationEffect> effects) {
+        SparseArray<VibrationEffect> filteredEffects = new SparseArray<>();
+        for (int i = 0; i < effects.size(); i++) {
+            if (mVibrators.contains(effects.keyAt(i))) {
+                filteredEffects.put(effects.keyAt(i), effects.valueAt(i));
+            }
+        }
+        return filteredEffects;
+    }
+
+    private static SparseArray<VibratorController> toSparseArray(VibratorController controller) {
+        SparseArray<VibratorController> array = new SparseArray<>(1);
+        array.put(controller.getVibratorInfo().getId(), controller);
+        return array;
+    }
+
+    /**
+     * Get the duration the vibrator will be on for given {@code waveform}, starting at {@code
+     * startIndex} until the next time it's vibrating amplitude is zero.
+     */
+    private static long getVibratorOnDuration(VibrationEffect.Waveform waveform, int startIndex) {
+        long[] timings = waveform.getTimings();
+        int[] amplitudes = waveform.getAmplitudes();
+        int repeatIndex = waveform.getRepeatIndex();
+        int i = startIndex;
+        long timing = 0;
+        while (timings[i] == 0 || amplitudes[i] != 0) {
+            timing += timings[i++];
+            if (i >= timings.length) {
+                if (repeatIndex >= 0) {
+                    i = repeatIndex;
+                    // prevent infinite loop
+                    repeatIndex = -1;
+                } else {
+                    break;
+                }
+            }
+            if (i == startIndex) {
+                return 1000;
+            }
+        }
+        return timing;
+    }
+
+    /**
+     * Sleeps until given {@code wakeUpTime}.
+     *
+     * <p>This stops immediately when {@link #cancel()} is called.
+     */
+    private void waitUntil(long wakeUpTime) {
+        synchronized (this) {
+            long durationRemaining = wakeUpTime - SystemClock.uptimeMillis();
+            while (durationRemaining > 0) {
+                try {
+                    VibrationThread.this.wait(durationRemaining);
+                } catch (InterruptedException e) {
+                }
+                if (mForceStop) {
+                    break;
+                }
+                durationRemaining = wakeUpTime - SystemClock.uptimeMillis();
+            }
+        }
+    }
+
+    /**
+     * Sleeps until given {@link CountDownLatch} has finished or {@code wakeUpTime} was reached.
+     *
+     * <p>This stops immediately when {@link #cancel()} is called.
+     */
+    private void awaitUntil(CountDownLatch counter, long wakeUpTime) {
+        synchronized (this) {
+            long durationRemaining = wakeUpTime - SystemClock.uptimeMillis();
+            while (counter.getCount() > 0 && durationRemaining > 0) {
+                try {
+                    counter.await(durationRemaining, TimeUnit.MILLISECONDS);
+                } catch (InterruptedException e) {
+                }
+                if (mForceStop) {
+                    break;
+                }
+                durationRemaining = wakeUpTime - SystemClock.uptimeMillis();
+            }
+        }
+    }
+
+    private void noteVibratorOn(long duration) {
+        try {
+            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) {
+        }
+    }
+
+    /** Represent a single synchronized step while playing a {@link CombinedVibrationEffect}. */
+    private interface Step {
+        Vibration.Status play();
+    }
+
+    /** Represent a synchronized vibration step. */
+    private interface VibrateStep extends Step {
+        /** Callback to notify a vibrator has finished playing a effect. */
+        void vibratorComplete(int vibratorId);
+    }
+
+    /** Represent a vibration on a single vibrator. */
+    private final class SingleVibrateStep implements VibrateStep {
+        private final VibratorController mVibrator;
+        private final VibrationEffect mEffect;
+        private final CountDownLatch mCounter;
+
+        SingleVibrateStep(VibratorController vibrator, VibrationEffect effect) {
+            mVibrator = vibrator;
+            mEffect = effect;
+            mCounter = new CountDownLatch(1);
+        }
+
+        @Override
+        public void vibratorComplete(int vibratorId) {
+            if (mVibrator.getVibratorInfo().getId() != vibratorId) {
+                return;
+            }
+            if (mEffect instanceof VibrationEffect.OneShot
+                    || mEffect instanceof VibrationEffect.Waveform) {
+                // Oneshot and Waveform are controlled by amplitude steps, ignore callbacks.
+                return;
+            }
+            mVibrator.off();
+            mCounter.countDown();
+        }
+
+        @Override
+        public Vibration.Status play() {
+            Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "SingleVibrateStep");
+            long duration = -1;
+            try {
+                if (DEBUG) {
+                    Slog.d(TAG, "SingleVibrateStep starting...");
+                }
+                long startTime = SystemClock.uptimeMillis();
+                duration = vibratePredefined(mEffect);
+
+                if (duration > 0) {
+                    noteVibratorOn(duration);
+                    // Vibration is playing with no need to control amplitudes, just wait for native
+                    // callback or timeout.
+                    awaitUntil(mCounter, startTime + duration + CALLBACKS_EXTRA_TIMEOUT);
+                    return Vibration.Status.FINISHED;
+                }
+
+                startTime = SystemClock.uptimeMillis();
+                AmplitudeStep amplitudeStep = vibrateWithAmplitude(mEffect, startTime);
+                if (amplitudeStep == null) {
+                    // Vibration could not be played with or without amplitude steps.
+                    return Vibration.Status.IGNORED_UNSUPPORTED;
+                }
+
+                duration = mEffect instanceof VibrationEffect.Prebaked
+                        ? ((VibrationEffect.Prebaked) mEffect).getFallbackEffect().getDuration()
+                        : mEffect.getDuration();
+                if (duration < Long.MAX_VALUE) {
+                    // Only report vibration stats if we know how long we will be vibrating.
+                    noteVibratorOn(duration);
+                }
+                while (amplitudeStep != null) {
+                    waitUntil(amplitudeStep.startTime);
+                    if (mForceStop) {
+                        mVibrator.off();
+                        return Vibration.Status.CANCELLED;
+                    }
+                    amplitudeStep.play();
+                    amplitudeStep = amplitudeStep.nextStep();
+                }
+
+                return Vibration.Status.FINISHED;
+            } finally {
+                if (duration > 0 && duration < Long.MAX_VALUE) {
+                    noteVibratorOff();
+                }
+                if (DEBUG) {
+                    Slog.d(TAG, "SingleVibrateStep step done.");
+                }
+                Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR);
+            }
+        }
+
+        /**
+         * Try to vibrate given effect using prebaked or composed predefined effects.
+         *
+         * @return the duration, in millis, expected for the vibration, or -1 if effect cannot be
+         * played with predefined effects.
+         */
+        private long vibratePredefined(VibrationEffect effect) {
+            if (effect instanceof VibrationEffect.Prebaked) {
+                VibrationEffect.Prebaked prebaked = (VibrationEffect.Prebaked) effect;
+                long duration = mVibrator.on(prebaked, mVibration.id);
+                if (duration > 0) {
+                    return duration;
+                }
+                if (prebaked.getFallbackEffect() != null) {
+                    return vibratePredefined(prebaked.getFallbackEffect());
+                }
+            } else if (effect instanceof VibrationEffect.Composed) {
+                VibrationEffect.Composed composed = (VibrationEffect.Composed) effect;
+                return mVibrator.on(composed, mVibration.id);
+            }
+            // OneShot and Waveform effects require amplitude change after calling vibrator.on.
+            return -1;
+        }
+
+        /**
+         * Try to vibrate given effect using {@link AmplitudeStep} to control vibration amplitude.
+         *
+         * @return the {@link AmplitudeStep} to start this vibration, or {@code null} if vibration
+         * do not require amplitude control.
+         */
+        private AmplitudeStep vibrateWithAmplitude(VibrationEffect effect, long startTime) {
+            int vibratorId = mVibrator.getVibratorInfo().getId();
+            if (effect instanceof VibrationEffect.OneShot) {
+                VibrationEffect.OneShot oneShot = (VibrationEffect.OneShot) effect;
+                return new AmplitudeStep(vibratorId, oneShot, startTime, startTime);
+            } else if (effect instanceof VibrationEffect.Waveform) {
+                VibrationEffect.Waveform waveform = (VibrationEffect.Waveform) effect;
+                return new AmplitudeStep(vibratorId, waveform, startTime, startTime);
+            } else if (effect instanceof VibrationEffect.Prebaked) {
+                VibrationEffect.Prebaked prebaked = (VibrationEffect.Prebaked) effect;
+                if (prebaked.getFallbackEffect() != null) {
+                    return vibrateWithAmplitude(prebaked.getFallbackEffect(), startTime);
+                }
+            }
+            return null;
+        }
+    }
+
+    /** Represent a synchronized vibration step on multiple vibrators. */
+    private final class SyncedVibrateStep implements VibrateStep {
+        private final SparseArray<VibrationEffect> mEffects;
+        private final CountDownLatch mActiveVibratorCounter;
+
+        private final int mRequiredCapabilities;
+        private final int[] mVibratorIds;
+
+        SyncedVibrateStep(SparseArray<VibrationEffect> effects) {
+            mEffects = effects;
+            mActiveVibratorCounter = new CountDownLatch(mEffects.size());
+            // TODO(b/159207608): Calculate required capabilities for syncing this step.
+            mRequiredCapabilities = 0;
+            mVibratorIds = new int[effects.size()];
+            for (int i = 0; i < effects.size(); i++) {
+                mVibratorIds[i] = effects.keyAt(i);
+            }
+        }
+
+        @Override
+        public void vibratorComplete(int vibratorId) {
+            VibrationEffect effect = mEffects.get(vibratorId);
+            if (effect == null) {
+                return;
+            }
+            if (effect instanceof VibrationEffect.OneShot
+                    || effect instanceof VibrationEffect.Waveform) {
+                // Oneshot and Waveform are controlled by amplitude steps, ignore callbacks.
+                return;
+            }
+            mVibrators.get(vibratorId).off();
+            mActiveVibratorCounter.countDown();
+        }
+
+        @Override
+        public Vibration.Status play() {
+            Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "SyncedVibrateStep");
+            long timeout = -1;
+            try {
+                if (DEBUG) {
+                    Slog.d(TAG, "SyncedVibrateStep starting...");
+                }
+                final PriorityQueue<AmplitudeStep> nextSteps = new PriorityQueue<>(mEffects.size());
+                long startTime = SystemClock.uptimeMillis();
+                mCallbacks.prepareSyncedVibration(mRequiredCapabilities, mVibratorIds);
+                timeout = startVibrating(startTime, nextSteps);
+                mCallbacks.triggerSyncedVibration(mVibration.id);
+                noteVibratorOn(timeout);
+
+                while (!nextSteps.isEmpty()) {
+                    AmplitudeStep step = nextSteps.poll();
+                    waitUntil(step.startTime);
+                    if (mForceStop) {
+                        stopAllVibrators();
+                        return Vibration.Status.CANCELLED;
+                    }
+                    step.play();
+                    AmplitudeStep nextStep = step.nextStep();
+                    if (nextStep == null) {
+                        // This vibrator has finished playing the effect for this step.
+                        mActiveVibratorCounter.countDown();
+                    } else {
+                        nextSteps.add(nextStep);
+                    }
+                }
+
+                // All OneShot and Waveform effects have finished. Just wait for the other effects
+                // to end via native callbacks before finishing this synced step.
+                awaitUntil(mActiveVibratorCounter, startTime + timeout + CALLBACKS_EXTRA_TIMEOUT);
+                return Vibration.Status.FINISHED;
+            } finally {
+                if (timeout > 0) {
+                    noteVibratorOff();
+                }
+                if (DEBUG) {
+                    Slog.d(TAG, "SyncedVibrateStep done.");
+                }
+                Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR);
+            }
+        }
+
+        /**
+         * Starts playing effects on designated vibrators.
+         *
+         * <p>This includes the {@link VibrationEffect.OneShot} and {@link VibrationEffect.Waveform}
+         * effects, that should start in sync with all other effects in this step. The waveforms are
+         * controlled by {@link AmplitudeStep} added to the {@code nextSteps} queue.
+         *
+         * @return A duration, in millis, to wait for the completion of all vibrations. This ignores
+         * any repeating waveform duration and returns the duration of a single run.
+         */
+        private long startVibrating(long startTime, PriorityQueue<AmplitudeStep> nextSteps) {
+            long maxDuration = 0;
+            for (int i = 0; i < mEffects.size(); i++) {
+                VibratorController controller = mVibrators.get(mEffects.keyAt(i));
+                VibrationEffect effect = mEffects.valueAt(i);
+                maxDuration = Math.max(maxDuration,
+                        startVibrating(controller, effect, startTime, nextSteps));
+            }
+            return maxDuration;
+        }
+
+        /**
+         * Play a single effect on a single vibrator.
+         *
+         * @return A duration, in millis, to wait for the completion of this effect. This ignores
+         * any repeating waveform duration and returns the duration of a single run to be used as
+         * timeout for callbacks.
+         */
+        private long startVibrating(VibratorController controller, VibrationEffect effect,
+                long startTime, PriorityQueue<AmplitudeStep> nextSteps) {
+            int vibratorId = controller.getVibratorInfo().getId();
+            long duration;
+            if (effect instanceof VibrationEffect.OneShot) {
+                VibrationEffect.OneShot oneShot = (VibrationEffect.OneShot) effect;
+                duration = oneShot.getDuration();
+                controller.on(duration, mVibration.id);
+                nextSteps.add(
+                        new AmplitudeStep(vibratorId, oneShot, startTime, startTime + duration));
+            } else if (effect instanceof VibrationEffect.Waveform) {
+                VibrationEffect.Waveform waveform = (VibrationEffect.Waveform) effect;
+                duration = getVibratorOnDuration(waveform, 0);
+                if (duration > 0) {
+                    // Waveform starts by turning vibrator on. Do it in this sync vibrate step.
+                    controller.on(duration, mVibration.id);
+                }
+                nextSteps.add(
+                        new AmplitudeStep(vibratorId, waveform, startTime, startTime + duration));
+            } else if (effect instanceof VibrationEffect.Prebaked) {
+                VibrationEffect.Prebaked prebaked = (VibrationEffect.Prebaked) effect;
+                duration = controller.on(prebaked, mVibration.id);
+                if (duration <= 0 && prebaked.getFallbackEffect() != null) {
+                    return startVibrating(controller, prebaked.getFallbackEffect(), startTime,
+                            nextSteps);
+                }
+            } else if (effect instanceof VibrationEffect.Composed) {
+                VibrationEffect.Composed composed = (VibrationEffect.Composed) effect;
+                duration = controller.on(composed, mVibration.id);
+            } else {
+                duration = 0;
+            }
+            return duration;
+        }
+
+        private void stopAllVibrators() {
+            for (int vibratorId : mVibratorIds) {
+                VibratorController controller = mVibrators.get(vibratorId);
+                if (controller != null) {
+                    controller.off();
+                }
+            }
+        }
+    }
+
+    /** Represent a step to set amplitude on a single vibrator. */
+    private final class AmplitudeStep implements Step, Comparable<AmplitudeStep> {
+        public final int vibratorId;
+        public final VibrationEffect.Waveform waveform;
+        public final int currentIndex;
+        public final long startTime;
+        public final long vibratorStopTime;
+
+        AmplitudeStep(int vibratorId, VibrationEffect.OneShot oneShot,
+                long startTime, long vibratorStopTime) {
+            this(vibratorId, (VibrationEffect.Waveform) VibrationEffect.createWaveform(
+                    new long[]{oneShot.getDuration()},
+                    new int[]{oneShot.getAmplitude()}, /* repeat= */ -1),
+                    startTime,
+                    vibratorStopTime);
+        }
+
+        AmplitudeStep(int vibratorId, VibrationEffect.Waveform waveform,
+                long startTime, long vibratorStopTime) {
+            this(vibratorId, waveform, /* index= */ 0, startTime, vibratorStopTime);
+        }
+
+        AmplitudeStep(int vibratorId, VibrationEffect.Waveform waveform,
+                int index, long startTime, long vibratorStopTime) {
+            this.vibratorId = vibratorId;
+            this.waveform = waveform;
+            this.currentIndex = index;
+            this.startTime = startTime;
+            this.vibratorStopTime = vibratorStopTime;
+        }
+
+        @Override
+        public Vibration.Status play() {
+            Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "AmplitudeStep");
+            try {
+                if (DEBUG) {
+                    Slog.d(TAG, "AmplitudeStep starting on vibrator " + vibratorId + "...");
+                }
+                VibratorController controller = mVibrators.get(vibratorId);
+                if (currentIndex < 0) {
+                    controller.off();
+                    if (DEBUG) {
+                        Slog.d(TAG, "Vibrator turned off and finishing");
+                    }
+                    return Vibration.Status.FINISHED;
+                }
+                if (waveform.getTimings()[currentIndex] == 0) {
+                    // Skip waveform entries with zero timing.
+                    return Vibration.Status.FINISHED;
+                }
+                int amplitude = waveform.getAmplitudes()[currentIndex];
+                if (amplitude == 0) {
+                    controller.off();
+                    if (DEBUG) {
+                        Slog.d(TAG, "Vibrator turned off");
+                    }
+                    return Vibration.Status.FINISHED;
+                }
+                if (startTime >= vibratorStopTime) {
+                    // Vibrator has stopped. Turn vibrator back on for the duration of another
+                    // cycle before setting the amplitude.
+                    long onDuration = getVibratorOnDuration(waveform, currentIndex);
+                    if (onDuration > 0) {
+                        controller.on(onDuration, mVibration.id);
+                        if (DEBUG) {
+                            Slog.d(TAG, "Vibrator turned on for " + onDuration + "ms");
+                        }
+                    }
+                }
+                controller.setAmplitude(amplitude);
+                if (DEBUG) {
+                    Slog.d(TAG, "Amplitude changed to " + amplitude);
+                }
+                return Vibration.Status.FINISHED;
+            } finally {
+                if (DEBUG) {
+                    Slog.d(TAG, "AmplitudeStep done.");
+                }
+                Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR);
+            }
+        }
+
+        @Override
+        public int compareTo(AmplitudeStep o) {
+            return Long.compare(startTime, o.startTime);
+        }
+
+        /** Return next {@link AmplitudeStep} from this waveform, of {@code null} if finished. */
+        @Nullable
+        public AmplitudeStep nextStep() {
+            if (currentIndex < 0) {
+                // Waveform has ended, no more steps to run.
+                return null;
+            }
+            long nextWakeUpTime = startTime + waveform.getTimings()[currentIndex];
+            int nextIndex = currentIndex + 1;
+            if (nextIndex >= waveform.getTimings().length) {
+                nextIndex = waveform.getRepeatIndex();
+            }
+            return new AmplitudeStep(vibratorId, waveform, nextIndex, nextWakeUpTime,
+                    nextVibratorStopTime());
+        }
+
+        /** Return next time the vibrator will stop after this step is played. */
+        private long nextVibratorStopTime() {
+            if (currentIndex < 0 || waveform.getTimings()[currentIndex] == 0
+                    || startTime < vibratorStopTime) {
+                return vibratorStopTime;
+            }
+            return startTime + getVibratorOnDuration(waveform, currentIndex);
+        }
+    }
+
+    /** Represent a delay step with fixed duration, that starts counting when it starts playing. */
+    private final class DelayStep implements Step {
+        private final int mDelay;
+
+        DelayStep(int delay) {
+            mDelay = delay;
+        }
+
+        @Override
+        public Vibration.Status play() {
+            Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "DelayStep");
+            try {
+                if (DEBUG) {
+                    Slog.d(TAG, "DelayStep of " + mDelay + "ms starting...");
+                }
+                waitUntil(SystemClock.uptimeMillis() + mDelay);
+                return Vibration.Status.FINISHED;
+            } finally {
+                if (DEBUG) {
+                    Slog.d(TAG, "DelayStep done.");
+                }
+                Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR);
+            }
+        }
+    }
+}
diff --git a/services/core/java/com/android/server/vibrator/VibratorController.java b/services/core/java/com/android/server/vibrator/VibratorController.java
index 311c73b..53f52e2 100644
--- a/services/core/java/com/android/server/vibrator/VibratorController.java
+++ b/services/core/java/com/android/server/vibrator/VibratorController.java
@@ -142,6 +142,11 @@
         }
     }
 
+    @VisibleForTesting
+    public NativeWrapper getNativeWrapper() {
+        return mNativeWrapper;
+    }
+
     /** Return the {@link VibratorInfo} representing the vibrator controlled by this instance. */
     public VibratorInfo getVibratorInfo() {
         return mVibratorInfo;
@@ -240,6 +245,8 @@
      * {@link OnVibrationCompleteListener}.
      *
      * <p>This will affect the state of {@link #isVibrating()}.
+     *
+     * @return The duration of the effect playing, or 0 if unsupported.
      */
     public long on(VibrationEffect.Prebaked effect, long vibrationId) {
         synchronized (mLock) {
@@ -257,15 +264,20 @@
      * {@link OnVibrationCompleteListener}.
      *
      * <p>This will affect the state of {@link #isVibrating()}.
+     *
+     * @return The duration of the effect playing, or 0 if unsupported.
      */
-    public void on(VibrationEffect.Composed effect, long vibrationId) {
+    public long on(VibrationEffect.Composed effect, long vibrationId) {
         if (!mVibratorInfo.hasCapability(IVibrator.CAP_COMPOSE_EFFECTS)) {
-            return;
+            return 0;
         }
         synchronized (mLock) {
             mNativeWrapper.compose(effect.getPrimitiveEffects().toArray(
                     new VibrationEffect.Composition.PrimitiveEffect[0]), vibrationId);
             notifyVibratorOnLocked();
+            // Compose don't actually give us an estimated duration, so we just guess here.
+            // TODO(b/177807015): use exposed durations from IVibrator here instead
+            return 20 * effect.getPrimitiveEffects().size();
         }
     }
 
diff --git a/services/tests/servicestests/src/com/android/server/VibratorManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/VibratorManagerServiceTest.java
index 726536d..0a35db5 100644
--- a/services/tests/servicestests/src/com/android/server/VibratorManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/VibratorManagerServiceTest.java
@@ -24,10 +24,6 @@
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
-import static org.mockito.ArgumentMatchers.anyLong;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
@@ -48,6 +44,7 @@
 
 import androidx.test.InstrumentationRegistry;
 
+import com.android.server.vibrator.FakeVibratorControllerProvider;
 import com.android.server.vibrator.VibratorController;
 
 import org.junit.After;
@@ -81,7 +78,7 @@
     @Mock private PowerManagerInternal mPowerManagerInternalMock;
     @Mock private PowerSaveState mPowerSaveStateMock;
 
-    private final Map<Integer, VibratorController.NativeWrapper> mNativeWrappers = new HashMap<>();
+    private final Map<Integer, FakeVibratorControllerProvider> mVibratorProviders = new HashMap<>();
 
     private TestLooper mTestLooper;
 
@@ -117,8 +114,8 @@
                     @Override
                     VibratorController createVibratorController(int vibratorId,
                             VibratorController.OnVibrationCompleteListener listener) {
-                        return new VibratorController(
-                                vibratorId, listener, mNativeWrappers.get(vibratorId));
+                        return mVibratorProviders.get(vibratorId)
+                                .newVibratorController(vibratorId, listener);
                     }
                 });
         service.systemReady();
@@ -126,9 +123,12 @@
     }
 
     @Test
-    public void createService_initializesNativeService() {
+    public void createService_initializesNativeManagerServiceAndVibrators() {
+        mockVibrators(1, 2);
         createService();
         verify(mNativeWrapperMock).init();
+        assertTrue(mVibratorProviders.get(1).isInitialized());
+        assertTrue(mVibratorProviders.get(2).isInitialized());
     }
 
     @Test
@@ -139,28 +139,23 @@
 
     @Test
     public void getVibratorIds_withNonEmptyResultFromNative_returnsSameArray() {
-        mNativeWrappers.put(1, mockVibrator(/* capabilities= */ 0));
-        mNativeWrappers.put(2, mockVibrator(/* capabilities= */ 0));
-        when(mNativeWrapperMock.getVibratorIds()).thenReturn(new int[]{2, 1});
+        mockVibrators(2, 1);
         assertArrayEquals(new int[]{2, 1}, createService().getVibratorIds());
     }
 
     @Test
     public void getVibratorInfo_withMissingVibratorId_returnsNull() {
-        mockVibrators(mockVibrator(/* capabilities= */ 0));
+        mockVibrators(1);
         assertNull(createService().getVibratorInfo(2));
     }
 
     @Test
     public void getVibratorInfo_withExistingVibratorId_returnsHalInfoForVibrator() {
-        VibratorController.NativeWrapper vibratorMock = mockVibrator(
-                IVibrator.CAP_COMPOSE_EFFECTS | IVibrator.CAP_AMPLITUDE_CONTROL);
-        when(vibratorMock.getSupportedEffects()).thenReturn(
-                new int[]{VibrationEffect.EFFECT_CLICK});
-        when(vibratorMock.getSupportedPrimitives()).thenReturn(
-                new int[]{VibrationEffect.Composition.PRIMITIVE_CLICK});
-        mNativeWrappers.put(1, vibratorMock);
-        when(mNativeWrapperMock.getVibratorIds()).thenReturn(new int[]{1});
+        mockVibrators(1);
+        FakeVibratorControllerProvider vibrator = mVibratorProviders.get(1);
+        vibrator.setCapabilities(IVibrator.CAP_COMPOSE_EFFECTS, IVibrator.CAP_AMPLITUDE_CONTROL);
+        vibrator.setSupportedEffects(VibrationEffect.EFFECT_CLICK);
+        vibrator.setSupportedPrimitives(VibrationEffect.Composition.PRIMITIVE_CLICK);
         VibratorInfo info = createService().getVibratorInfo(1);
 
         assertNotNull(info);
@@ -178,105 +173,95 @@
 
     @Test
     public void setAlwaysOnEffect_withMono_enablesAlwaysOnEffectToAllVibratorsWithCapability() {
-        VibratorController.NativeWrapper[] vibratorMocks = new VibratorController.NativeWrapper[]{
-                mockVibrator(IVibrator.CAP_ALWAYS_ON_CONTROL),
-                mockVibrator(/* capabilities= */ 0),
-                mockVibrator(IVibrator.CAP_ALWAYS_ON_CONTROL),
-        };
-        mockVibrators(vibratorMocks);
+        mockVibrators(1, 2, 3);
+        mVibratorProviders.get(1).setCapabilities(IVibrator.CAP_ALWAYS_ON_CONTROL);
+        mVibratorProviders.get(3).setCapabilities(IVibrator.CAP_ALWAYS_ON_CONTROL);
 
         CombinedVibrationEffect effect = CombinedVibrationEffect.createSynced(
                 VibrationEffect.createPredefined(VibrationEffect.EFFECT_CLICK));
         assertTrue(createService().setAlwaysOnEffect(UID, PACKAGE_NAME, 1, effect, ALARM_ATTRS));
 
-        // Only vibrators 0 and 2 have always-on capabilities.
-        verify(vibratorMocks[0]).alwaysOnEnable(
-                eq(1L), eq((long) VibrationEffect.EFFECT_CLICK),
-                eq((long) VibrationEffect.EFFECT_STRENGTH_STRONG));
-        verify(vibratorMocks[1], never()).alwaysOnEnable(anyLong(), anyLong(), anyLong());
-        verify(vibratorMocks[2]).alwaysOnEnable(
-                eq(1L), eq((long) VibrationEffect.EFFECT_CLICK),
-                eq((long) VibrationEffect.EFFECT_STRENGTH_STRONG));
+        VibrationEffect.Prebaked expectedEffect = new VibrationEffect.Prebaked(
+                VibrationEffect.EFFECT_CLICK, false, VibrationEffect.EFFECT_STRENGTH_STRONG);
+
+        // Only vibrators 1 and 3 have always-on capabilities.
+        assertEquals(mVibratorProviders.get(1).getAlwaysOnEffect(1), expectedEffect);
+        assertNull(mVibratorProviders.get(2).getAlwaysOnEffect(1));
+        assertEquals(mVibratorProviders.get(3).getAlwaysOnEffect(1), expectedEffect);
     }
 
     @Test
     public void setAlwaysOnEffect_withStereo_enablesAlwaysOnEffectToAllVibratorsWithCapability() {
-        VibratorController.NativeWrapper[] vibratorMocks = new VibratorController.NativeWrapper[] {
-                mockVibrator(IVibrator.CAP_ALWAYS_ON_CONTROL),
-                mockVibrator(IVibrator.CAP_ALWAYS_ON_CONTROL),
-                mockVibrator(0),
-                mockVibrator(IVibrator.CAP_ALWAYS_ON_CONTROL),
-        };
-        mockVibrators(vibratorMocks);
+        mockVibrators(1, 2, 3, 4);
+        mVibratorProviders.get(1).setCapabilities(IVibrator.CAP_ALWAYS_ON_CONTROL);
+        mVibratorProviders.get(2).setCapabilities(IVibrator.CAP_ALWAYS_ON_CONTROL);
+        mVibratorProviders.get(4).setCapabilities(IVibrator.CAP_ALWAYS_ON_CONTROL);
 
         CombinedVibrationEffect effect = CombinedVibrationEffect.startSynced()
-                .addVibrator(0, VibrationEffect.createPredefined(VibrationEffect.EFFECT_CLICK))
-                .addVibrator(1, VibrationEffect.createPredefined(VibrationEffect.EFFECT_TICK))
-                .addVibrator(2, VibrationEffect.createPredefined(VibrationEffect.EFFECT_CLICK))
+                .addVibrator(1, VibrationEffect.createPredefined(VibrationEffect.EFFECT_CLICK))
+                .addVibrator(2, VibrationEffect.createPredefined(VibrationEffect.EFFECT_TICK))
+                .addVibrator(3, VibrationEffect.createPredefined(VibrationEffect.EFFECT_CLICK))
                 .combine();
         assertTrue(createService().setAlwaysOnEffect(UID, PACKAGE_NAME, 1, effect, ALARM_ATTRS));
 
-        // Enables click on vibrator 0 and tick on vibrator 1 only.
-        verify(vibratorMocks[0]).alwaysOnEnable(
-                eq(1L), eq((long) VibrationEffect.EFFECT_CLICK),
-                eq((long) VibrationEffect.EFFECT_STRENGTH_STRONG));
-        verify(vibratorMocks[1]).alwaysOnEnable(
-                eq(1L), eq((long) VibrationEffect.EFFECT_TICK),
-                eq((long) VibrationEffect.EFFECT_STRENGTH_STRONG));
-        verify(vibratorMocks[2], never()).alwaysOnEnable(anyLong(), anyLong(), anyLong());
-        verify(vibratorMocks[3], never()).alwaysOnEnable(anyLong(), anyLong(), anyLong());
+        VibrationEffect.Prebaked expectedClick = new VibrationEffect.Prebaked(
+                VibrationEffect.EFFECT_CLICK, false, VibrationEffect.EFFECT_STRENGTH_STRONG);
+
+        VibrationEffect.Prebaked expectedTick = new VibrationEffect.Prebaked(
+                VibrationEffect.EFFECT_TICK, false, VibrationEffect.EFFECT_STRENGTH_STRONG);
+
+        // Enables click on vibrator 1 and tick on vibrator 2 only.
+        assertEquals(mVibratorProviders.get(1).getAlwaysOnEffect(1), expectedClick);
+        assertEquals(mVibratorProviders.get(2).getAlwaysOnEffect(1), expectedTick);
+        assertNull(mVibratorProviders.get(3).getAlwaysOnEffect(1));
+        assertNull(mVibratorProviders.get(4).getAlwaysOnEffect(1));
     }
 
     @Test
     public void setAlwaysOnEffect_withNullEffect_disablesAlwaysOnEffects() {
-        VibratorController.NativeWrapper[] vibratorMocks = new VibratorController.NativeWrapper[] {
-                mockVibrator(IVibrator.CAP_ALWAYS_ON_CONTROL),
-                mockVibrator(0),
-                mockVibrator(IVibrator.CAP_ALWAYS_ON_CONTROL),
-        };
-        mockVibrators(vibratorMocks);
+        mockVibrators(1, 2, 3);
+        mVibratorProviders.get(1).setCapabilities(IVibrator.CAP_ALWAYS_ON_CONTROL);
+        mVibratorProviders.get(3).setCapabilities(IVibrator.CAP_ALWAYS_ON_CONTROL);
+
+        CombinedVibrationEffect effect = CombinedVibrationEffect.createSynced(
+                VibrationEffect.createPredefined(VibrationEffect.EFFECT_CLICK));
+        assertTrue(createService().setAlwaysOnEffect(UID, PACKAGE_NAME, 1, effect, ALARM_ATTRS));
 
         assertTrue(createService().setAlwaysOnEffect(UID, PACKAGE_NAME, 1, null, ALARM_ATTRS));
 
-        // Disables only 0 and 2 that have capability.
-        verify(vibratorMocks[0]).alwaysOnDisable(eq(1L));
-        verify(vibratorMocks[1], never()).alwaysOnDisable(anyLong());
-        verify(vibratorMocks[2]).alwaysOnDisable(eq(1L));
+        assertNull(mVibratorProviders.get(1).getAlwaysOnEffect(1));
+        assertNull(mVibratorProviders.get(2).getAlwaysOnEffect(1));
+        assertNull(mVibratorProviders.get(3).getAlwaysOnEffect(1));
     }
 
     @Test
     public void setAlwaysOnEffect_withNonPrebakedEffect_ignoresEffect() {
-        VibratorController.NativeWrapper vibratorMock =
-                mockVibrator(IVibrator.CAP_ALWAYS_ON_CONTROL);
-        mockVibrators(vibratorMock);
+        mockVibrators(1);
+        mVibratorProviders.get(1).setCapabilities(IVibrator.CAP_ALWAYS_ON_CONTROL);
 
         CombinedVibrationEffect effect = CombinedVibrationEffect.createSynced(
                 VibrationEffect.createOneShot(100, VibrationEffect.DEFAULT_AMPLITUDE));
         assertFalse(createService().setAlwaysOnEffect(UID, PACKAGE_NAME, 1, effect, ALARM_ATTRS));
 
-        verify(vibratorMock, never()).alwaysOnEnable(anyLong(), anyLong(), anyLong());
-        verify(vibratorMock, never()).alwaysOnDisable(anyLong());
+        assertNull(mVibratorProviders.get(1).getAlwaysOnEffect(1));
     }
 
     @Test
     public void setAlwaysOnEffect_withNonSyncedEffect_ignoresEffect() {
-        VibratorController.NativeWrapper vibratorMock =
-                mockVibrator(IVibrator.CAP_ALWAYS_ON_CONTROL);
-        mockVibrators(vibratorMock);
+        mockVibrators(1);
+        mVibratorProviders.get(1).setCapabilities(IVibrator.CAP_ALWAYS_ON_CONTROL);
 
         CombinedVibrationEffect effect = CombinedVibrationEffect.startSequential()
                 .addNext(0, VibrationEffect.get(VibrationEffect.EFFECT_CLICK))
                 .combine();
         assertFalse(createService().setAlwaysOnEffect(UID, PACKAGE_NAME, 1, effect, ALARM_ATTRS));
 
-        verify(vibratorMock, never()).alwaysOnEnable(anyLong(), anyLong(), anyLong());
-        verify(vibratorMock, never()).alwaysOnDisable(anyLong());
+        assertNull(mVibratorProviders.get(1).getAlwaysOnEffect(1));
     }
 
     @Test
     public void setAlwaysOnEffect_withNoVibratorWithCapability_ignoresEffect() {
-        VibratorController.NativeWrapper vibratorMock = mockVibrator(0);
-        mockVibrators(vibratorMock);
+        mockVibrators(1);
         VibratorManagerService service = createService();
 
         CombinedVibrationEffect mono = CombinedVibrationEffect.createSynced(
@@ -287,8 +272,7 @@
         assertFalse(service.setAlwaysOnEffect(UID, PACKAGE_NAME, 1, mono, ALARM_ATTRS));
         assertFalse(service.setAlwaysOnEffect(UID, PACKAGE_NAME, 2, stereo, ALARM_ATTRS));
 
-        verify(vibratorMock, never()).alwaysOnEnable(anyLong(), anyLong(), anyLong());
-        verify(vibratorMock, never()).alwaysOnDisable(anyLong());
+        assertNull(mVibratorProviders.get(1).getAlwaysOnEffect(1));
     }
 
     @Test
@@ -310,19 +294,12 @@
                 "Not implemented", () -> service.cancelVibrate(service));
     }
 
-    private VibratorController.NativeWrapper mockVibrator(int capabilities) {
-        VibratorController.NativeWrapper wrapper = mock(VibratorController.NativeWrapper.class);
-        when(wrapper.getCapabilities()).thenReturn((long) capabilities);
-        return wrapper;
-    }
-
-    private void mockVibrators(VibratorController.NativeWrapper... wrappers) {
-        int[] ids = new int[wrappers.length];
-        for (int i = 0; i < wrappers.length; i++) {
-            ids[i] = i;
-            mNativeWrappers.put(i, wrappers[i]);
+    private void mockVibrators(int... vibratorIds) {
+        for (int vibratorId : vibratorIds) {
+            mVibratorProviders.put(vibratorId,
+                    new FakeVibratorControllerProvider(mTestLooper.getLooper()));
         }
-        when(mNativeWrapperMock.getVibratorIds()).thenReturn(ids);
+        when(mNativeWrapperMock.getVibratorIds()).thenReturn(vibratorIds);
     }
 
     private static <T> void addLocalServiceMock(Class<T> clazz, T mock) {
diff --git a/services/tests/servicestests/src/com/android/server/VibratorServiceTest.java b/services/tests/servicestests/src/com/android/server/VibratorServiceTest.java
index 32ca7b5..92256e2 100644
--- a/services/tests/servicestests/src/com/android/server/VibratorServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/VibratorServiceTest.java
@@ -19,21 +19,17 @@
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
-import static org.mockito.AdditionalMatchers.gt;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.ArgumentMatchers.anyLong;
 import static org.mockito.ArgumentMatchers.anyString;
 import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.ArgumentMatchers.intThat;
-import static org.mockito.ArgumentMatchers.notNull;
+import static org.mockito.Mockito.atLeastOnce;
+import static org.mockito.Mockito.clearInvocations;
 import static org.mockito.Mockito.doAnswer;
 import static org.mockito.Mockito.inOrder;
-import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyNoMoreInteractions;
 import static org.mockito.Mockito.when;
 
 import android.app.AppOpsManager;
@@ -54,8 +50,6 @@
 import android.os.PowerManagerInternal;
 import android.os.PowerSaveState;
 import android.os.Process;
-import android.os.RemoteException;
-import android.os.SystemClock;
 import android.os.UserHandle;
 import android.os.VibrationAttributes;
 import android.os.VibrationEffect;
@@ -70,16 +64,15 @@
 
 import com.android.internal.util.test.FakeSettingsProvider;
 import com.android.internal.util.test.FakeSettingsProviderRule;
+import com.android.server.vibrator.FakeVibratorControllerProvider;
 import com.android.server.vibrator.VibratorController;
 
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
-import org.mockito.ArgumentCaptor;
 import org.mockito.InOrder;
 import org.mockito.Mock;
-import org.mockito.Mockito;
 import org.mockito.junit.MockitoJUnit;
 import org.mockito.junit.MockitoRule;
 
@@ -87,7 +80,7 @@
 import java.util.List;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicLong;
+import java.util.stream.Collectors;
 
 /**
  * Tests for {@link VibratorService}.
@@ -99,6 +92,7 @@
 public class VibratorServiceTest {
 
     private static final int UID = Process.ROOT_UID;
+    private static final int VIBRATOR_ID = 1;
     private static final String PACKAGE_NAME = "package";
     private static final PowerSaveState NORMAL_POWER_STATE = new PowerSaveState.Builder().build();
     private static final PowerSaveState LOW_POWER_STATE = new PowerSaveState.Builder()
@@ -123,7 +117,6 @@
     // TODO(b/131311651): replace with a FakeVibrator instead.
     @Mock private Vibrator mVibratorMock;
     @Mock private AppOpsManager mAppOpsManagerMock;
-    @Mock private VibratorController.NativeWrapper mNativeWrapperMock;
     @Mock private IVibratorStateListener mVibratorStateListenerMock;
     @Mock private IInputManager mIInputManagerMock;
     @Mock private IBinder mVibratorStateListenerBinderMock;
@@ -131,10 +124,12 @@
     private TestLooper mTestLooper;
     private ContextWrapper mContextSpy;
     private PowerManagerInternal.LowPowerModeListener mRegisteredPowerModeListener;
+    private FakeVibratorControllerProvider mVibratorProvider;
 
     @Before
     public void setUp() throws Exception {
         mTestLooper = new TestLooper();
+        mVibratorProvider = new FakeVibratorControllerProvider(mTestLooper.getLooper());
         mContextSpy = spy(new ContextWrapper(InstrumentationRegistry.getContext()));
         InputManager inputManager = InputManager.resetInstance(mIInputManagerMock);
 
@@ -183,7 +178,7 @@
                     @Override
                     VibratorController createVibratorController(
                             VibratorController.OnVibrationCompleteListener listener) {
-                        return new VibratorController(0, listener, mNativeWrapperMock);
+                        return mVibratorProvider.newVibratorController(VIBRATOR_ID, listener);
                     }
 
                     @Override
@@ -203,25 +198,23 @@
     @Test
     public void createService_initializesNativeService() {
         createService();
-        verify(mNativeWrapperMock).init(eq(0), notNull());
-        verify(mNativeWrapperMock, times(2)).off(); // Called from constructor and onSystemReady
+        assertTrue(mVibratorProvider.isInitialized());
     }
 
     @Test
     public void hasVibrator_withVibratorHalPresent_returnsTrue() {
-        when(mNativeWrapperMock.isAvailable()).thenReturn(true);
         assertTrue(createService().hasVibrator());
     }
 
     @Test
     public void hasVibrator_withNoVibratorHalPresent_returnsFalse() {
-        when(mNativeWrapperMock.isAvailable()).thenReturn(false);
+        mVibratorProvider.disableVibrators();
         assertFalse(createService().hasVibrator());
     }
 
     @Test
     public void hasAmplitudeControl_withAmplitudeControlSupport_returnsTrue() {
-        mockVibratorCapabilities(IVibrator.CAP_AMPLITUDE_CONTROL);
+        mVibratorProvider.setCapabilities(IVibrator.CAP_AMPLITUDE_CONTROL);
         assertTrue(createService().hasAmplitudeControl());
     }
 
@@ -234,18 +227,17 @@
     public void hasAmplitudeControl_withInputDevices_returnsTrue() throws Exception {
         when(mIInputManagerMock.getInputDeviceIds()).thenReturn(new int[]{1});
         when(mIInputManagerMock.getInputDevice(1)).thenReturn(createInputDeviceWithVibrator(1));
-        mockVibratorCapabilities(IVibrator.CAP_AMPLITUDE_CONTROL);
+        mVibratorProvider.setCapabilities(IVibrator.CAP_AMPLITUDE_CONTROL);
         setUserSetting(Settings.System.VIBRATE_INPUT_DEVICES, 1);
         assertTrue(createService().hasAmplitudeControl());
     }
 
     @Test
     public void getVibratorInfo_returnsSameInfoFromNative() {
-        mockVibratorCapabilities(IVibrator.CAP_COMPOSE_EFFECTS | IVibrator.CAP_AMPLITUDE_CONTROL);
-        when(mNativeWrapperMock.getSupportedEffects())
-                .thenReturn(new int[]{VibrationEffect.EFFECT_CLICK});
-        when(mNativeWrapperMock.getSupportedPrimitives())
-                .thenReturn(new int[]{VibrationEffect.Composition.PRIMITIVE_CLICK});
+        mVibratorProvider.setCapabilities(IVibrator.CAP_COMPOSE_EFFECTS,
+                IVibrator.CAP_AMPLITUDE_CONTROL);
+        mVibratorProvider.setSupportedEffects(VibrationEffect.EFFECT_CLICK);
+        mVibratorProvider.setSupportedPrimitives(VibrationEffect.Composition.PRIMITIVE_CLICK);
 
         VibratorInfo info = createService().getVibratorInfo();
         assertTrue(info.hasAmplitudeControl());
@@ -258,7 +250,7 @@
     }
 
     @Test
-    public void vibrate_withRingtone_usesRingtoneSettings() {
+    public void vibrate_withRingtone_usesRingtoneSettings() throws Exception {
         setRingerMode(AudioManager.RINGER_MODE_NORMAL);
         setUserSetting(Settings.System.VIBRATE_WHEN_RINGING, 0);
         setGlobalSetting(Settings.Global.APPLY_RAMPING_RINGER, 0);
@@ -266,34 +258,34 @@
 
         setUserSetting(Settings.System.VIBRATE_WHEN_RINGING, 0);
         setGlobalSetting(Settings.Global.APPLY_RAMPING_RINGER, 1);
-        vibrate(createService(), VibrationEffect.createOneShot(10, 10), RINGTONE_ATTRS);
+        vibrateAndWait(createService(), VibrationEffect.createOneShot(10, 10), RINGTONE_ATTRS);
 
         setUserSetting(Settings.System.VIBRATE_WHEN_RINGING, 1);
         setGlobalSetting(Settings.Global.APPLY_RAMPING_RINGER, 0);
-        vibrate(createService(), VibrationEffect.createOneShot(100, 100), RINGTONE_ATTRS);
+        vibrateAndWait(createService(), VibrationEffect.createOneShot(100, 100), RINGTONE_ATTRS);
 
-        InOrder inOrderVerifier = inOrder(mNativeWrapperMock);
-        inOrderVerifier.verify(mNativeWrapperMock, never()).on(eq(1L), anyLong());
-        inOrderVerifier.verify(mNativeWrapperMock).on(eq(10L), anyLong());
-        inOrderVerifier.verify(mNativeWrapperMock).on(eq(100L), anyLong());
+        List<VibrationEffect> effects = mVibratorProvider.getEffects();
+        assertEquals(2, effects.size());
+        assertEquals(10, effects.get(0).getDuration());
+        assertEquals(100, effects.get(1).getDuration());
     }
 
     @Test
-    public void vibrate_withPowerModeChange_usesLowPowerModeState() {
+    public void vibrate_withPowerModeChange_usesLowPowerModeState() throws Exception {
         VibratorService service = createService();
         mRegisteredPowerModeListener.onLowPowerModeChanged(LOW_POWER_STATE);
         vibrate(service, VibrationEffect.createOneShot(1, 1), HAPTIC_FEEDBACK_ATTRS);
-        vibrate(service, VibrationEffect.createOneShot(2, 2), RINGTONE_ATTRS);
+        vibrateAndWait(service, VibrationEffect.createOneShot(2, 2), RINGTONE_ATTRS);
 
         mRegisteredPowerModeListener.onLowPowerModeChanged(NORMAL_POWER_STATE);
-        vibrate(service, VibrationEffect.createOneShot(3, 3), /* attributes= */ null);
-        vibrate(service, VibrationEffect.createOneShot(4, 4), NOTIFICATION_ATTRS);
+        vibrateAndWait(service, VibrationEffect.createOneShot(3, 3), /* attributes= */ null);
+        vibrateAndWait(service, VibrationEffect.createOneShot(4, 4), NOTIFICATION_ATTRS);
 
-        InOrder inOrderVerifier = inOrder(mNativeWrapperMock);
-        inOrderVerifier.verify(mNativeWrapperMock, never()).on(eq(1L), anyLong());
-        inOrderVerifier.verify(mNativeWrapperMock).on(eq(2L), anyLong());
-        inOrderVerifier.verify(mNativeWrapperMock).on(eq(3L), anyLong());
-        inOrderVerifier.verify(mNativeWrapperMock).on(eq(4L), anyLong());
+        List<VibrationEffect> effects = mVibratorProvider.getEffects();
+        assertEquals(3, effects.size());
+        assertEquals(2, effects.get(0).getDuration());
+        assertEquals(3, effects.get(1).getDuration());
+        assertEquals(4, effects.get(2).getDuration());
     }
 
     @Test
@@ -349,55 +341,55 @@
         when(mIInputManagerMock.getInputDevice(1)).thenReturn(createInputDeviceWithVibrator(1));
         setUserSetting(Settings.System.VIBRATE_INPUT_DEVICES, 1);
         VibratorService service = createService();
-        Mockito.clearInvocations(mNativeWrapperMock);
 
         VibrationEffect effect = VibrationEffect.createOneShot(100, 128);
-        vibrate(service, effect);
-        assertFalse(service.isVibrating());
-
+        vibrate(service, effect, ALARM_ATTRS);
         verify(mIInputManagerMock).vibrate(eq(1), eq(effect), any());
-        verify(mNativeWrapperMock, never()).on(anyLong(), anyLong());
+
+        // VibrationThread will start this vibration async, so wait before checking it never played.
+        Thread.sleep(10);
+        assertTrue(mVibratorProvider.getEffects().isEmpty());
     }
 
     @Test
-    public void vibrate_withOneShotAndAmplitudeControl_turnsVibratorOnAndSetsAmplitude() {
-        mockVibratorCapabilities(IVibrator.CAP_AMPLITUDE_CONTROL);
+    public void vibrate_withOneShotAndAmplitudeControl_turnsVibratorOnAndSetsAmplitude()
+            throws Exception {
+        mVibratorProvider.setCapabilities(IVibrator.CAP_AMPLITUDE_CONTROL);
         VibratorService service = createService();
-        Mockito.clearInvocations(mNativeWrapperMock);
 
-        vibrate(service, VibrationEffect.createOneShot(100, 128));
-        assertTrue(service.isVibrating());
+        vibrateAndWait(service, VibrationEffect.createOneShot(100, 128), ALARM_ATTRS);
 
-        verify(mNativeWrapperMock).off();
-        verify(mNativeWrapperMock).on(eq(100L), gt(0L));
-        verify(mNativeWrapperMock).setAmplitude(eq(128));
+        List<VibrationEffect> effects = mVibratorProvider.getEffects();
+        assertEquals(1, effects.size());
+        assertEquals(100, effects.get(0).getDuration());
+        assertEquals(Arrays.asList(128), mVibratorProvider.getAmplitudes());
     }
 
     @Test
-    public void vibrate_withOneShotAndNoAmplitudeControl_turnsVibratorOnAndIgnoresAmplitude() {
+    public void vibrate_withOneShotAndNoAmplitudeControl_turnsVibratorOnAndIgnoresAmplitude()
+            throws Exception {
         VibratorService service = createService();
-        Mockito.clearInvocations(mNativeWrapperMock);
+        clearInvocations();
 
-        vibrate(service, VibrationEffect.createOneShot(100, 128));
-        assertTrue(service.isVibrating());
+        vibrateAndWait(service, VibrationEffect.createOneShot(100, 128), ALARM_ATTRS);
 
-        verify(mNativeWrapperMock).off();
-        verify(mNativeWrapperMock).on(eq(100L), gt(0L));
-        verify(mNativeWrapperMock, never()).setAmplitude(anyInt());
+        List<VibrationEffect> effects = mVibratorProvider.getEffects();
+        assertEquals(1, effects.size());
+        assertEquals(100, effects.get(0).getDuration());
+        assertTrue(mVibratorProvider.getAmplitudes().isEmpty());
     }
 
     @Test
-    public void vibrate_withPrebaked_performsEffect() {
-        when(mNativeWrapperMock.getSupportedEffects())
-                .thenReturn(new int[]{VibrationEffect.EFFECT_CLICK});
+    public void vibrate_withPrebaked_performsEffect() throws Exception {
+        mVibratorProvider.setSupportedEffects(VibrationEffect.EFFECT_CLICK);
         VibratorService service = createService();
-        Mockito.clearInvocations(mNativeWrapperMock);
 
-        vibrate(service, VibrationEffect.createPredefined(VibrationEffect.EFFECT_CLICK));
+        VibrationEffect effect = VibrationEffect.createPredefined(VibrationEffect.EFFECT_CLICK);
+        vibrateAndWait(service, effect, ALARM_ATTRS);
 
-        verify(mNativeWrapperMock).off();
-        verify(mNativeWrapperMock).perform(eq((long) VibrationEffect.EFFECT_CLICK),
-                eq((long) VibrationEffect.EFFECT_STRENGTH_STRONG), gt(0L));
+        VibrationEffect.Prebaked expectedEffect = new VibrationEffect.Prebaked(
+                VibrationEffect.EFFECT_CLICK, false, VibrationEffect.EFFECT_STRENGTH_STRONG);
+        assertEquals(Arrays.asList(expectedEffect), mVibratorProvider.getEffects());
     }
 
     @Test
@@ -407,120 +399,62 @@
         when(mIInputManagerMock.getInputDevice(1)).thenReturn(createInputDeviceWithVibrator(1));
         setUserSetting(Settings.System.VIBRATE_INPUT_DEVICES, 1);
         VibratorService service = createService();
-        Mockito.clearInvocations(mNativeWrapperMock);
 
-        vibrate(service, VibrationEffect.get(VibrationEffect.EFFECT_CLICK));
-        assertFalse(service.isVibrating());
-
-        // Wait for VibrateThread to turn input device vibrator ON.
-        Thread.sleep(5);
+        vibrate(service, VibrationEffect.get(VibrationEffect.EFFECT_CLICK), ALARM_ATTRS);
         verify(mIInputManagerMock).vibrate(eq(1), any(), any());
-        verify(mNativeWrapperMock, never()).on(anyLong(), anyLong());
-        verify(mNativeWrapperMock, never()).perform(anyLong(), anyLong(), anyLong());
+
+        // VibrationThread will start this vibration async, so wait before checking it never played.
+        Thread.sleep(10);
+        assertTrue(mVibratorProvider.getEffects().isEmpty());
     }
 
     @Test
-    public void vibrate_withComposed_performsEffect() {
-        mockVibratorCapabilities(IVibrator.CAP_COMPOSE_EFFECTS);
+    public void vibrate_withComposed_performsEffect() throws Exception {
+        mVibratorProvider.setCapabilities(IVibrator.CAP_COMPOSE_EFFECTS);
         VibratorService service = createService();
-        Mockito.clearInvocations(mNativeWrapperMock);
 
         VibrationEffect effect = VibrationEffect.startComposition()
                 .addPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK, 0.5f, 10)
                 .compose();
-        vibrate(service, effect);
-
-        ArgumentCaptor<VibrationEffect.Composition.PrimitiveEffect[]> primitivesCaptor =
-                ArgumentCaptor.forClass(VibrationEffect.Composition.PrimitiveEffect[].class);
-
-        verify(mNativeWrapperMock).off();
-        verify(mNativeWrapperMock).compose(primitivesCaptor.capture(), gt(0L));
-
-        // Check all primitive effect fields are passed down to the HAL.
-        assertEquals(1, primitivesCaptor.getValue().length);
-        VibrationEffect.Composition.PrimitiveEffect primitive = primitivesCaptor.getValue()[0];
-        assertEquals(VibrationEffect.Composition.PRIMITIVE_CLICK, primitive.id);
-        assertEquals(0.5f, primitive.scale, /* delta= */ 1e-2);
-        assertEquals(10, primitive.delay);
+        vibrateAndWait(service, effect, ALARM_ATTRS);
+        assertEquals(Arrays.asList(effect), mVibratorProvider.getEffects());
     }
 
     @Test
-    public void vibrate_withComposedAndInputDevices_vibratesInputDevices()
-            throws Exception {
+    public void vibrate_withComposedAndInputDevices_vibratesInputDevices() throws Exception {
         when(mIInputManagerMock.getInputDeviceIds()).thenReturn(new int[]{1, 2});
         when(mIInputManagerMock.getInputDevice(1)).thenReturn(createInputDeviceWithVibrator(1));
         when(mIInputManagerMock.getInputDevice(2)).thenReturn(createInputDeviceWithVibrator(2));
         setUserSetting(Settings.System.VIBRATE_INPUT_DEVICES, 1);
         VibratorService service = createService();
-        Mockito.clearInvocations(mNativeWrapperMock);
 
         VibrationEffect effect = VibrationEffect.startComposition()
                 .addPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK, 0.5f, 10)
                 .compose();
-        vibrate(service, effect);
-        assertFalse(service.isVibrating());
+        vibrate(service, effect, ALARM_ATTRS);
+        InOrder inOrderVerifier = inOrder(mIInputManagerMock);
+        inOrderVerifier.verify(mIInputManagerMock).vibrate(eq(1), eq(effect), any());
+        inOrderVerifier.verify(mIInputManagerMock).vibrate(eq(2), eq(effect), any());
 
-        verify(mIInputManagerMock).vibrate(eq(1), eq(effect), any());
-        verify(mIInputManagerMock).vibrate(eq(2), eq(effect), any());
-        verify(mNativeWrapperMock, never()).compose(any(), anyLong());
+        // VibrationThread will start this vibration async, so wait before checking it never played.
+        Thread.sleep(10);
+        assertTrue(mVibratorProvider.getEffects().isEmpty());
     }
 
     @Test
     public void vibrate_withWaveform_controlsVibratorAmplitudeDuringTotalVibrationTime()
             throws Exception {
-        mockVibratorCapabilities(IVibrator.CAP_AMPLITUDE_CONTROL);
+        mVibratorProvider.setCapabilities(IVibrator.CAP_AMPLITUDE_CONTROL);
         VibratorService service = createService();
-        Mockito.clearInvocations(mNativeWrapperMock);
 
         VibrationEffect effect = VibrationEffect.createWaveform(
                 new long[]{10, 10, 10}, new int[]{100, 200, 50}, -1);
-        vibrate(service, effect);
+        vibrateAndWait(service, effect, ALARM_ATTRS);
 
-        // Wait for VibrateThread to finish: 10ms 100, 10ms 200, 10ms 50.
-        Thread.sleep(40);
-        InOrder inOrderVerifier = inOrder(mNativeWrapperMock);
-        inOrderVerifier.verify(mNativeWrapperMock).off();
-        inOrderVerifier.verify(mNativeWrapperMock).on(eq(30L), anyLong());
-        inOrderVerifier.verify(mNativeWrapperMock).setAmplitude(eq(100));
-        inOrderVerifier.verify(mNativeWrapperMock).setAmplitude(eq(200));
-        inOrderVerifier.verify(mNativeWrapperMock).setAmplitude(eq(50));
-        inOrderVerifier.verify(mNativeWrapperMock).off();
-    }
-
-    @Test
-    public void vibrate_withWaveform_totalVibrationTimeRespected() throws Exception {
-        int totalDuration = 10_000; // 10s
-        int stepDuration = 25; // 25ms
-
-        // 25% of the first waveform step will be spent on the native on() call.
-        mockVibratorCapabilities(IVibrator.CAP_AMPLITUDE_CONTROL);
-        doAnswer(invocation -> {
-            Thread.currentThread().sleep(stepDuration / 4);
-            return null;
-        }).when(mNativeWrapperMock).on(anyLong(), anyLong());
-        // 25% of each waveform step will be spent on the native setAmplitude() call..
-        doAnswer(invocation -> {
-            Thread.currentThread().sleep(stepDuration / 4);
-            return null;
-        }).when(mNativeWrapperMock).setAmplitude(anyInt());
-
-        VibratorService service = createService();
-
-        int stepCount = totalDuration / stepDuration;
-        long[] timings = new long[stepCount];
-        int[] amplitudes = new int[stepCount];
-        Arrays.fill(timings, stepDuration);
-        Arrays.fill(amplitudes, VibrationEffect.DEFAULT_AMPLITUDE);
-        VibrationEffect effect = VibrationEffect.createWaveform(timings, amplitudes, -1);
-
-        int perceivedDuration = vibrateAndMeasure(service, effect, /* timeoutSecs= */ 15);
-        int delay = Math.abs(perceivedDuration - totalDuration);
-
-        // Allow some delay for thread scheduling and callback triggering.
-        int maxDelay = (int) (0.05 * totalDuration); // < 5% of total duration
-        assertTrue("Waveform with perceived delay of " + delay + "ms,"
-                        + " expected less than " + maxDelay + "ms",
-                delay < maxDelay);
+        assertEquals(Arrays.asList(100, 200, 50), mVibratorProvider.getAmplitudes());
+        assertEquals(
+                Arrays.asList(VibrationEffect.createOneShot(30, VibrationEffect.DEFAULT_AMPLITUDE)),
+                mVibratorProvider.getEffects());
     }
 
     @Test
@@ -529,123 +463,52 @@
         when(mIInputManagerMock.getInputDevice(1)).thenReturn(createInputDeviceWithVibrator(1));
         setUserSetting(Settings.System.VIBRATE_INPUT_DEVICES, 1);
         VibratorService service = createService();
-        Mockito.clearInvocations(mNativeWrapperMock);
 
         VibrationEffect effect = VibrationEffect.createWaveform(
                 new long[]{10, 10, 10}, new int[]{100, 200, 50}, -1);
-        vibrate(service, effect);
-        assertFalse(service.isVibrating());
-
-        // Wait for VibrateThread to turn input device vibrator ON.
-        Thread.sleep(5);
+        vibrate(service, effect, ALARM_ATTRS);
         verify(mIInputManagerMock).vibrate(eq(1), eq(effect), any());
-        verify(mNativeWrapperMock, never()).on(anyLong(), anyLong());
+
+        // VibrationThread will start this vibration async, so wait before checking it never played.
+        Thread.sleep(10);
+        assertTrue(mVibratorProvider.getEffects().isEmpty());
     }
 
     @Test
-    public void vibrate_withOneShotAndNativeCallbackTriggered_finishesVibration() {
+    public void vibrate_withNativeCallbackTriggered_finishesVibration() throws Exception {
+        mVibratorProvider.setSupportedEffects(VibrationEffect.EFFECT_CLICK);
         VibratorService service = createService();
-        doAnswer(invocation -> {
-            service.onVibrationComplete(invocation.getArgument(1));
-            return null;
-        }).when(mNativeWrapperMock).on(anyLong(), anyLong());
-        Mockito.clearInvocations(mNativeWrapperMock);
 
-        vibrate(service, VibrationEffect.createOneShot(100, VibrationEffect.DEFAULT_AMPLITUDE));
+        vibrate(service, VibrationEffect.get(VibrationEffect.EFFECT_CLICK), ALARM_ATTRS);
 
-        InOrder inOrderVerifier = inOrder(mNativeWrapperMock);
-        inOrderVerifier.verify(mNativeWrapperMock).off();
-        inOrderVerifier.verify(mNativeWrapperMock).on(eq(100L), gt(0L));
-        inOrderVerifier.verify(mNativeWrapperMock).off();
-    }
-
-    @Test
-    public void vibrate_withPrebakedAndNativeCallbackTriggered_finishesVibration() {
-        when(mNativeWrapperMock.getSupportedEffects())
-                .thenReturn(new int[]{VibrationEffect.EFFECT_CLICK});
-        VibratorService service = createService();
-        doAnswer(invocation -> {
-            service.onVibrationComplete(invocation.getArgument(2));
-            return 10_000L; // 10s
-        }).when(mNativeWrapperMock).perform(anyLong(), anyLong(), anyLong());
-        Mockito.clearInvocations(mNativeWrapperMock);
-
-        vibrate(service, VibrationEffect.createPredefined(VibrationEffect.EFFECT_CLICK));
-
-        InOrder inOrderVerifier = inOrder(mNativeWrapperMock);
-        inOrderVerifier.verify(mNativeWrapperMock).off();
-        inOrderVerifier.verify(mNativeWrapperMock).perform(
-                eq((long) VibrationEffect.EFFECT_CLICK),
-                eq((long) VibrationEffect.EFFECT_STRENGTH_STRONG),
-                gt(0L));
-        inOrderVerifier.verify(mNativeWrapperMock).off();
-    }
-
-    @Test
-    public void vibrate_withWaveformAndNativeCallback_callbackIgnoredAndWaveformPlaysCompletely()
-            throws Exception {
-        VibratorService service = createService();
-        doAnswer(invocation -> {
-            service.onVibrationComplete(invocation.getArgument(1));
-            return null;
-        }).when(mNativeWrapperMock).on(anyLong(), anyLong());
-        Mockito.clearInvocations(mNativeWrapperMock);
-
-        VibrationEffect effect = VibrationEffect.createWaveform(new long[]{1, 3, 1, 2}, -1);
-        vibrate(service, effect);
-
-        // Wait for VibrateThread to finish: 1ms OFF, 3ms ON, 1ms OFF, 2ms ON.
-        Thread.sleep(15);
-        InOrder inOrderVerifier = inOrder(mNativeWrapperMock);
-        inOrderVerifier.verify(mNativeWrapperMock, times(2)).off();
-        inOrderVerifier.verify(mNativeWrapperMock).on(eq(3L), anyLong());
-        inOrderVerifier.verify(mNativeWrapperMock).off();
-        inOrderVerifier.verify(mNativeWrapperMock).on(eq(2L), anyLong());
-        inOrderVerifier.verify(mNativeWrapperMock).off();
-    }
-
-    @Test
-    public void vibrate_withComposedAndNativeCallbackTriggered_finishesVibration() {
-        mockVibratorCapabilities(IVibrator.CAP_COMPOSE_EFFECTS);
-        VibratorService service = createService();
-        doAnswer(invocation -> {
-            service.onVibrationComplete(invocation.getArgument(1));
-            return null;
-        }).when(mNativeWrapperMock).compose(any(), anyLong());
-        Mockito.clearInvocations(mNativeWrapperMock);
-
-        VibrationEffect effect = VibrationEffect.startComposition()
-                .addPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK, 1f, 10)
-                .compose();
-        vibrate(service, effect);
-
-        InOrder inOrderVerifier = inOrder(mNativeWrapperMock);
-        inOrderVerifier.verify(mNativeWrapperMock).off();
-        inOrderVerifier.verify(mNativeWrapperMock).compose(
-                any(VibrationEffect.Composition.PrimitiveEffect[].class), gt(0L));
-        inOrderVerifier.verify(mNativeWrapperMock).off();
-    }
-
-    @Test
-    public void cancelVibrate_withDeviceVibrating_callsoff() {
-        VibratorService service = createService();
-        vibrate(service, VibrationEffect.createOneShot(100, VibrationEffect.DEFAULT_AMPLITUDE));
+        // VibrationThread will start this vibration async, so wait before triggering callbacks.
+        Thread.sleep(10);
         assertTrue(service.isVibrating());
-        Mockito.clearInvocations(mNativeWrapperMock);
 
-        service.cancelVibrate(service);
+        // Trigger callbacks from controller.
+        mTestLooper.moveTimeForward(50);
+        mTestLooper.dispatchAll();
+
+        // VibrationThread needs some time to react to native callbacks and stop the vibrator.
+        Thread.sleep(10);
         assertFalse(service.isVibrating());
-        verify(mNativeWrapperMock).off();
     }
 
     @Test
-    public void cancelVibrate_withDeviceNotVibrating_ignoresCall() {
+    public void cancelVibrate_withDeviceVibrating_callsOff() throws Exception {
         VibratorService service = createService();
-        Mockito.clearInvocations(mNativeWrapperMock);
+
+        vibrate(service, VibrationEffect.createOneShot(100, 100), ALARM_ATTRS);
+
+        // VibrationThread will start this vibration async, so wait before checking.
+        Thread.sleep(10);
+        assertTrue(service.isVibrating());
 
         service.cancelVibrate(service);
+
+        // VibrationThread will stop this vibration async, so wait before checking.
+        Thread.sleep(10);
         assertFalse(service.isVibrating());
-        verify(mNativeWrapperMock, never()).off();
     }
 
     @Test
@@ -653,12 +516,11 @@
         VibratorService service = createService();
         service.registerVibratorStateListener(mVibratorStateListenerMock);
 
-        vibrate(service, VibrationEffect.createOneShot(10, VibrationEffect.DEFAULT_AMPLITUDE));
-        service.cancelVibrate(service);
+        vibrateAndWait(service, VibrationEffect.createOneShot(100, 100), ALARM_ATTRS);
 
         InOrder inOrderVerifier = inOrder(mVibratorStateListenerMock);
         // First notification done when listener is registered.
-        inOrderVerifier.verify(mVibratorStateListenerMock).onVibrating(false);
+        inOrderVerifier.verify(mVibratorStateListenerMock).onVibrating(eq(false));
         inOrderVerifier.verify(mVibratorStateListenerMock).onVibrating(eq(true));
         inOrderVerifier.verify(mVibratorStateListenerMock).onVibrating(eq(false));
         inOrderVerifier.verifyNoMoreInteractions();
@@ -671,18 +533,25 @@
         service.registerVibratorStateListener(mVibratorStateListenerMock);
         verify(mVibratorStateListenerMock).onVibrating(false);
 
-        vibrate(service, VibrationEffect.createOneShot(5, VibrationEffect.DEFAULT_AMPLITUDE));
-        verify(mVibratorStateListenerMock).onVibrating(true);
+        vibrate(service, VibrationEffect.createOneShot(100, 100), ALARM_ATTRS);
 
+        // VibrationThread will start this vibration async, so wait before triggering callbacks.
+        Thread.sleep(10);
         service.unregisterVibratorStateListener(mVibratorStateListenerMock);
-        Mockito.clearInvocations(mVibratorStateListenerMock);
+        // Trigger callbacks from controller.
+        mTestLooper.moveTimeForward(150);
+        mTestLooper.dispatchAll();
 
-        vibrate(service, VibrationEffect.createOneShot(10, VibrationEffect.DEFAULT_AMPLITUDE));
-        verifyNoMoreInteractions(mVibratorStateListenerMock);
+        InOrder inOrderVerifier = inOrder(mVibratorStateListenerMock);
+        // First notification done when listener is registered.
+        inOrderVerifier.verify(mVibratorStateListenerMock).onVibrating(eq(false));
+        inOrderVerifier.verify(mVibratorStateListenerMock).onVibrating(eq(true));
+        inOrderVerifier.verify(mVibratorStateListenerMock, atLeastOnce()).asBinder(); // unregister
+        inOrderVerifier.verifyNoMoreInteractions();
     }
 
     @Test
-    public void scale_withPrebaked_userIntensitySettingAsEffectStrength() {
+    public void scale_withPrebaked_userIntensitySettingAsEffectStrength() throws Exception {
         // Alarm vibration is always VIBRATION_INTENSITY_HIGH.
         setUserSetting(Settings.System.NOTIFICATION_VIBRATION_INTENSITY,
                 Vibrator.VIBRATION_INTENSITY_MEDIUM);
@@ -690,28 +559,29 @@
                 Vibrator.VIBRATION_INTENSITY_LOW);
         setUserSetting(Settings.System.RING_VIBRATION_INTENSITY,
                 Vibrator.VIBRATION_INTENSITY_OFF);
+        mVibratorProvider.setSupportedEffects(
+                VibrationEffect.EFFECT_CLICK,
+                VibrationEffect.EFFECT_TICK,
+                VibrationEffect.EFFECT_DOUBLE_CLICK,
+                VibrationEffect.EFFECT_HEAVY_CLICK);
         VibratorService service = createService();
 
-        vibrate(service, VibrationEffect.createPredefined(VibrationEffect.EFFECT_CLICK),
-                ALARM_ATTRS);
-        vibrate(service, VibrationEffect.createPredefined(VibrationEffect.EFFECT_TICK),
+        vibrateAndWait(service, VibrationEffect.get(VibrationEffect.EFFECT_CLICK), ALARM_ATTRS);
+        vibrateAndWait(service, VibrationEffect.get(VibrationEffect.EFFECT_TICK),
                 NOTIFICATION_ATTRS);
-        vibrate(service, VibrationEffect.createPredefined(VibrationEffect.EFFECT_DOUBLE_CLICK),
+        vibrateAndWait(service, VibrationEffect.get(VibrationEffect.EFFECT_DOUBLE_CLICK),
                 HAPTIC_FEEDBACK_ATTRS);
-        vibrate(service, VibrationEffect.createPredefined(VibrationEffect.EFFECT_HEAVY_CLICK),
-                RINGTONE_ATTRS);
+        vibrate(service, VibrationEffect.get(VibrationEffect.EFFECT_HEAVY_CLICK), RINGTONE_ATTRS);
 
-        verify(mNativeWrapperMock).perform(
-                eq((long) VibrationEffect.EFFECT_CLICK),
-                eq((long) VibrationEffect.EFFECT_STRENGTH_STRONG), anyLong());
-        verify(mNativeWrapperMock).perform(
-                eq((long) VibrationEffect.EFFECT_TICK),
-                eq((long) VibrationEffect.EFFECT_STRENGTH_MEDIUM), anyLong());
-        verify(mNativeWrapperMock).perform(
-                eq((long) VibrationEffect.EFFECT_DOUBLE_CLICK),
-                eq((long) VibrationEffect.EFFECT_STRENGTH_LIGHT), anyLong());
-        verify(mNativeWrapperMock, never()).perform(
-                eq((long) VibrationEffect.EFFECT_HEAVY_CLICK), anyLong(), anyLong());
+        List<Integer> playedStrengths = mVibratorProvider.getEffects().stream()
+                .map(VibrationEffect.Prebaked.class::cast)
+                .map(VibrationEffect.Prebaked::getEffectStrength)
+                .collect(Collectors.toList());
+        assertEquals(Arrays.asList(
+                VibrationEffect.EFFECT_STRENGTH_STRONG,
+                VibrationEffect.EFFECT_STRENGTH_MEDIUM,
+                VibrationEffect.EFFECT_STRENGTH_LIGHT),
+                playedStrengths);
     }
 
     @Test
@@ -725,31 +595,28 @@
         setUserSetting(Settings.System.RING_VIBRATION_INTENSITY,
                 Vibrator.VIBRATION_INTENSITY_OFF);
 
-        mockVibratorCapabilities(IVibrator.CAP_AMPLITUDE_CONTROL);
+        mVibratorProvider.setCapabilities(IVibrator.CAP_AMPLITUDE_CONTROL);
         VibratorService service = createService();
 
-        vibrate(service, VibrationEffect.createOneShot(20, 100), ALARM_ATTRS);
-        vibrate(service, VibrationEffect.createOneShot(20, 100), NOTIFICATION_ATTRS);
-        vibrate(service, VibrationEffect.createOneShot(20, 255), RINGTONE_ATTRS);
-        vibrate(service, VibrationEffect.createWaveform(new long[] { 10 }, new int[] { 100 }, -1),
+        vibrateAndWait(service, VibrationEffect.createOneShot(20, 100), ALARM_ATTRS);
+        vibrateAndWait(service, VibrationEffect.createOneShot(20, 100), NOTIFICATION_ATTRS);
+        vibrateAndWait(service,
+                VibrationEffect.createWaveform(new long[]{10}, new int[]{100}, -1),
                 HAPTIC_FEEDBACK_ATTRS);
+        vibrate(service, VibrationEffect.createOneShot(20, 255), RINGTONE_ATTRS);
 
-        // Waveform effect runs on a separate thread.
-        Thread.sleep(15);
-
+        List<Integer> amplitudes = mVibratorProvider.getAmplitudes();
+        assertEquals(3, amplitudes.size());
         // Alarm vibration is never scaled.
-        verify(mNativeWrapperMock).setAmplitude(eq(100));
+        assertEquals(100, amplitudes.get(0).intValue());
         // Notification vibrations will be scaled with SCALE_VERY_HIGH.
-        verify(mNativeWrapperMock).setAmplitude(intThat(amplitude -> amplitude > 150));
+        assertTrue(amplitudes.get(1) > 150);
         // Haptic feedback vibrations will be scaled with SCALE_LOW.
-        verify(mNativeWrapperMock).setAmplitude(
-                intThat(amplitude -> amplitude < 100 && amplitude > 50));
-        // Ringtone vibration is off.
-        verify(mNativeWrapperMock, never()).setAmplitude(eq(255));
+        assertTrue(amplitudes.get(2) < 100 && amplitudes.get(2) > 50);
     }
 
     @Test
-    public void scale_withComposed_usesScaleLevelOnPrimitiveScaleValues() {
+    public void scale_withComposed_usesScaleLevelOnPrimitiveScaleValues() throws Exception {
         when(mVibratorMock.getDefaultNotificationVibrationIntensity())
                 .thenReturn(Vibrator.VIBRATION_INTENSITY_LOW);
         setUserSetting(Settings.System.NOTIFICATION_VIBRATION_INTENSITY,
@@ -759,82 +626,72 @@
         setUserSetting(Settings.System.RING_VIBRATION_INTENSITY,
                 Vibrator.VIBRATION_INTENSITY_OFF);
 
-        mockVibratorCapabilities(IVibrator.CAP_COMPOSE_EFFECTS);
+        mVibratorProvider.setCapabilities(IVibrator.CAP_COMPOSE_EFFECTS);
         VibratorService service = createService();
 
         VibrationEffect effect = VibrationEffect.startComposition()
                 .addPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK, 1f)
                 .addPrimitive(VibrationEffect.Composition.PRIMITIVE_TICK, 0.5f)
                 .compose();
-        ArgumentCaptor<VibrationEffect.Composition.PrimitiveEffect[]> primitivesCaptor =
-                ArgumentCaptor.forClass(VibrationEffect.Composition.PrimitiveEffect[].class);
 
-        vibrate(service, effect, ALARM_ATTRS);
-        vibrate(service, effect, NOTIFICATION_ATTRS);
-        vibrate(service, effect, HAPTIC_FEEDBACK_ATTRS);
+        vibrateAndWait(service, effect, ALARM_ATTRS);
+        vibrateAndWait(service, effect, NOTIFICATION_ATTRS);
+        vibrateAndWait(service, effect, HAPTIC_FEEDBACK_ATTRS);
         vibrate(service, effect, RINGTONE_ATTRS);
 
-        // Ringtone vibration is off, so only the other 3 are propagated to native.
-        verify(mNativeWrapperMock, times(3)).compose(
-                primitivesCaptor.capture(), anyLong());
+        List<VibrationEffect.Composition.PrimitiveEffect> primitives =
+                mVibratorProvider.getEffects().stream()
+                        .map(VibrationEffect.Composed.class::cast)
+                        .map(VibrationEffect.Composed::getPrimitiveEffects)
+                        .flatMap(List::stream)
+                        .collect(Collectors.toList());
 
-        List<VibrationEffect.Composition.PrimitiveEffect[]> values =
-                primitivesCaptor.getAllValues();
+        // Ringtone vibration is off, so only the other 3 are propagated to native.
+        assertEquals(6, primitives.size());
 
         // Alarm vibration is never scaled.
-        assertEquals(1f, values.get(0)[0].scale, /* delta= */ 1e-2);
-        assertEquals(0.5f, values.get(0)[1].scale, /* delta= */ 1e-2);
+        assertEquals(1f, primitives.get(0).scale, /* delta= */ 1e-2);
+        assertEquals(0.5f, primitives.get(1).scale, /* delta= */ 1e-2);
 
         // Notification vibrations will be scaled with SCALE_VERY_HIGH.
-        assertEquals(1f, values.get(1)[0].scale, /* delta= */ 1e-2);
-        assertTrue(0.7 < values.get(1)[1].scale);
+        assertEquals(1f, primitives.get(2).scale, /* delta= */ 1e-2);
+        assertTrue(0.7 < primitives.get(3).scale);
 
         // Haptic feedback vibrations will be scaled with SCALE_LOW.
-        assertTrue(0.5 < values.get(2)[0].scale);
-        assertTrue(0.5 > values.get(2)[1].scale);
-    }
-
-    private void vibrate(VibratorService service, VibrationEffect effect) {
-        vibrate(service, effect, ALARM_ATTRS);
+        assertTrue(0.5 < primitives.get(4).scale);
+        assertTrue(0.5 > primitives.get(5).scale);
     }
 
     private void vibrate(VibratorService service, VibrationEffect effect,
-            VibrationAttributes attributes) {
-        service.vibrate(UID, PACKAGE_NAME, effect, attributes, "some reason", service);
+            VibrationAttributes attrs) {
+        service.vibrate(UID, PACKAGE_NAME, effect, attrs, "some reason", service);
     }
 
-    private int vibrateAndMeasure(
-            VibratorService service, VibrationEffect effect, long timeoutSecs) throws Exception {
-        AtomicLong startTime = new AtomicLong(0);
-        AtomicLong endTime = new AtomicLong(0);
+    private void vibrateAndWait(VibratorService service, VibrationEffect effect,
+            VibrationAttributes attrs) throws Exception {
         CountDownLatch startedCount = new CountDownLatch(1);
         CountDownLatch finishedCount = new CountDownLatch(1);
         service.registerVibratorStateListener(new IVibratorStateListener() {
             @Override
-            public void onVibrating(boolean vibrating) throws RemoteException {
+            public void onVibrating(boolean vibrating) {
                 if (vibrating) {
-                    startTime.set(SystemClock.uptimeMillis());
                     startedCount.countDown();
                 } else if (startedCount.getCount() == 0) {
-                    endTime.set(SystemClock.uptimeMillis());
                     finishedCount.countDown();
                 }
             }
 
             @Override
             public IBinder asBinder() {
-                return mVibratorStateListenerBinderMock;
+                return mock(IBinder.class);
             }
         });
 
-        vibrate(service, effect);
-
-        assertTrue(finishedCount.await(timeoutSecs, TimeUnit.SECONDS));
-        return (int) (endTime.get() - startTime.get());
-    }
-
-    private void mockVibratorCapabilities(int capabilities) {
-        when(mNativeWrapperMock.getCapabilities()).thenReturn((long) capabilities);
+        mTestLooper.startAutoDispatch();
+        service.vibrate(UID, PACKAGE_NAME, effect, attrs, "some reason", service);
+        assertTrue(startedCount.await(1, TimeUnit.SECONDS));
+        assertTrue(finishedCount.await(1, TimeUnit.SECONDS));
+        mTestLooper.stopAutoDispatchAndIgnoreExceptions();
     }
 
     private InputDevice createInputDeviceWithVibrator(int id) {
diff --git a/services/tests/servicestests/src/com/android/server/vibrator/FakeVibratorControllerProvider.java b/services/tests/servicestests/src/com/android/server/vibrator/FakeVibratorControllerProvider.java
new file mode 100644
index 0000000..f562c16
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/vibrator/FakeVibratorControllerProvider.java
@@ -0,0 +1,221 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.vibrator;
+
+import android.annotation.Nullable;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.VibrationEffect;
+
+import com.android.server.vibrator.VibratorController.OnVibrationCompleteListener;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Provides {@link VibratorController} with controlled vibrator hardware capabilities and
+ * interactions.
+ */
+public final class FakeVibratorControllerProvider {
+
+    private static final int EFFECT_DURATION = 20;
+
+    private final Map<Long, VibrationEffect.Prebaked> mEnabledAlwaysOnEffects = new HashMap<>();
+    private final List<VibrationEffect> mEffects = new ArrayList<>();
+    private final List<Integer> mAmplitudes = new ArrayList<>();
+    private final Handler mHandler;
+    private final FakeNativeWrapper mNativeWrapper;
+
+    private boolean mIsAvailable = true;
+    private long mLatency;
+
+    private int mCapabilities;
+    private int[] mSupportedEffects;
+    private int[] mSupportedPrimitives;
+
+    private final class FakeNativeWrapper extends VibratorController.NativeWrapper {
+        public int vibratorId;
+        public OnVibrationCompleteListener listener;
+        public boolean isInitialized;
+
+        public void init(int vibratorId, OnVibrationCompleteListener listener) {
+            isInitialized = true;
+            this.vibratorId = vibratorId;
+            this.listener = listener;
+        }
+
+        public boolean isAvailable() {
+            return mIsAvailable;
+        }
+
+        public void on(long milliseconds, long vibrationId) {
+            VibrationEffect effect = VibrationEffect.createOneShot(
+                    milliseconds, VibrationEffect.DEFAULT_AMPLITUDE);
+            mEffects.add(effect);
+            applyLatency();
+            scheduleListener(milliseconds, vibrationId);
+        }
+
+        public void off() {
+        }
+
+        public void setAmplitude(int amplitude) {
+            mAmplitudes.add(amplitude);
+            applyLatency();
+        }
+
+        public int[] getSupportedEffects() {
+            return mSupportedEffects;
+        }
+
+        public int[] getSupportedPrimitives() {
+            return mSupportedPrimitives;
+        }
+
+        public long perform(long effect, long strength, long vibrationId) {
+            if (mSupportedEffects == null
+                    || Arrays.binarySearch(mSupportedEffects, (int) effect) < 0) {
+                return 0;
+            }
+            mEffects.add(new VibrationEffect.Prebaked((int) effect, false, (int) strength));
+            applyLatency();
+            scheduleListener(EFFECT_DURATION, vibrationId);
+            return EFFECT_DURATION;
+        }
+
+        public void compose(VibrationEffect.Composition.PrimitiveEffect[] effect,
+                long vibrationId) {
+            VibrationEffect.Composed composed = new VibrationEffect.Composed(Arrays.asList(effect));
+            mEffects.add(composed);
+            applyLatency();
+            long duration = EFFECT_DURATION * effect.length;
+            for (VibrationEffect.Composition.PrimitiveEffect e : effect) {
+                duration += e.delay;
+            }
+            scheduleListener(duration, vibrationId);
+        }
+
+        public void setExternalControl(boolean enabled) {
+        }
+
+        public long getCapabilities() {
+            return mCapabilities;
+        }
+
+        public void alwaysOnEnable(long id, long effect, long strength) {
+            VibrationEffect.Prebaked prebaked = new VibrationEffect.Prebaked((int) effect, false,
+                    (int) strength);
+            mEnabledAlwaysOnEffects.put(id, prebaked);
+        }
+
+        public void alwaysOnDisable(long id) {
+            mEnabledAlwaysOnEffects.remove(id);
+        }
+
+        private void applyLatency() {
+            try {
+                if (mLatency > 0) {
+                    Thread.sleep(mLatency);
+                }
+            } catch (InterruptedException e) {
+            }
+        }
+
+        private void scheduleListener(long vibrationDuration, long vibrationId) {
+            mHandler.postDelayed(() -> listener.onComplete(vibratorId, vibrationId),
+                    vibrationDuration);
+        }
+    }
+
+    public FakeVibratorControllerProvider(Looper looper) {
+        mHandler = new Handler(looper);
+        mNativeWrapper = new FakeNativeWrapper();
+    }
+
+    public VibratorController newVibratorController(
+            int vibratorId, OnVibrationCompleteListener listener) {
+        return new VibratorController(vibratorId, listener, mNativeWrapper);
+    }
+
+    /** Return {@code true} if this controller was initialized. */
+    public boolean isInitialized() {
+        return mNativeWrapper.isInitialized;
+    }
+
+    /**
+     * Disable fake vibrator hardware, mocking a state where the underlying service is unavailable.
+     */
+    public void disableVibrators() {
+        mIsAvailable = false;
+    }
+
+    /**
+     * Sets the latency this controller should fake for turning the vibrator hardware on or setting
+     * it's vibration amplitude.
+     */
+    public void setLatency(long millis) {
+        mLatency = millis;
+    }
+
+    /** Set the capabilities of the fake vibrator hardware. */
+    public void setCapabilities(int... capabilities) {
+        mCapabilities = Arrays.stream(capabilities).reduce(0, (a, b) -> a | b);
+    }
+
+    /** Set the effects supported by the fake vibrator hardware. */
+    public void setSupportedEffects(int... effects) {
+        if (effects != null) {
+            effects = Arrays.copyOf(effects, effects.length);
+            Arrays.sort(effects);
+        }
+        mSupportedEffects = effects;
+    }
+
+    /** Set the primitives supported by the fake vibrator hardware. */
+    public void setSupportedPrimitives(int... primitives) {
+        if (primitives != null) {
+            primitives = Arrays.copyOf(primitives, primitives.length);
+            Arrays.sort(primitives);
+        }
+        mSupportedPrimitives = primitives;
+    }
+
+    /**
+     * Return the amplitudes set by this controller, including zeroes for each time the vibrator was
+     * turned off.
+     */
+    public List<Integer> getAmplitudes() {
+        return new ArrayList<>(mAmplitudes);
+    }
+
+    /** Return list of {@link VibrationEffect} played by this controller, in order. */
+    public List<VibrationEffect> getEffects() {
+        return new ArrayList<>(mEffects);
+    }
+
+    /**
+     * Return the {@link VibrationEffect.Prebaked} effect enabled with given id, or {@code null} if
+     * missing or disabled.
+     */
+    @Nullable
+    public VibrationEffect.Prebaked getAlwaysOnEffect(int id) {
+        return mEnabledAlwaysOnEffects.get((long) id);
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/vibrator/InputDeviceDelegateTest.java b/services/tests/servicestests/src/com/android/server/vibrator/InputDeviceDelegateTest.java
index ac93ff6..28d313b 100644
--- a/services/tests/servicestests/src/com/android/server/vibrator/InputDeviceDelegateTest.java
+++ b/services/tests/servicestests/src/com/android/server/vibrator/InputDeviceDelegateTest.java
@@ -34,6 +34,7 @@
 import android.hardware.input.IInputDevicesChangedListener;
 import android.hardware.input.IInputManager;
 import android.hardware.input.InputManager;
+import android.os.CombinedVibrationEffect;
 import android.os.Handler;
 import android.os.Process;
 import android.os.VibrationAttributes;
@@ -66,6 +67,9 @@
     private static final String REASON = "some reason";
     private static final VibrationAttributes VIBRATION_ATTRIBUTES =
             new VibrationAttributes.Builder().setUsage(VibrationAttributes.USAGE_ALARM).build();
+    private static final VibrationEffect EFFECT = VibrationEffect.createOneShot(100, 255);
+    private static final CombinedVibrationEffect SYNCED_EFFECT =
+            CombinedVibrationEffect.createSynced(EFFECT);
 
     @Rule public MockitoRule rule = MockitoJUnit.rule();
 
@@ -227,10 +231,9 @@
 
     @Test
     public void vibrateIfAvailable_withNoInputDevice_returnsFalse() {
-        VibrationEffect effect = VibrationEffect.createOneShot(100, 255);
         assertFalse(mInputDeviceDelegate.isAvailable());
         assertFalse(mInputDeviceDelegate.vibrateIfAvailable(
-                UID, PACKAGE_NAME, effect, REASON, VIBRATION_ATTRIBUTES));
+                UID, PACKAGE_NAME, SYNCED_EFFECT, REASON, VIBRATION_ATTRIBUTES));
     }
 
     @Test
@@ -241,11 +244,10 @@
         when(mIInputManagerMock.getInputDevice(eq(2))).thenReturn(createInputDeviceWithVibrator(2));
         mInputDeviceDelegate.updateInputDeviceVibrators(/* vibrateInputDevices= */ true);
 
-        VibrationEffect effect = VibrationEffect.createOneShot(100, 255);
         assertTrue(mInputDeviceDelegate.vibrateIfAvailable(
-                UID, PACKAGE_NAME, effect, REASON, VIBRATION_ATTRIBUTES));
-        verify(mIInputManagerMock).vibrate(eq(1), same(effect), any());
-        verify(mIInputManagerMock).vibrate(eq(2), same(effect), any());
+                UID, PACKAGE_NAME, SYNCED_EFFECT, REASON, VIBRATION_ATTRIBUTES));
+        verify(mIInputManagerMock).vibrate(eq(1), same(EFFECT), any());
+        verify(mIInputManagerMock).vibrate(eq(2), same(EFFECT), any());
     }
 
     @Test
diff --git a/services/tests/servicestests/src/com/android/server/vibrator/VibrationScalerTest.java b/services/tests/servicestests/src/com/android/server/vibrator/VibrationScalerTest.java
index 1a4ac07..82a6937 100644
--- a/services/tests/servicestests/src/com/android/server/vibrator/VibrationScalerTest.java
+++ b/services/tests/servicestests/src/com/android/server/vibrator/VibrationScalerTest.java
@@ -26,6 +26,7 @@
 import android.content.ContentResolver;
 import android.content.Context;
 import android.content.ContextWrapper;
+import android.os.CombinedVibrationEffect;
 import android.os.Handler;
 import android.os.IExternalVibratorService;
 import android.os.PowerManagerInternal;
@@ -131,6 +132,45 @@
     }
 
     @Test
+    public void scale_withCombined_resolvesAndScalesRecursively() {
+        setUserSetting(Settings.System.NOTIFICATION_VIBRATION_INTENSITY,
+                Vibrator.VIBRATION_INTENSITY_HIGH);
+        VibrationEffect prebaked = VibrationEffect.createPredefined(VibrationEffect.EFFECT_CLICK);
+        VibrationEffect oneShot = VibrationEffect.createOneShot(10, 10);
+
+        CombinedVibrationEffect.Mono monoScaled = mVibrationScaler.scale(
+                CombinedVibrationEffect.createSynced(prebaked),
+                VibrationAttributes.USAGE_NOTIFICATION);
+        VibrationEffect.Prebaked prebakedScaled = (VibrationEffect.Prebaked) monoScaled.getEffect();
+        assertEquals(prebakedScaled.getEffectStrength(), VibrationEffect.EFFECT_STRENGTH_STRONG);
+
+        CombinedVibrationEffect.Stereo stereoScaled = mVibrationScaler.scale(
+                CombinedVibrationEffect.startSynced()
+                        .addVibrator(1, prebaked)
+                        .addVibrator(2, oneShot)
+                        .combine(),
+                VibrationAttributes.USAGE_NOTIFICATION);
+        prebakedScaled = (VibrationEffect.Prebaked) stereoScaled.getEffects().get(1);
+        assertEquals(prebakedScaled.getEffectStrength(), VibrationEffect.EFFECT_STRENGTH_STRONG);
+        VibrationEffect.OneShot oneshotScaled =
+                (VibrationEffect.OneShot) stereoScaled.getEffects().get(2);
+        assertTrue(oneshotScaled.getAmplitude() > 0);
+
+        CombinedVibrationEffect.Sequential sequentialScaled = mVibrationScaler.scale(
+                CombinedVibrationEffect.startSequential()
+                        .addNext(CombinedVibrationEffect.createSynced(prebaked))
+                        .addNext(CombinedVibrationEffect.createSynced(oneShot))
+                        .combine(),
+                VibrationAttributes.USAGE_NOTIFICATION);
+        monoScaled = (CombinedVibrationEffect.Mono) sequentialScaled.getEffects().get(0);
+        prebakedScaled = (VibrationEffect.Prebaked) monoScaled.getEffect();
+        assertEquals(prebakedScaled.getEffectStrength(), VibrationEffect.EFFECT_STRENGTH_STRONG);
+        monoScaled = (CombinedVibrationEffect.Mono) sequentialScaled.getEffects().get(1);
+        oneshotScaled = (VibrationEffect.OneShot) monoScaled.getEffect();
+        assertTrue(oneshotScaled.getAmplitude() > 0);
+    }
+
+    @Test
     public void scale_withPrebaked_setsEffectStrengthBasedOnSettings() {
         setUserSetting(Settings.System.NOTIFICATION_VIBRATION_INTENSITY,
                 Vibrator.VIBRATION_INTENSITY_HIGH);
@@ -158,6 +198,28 @@
     }
 
     @Test
+    public void scale_withPrebakedAndFallback_resolvesAndScalesRecursively() {
+        setUserSetting(Settings.System.NOTIFICATION_VIBRATION_INTENSITY,
+                Vibrator.VIBRATION_INTENSITY_HIGH);
+        VibrationEffect.OneShot fallback2 = (VibrationEffect.OneShot) VibrationEffect.createOneShot(
+                10, VibrationEffect.DEFAULT_AMPLITUDE);
+        VibrationEffect.Prebaked fallback1 = new VibrationEffect.Prebaked(
+                VibrationEffect.EFFECT_TICK, VibrationEffect.EFFECT_STRENGTH_MEDIUM, fallback2);
+        VibrationEffect.Prebaked effect = new VibrationEffect.Prebaked(VibrationEffect.EFFECT_CLICK,
+                VibrationEffect.EFFECT_STRENGTH_MEDIUM, fallback1);
+
+        VibrationEffect.Prebaked scaled = mVibrationScaler.scale(
+                effect, VibrationAttributes.USAGE_NOTIFICATION);
+        VibrationEffect.Prebaked scaledFallback1 =
+                (VibrationEffect.Prebaked) scaled.getFallbackEffect();
+        VibrationEffect.OneShot scaledFallback2 =
+                (VibrationEffect.OneShot) scaledFallback1.getFallbackEffect();
+        assertEquals(scaled.getEffectStrength(), VibrationEffect.EFFECT_STRENGTH_STRONG);
+        assertEquals(scaledFallback1.getEffectStrength(), VibrationEffect.EFFECT_STRENGTH_STRONG);
+        assertTrue(scaledFallback2.getAmplitude() > 0);
+    }
+
+    @Test
     public void scale_withOneShotAndWaveform_resolvesAmplitude() {
         // No scale, default amplitude still resolved
         when(mVibratorMock.getDefaultRingVibrationIntensity())
diff --git a/services/tests/servicestests/src/com/android/server/vibrator/VibrationThreadTest.java b/services/tests/servicestests/src/com/android/server/vibrator/VibrationThreadTest.java
new file mode 100644
index 0000000..bee7392
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/vibrator/VibrationThreadTest.java
@@ -0,0 +1,658 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.vibrator;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyLong;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.ArgumentMatchers.same;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.inOrder;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+
+import android.hardware.vibrator.IVibrator;
+import android.os.CombinedVibrationEffect;
+import android.os.IBinder;
+import android.os.PowerManager;
+import android.os.Process;
+import android.os.SystemClock;
+import android.os.VibrationAttributes;
+import android.os.VibrationEffect;
+import android.os.test.TestLooper;
+import android.platform.test.annotations.Presubmit;
+import android.util.SparseArray;
+
+import androidx.test.InstrumentationRegistry;
+
+import com.android.internal.app.IBatteryStats;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.mockito.InOrder;
+import org.mockito.Mock;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Tests for {@link VibrationThread}.
+ *
+ * Build/Install/Run:
+ * atest FrameworksServicesTests:VibrationThreadTest
+ */
+@Presubmit
+public class VibrationThreadTest {
+
+    private static final int TEST_TIMEOUT_MILLIS = 1_000;
+    private static final int UID = Process.ROOT_UID;
+    private static final int VIBRATOR_ID = 1;
+    private static final String PACKAGE_NAME = "package";
+    private static final VibrationAttributes ATTRS = new VibrationAttributes.Builder().build();
+
+    @Rule public MockitoRule mMockitoRule = MockitoJUnit.rule();
+
+    @Mock private VibrationThread.VibrationCallbacks mThreadCallbacks;
+    @Mock private VibratorController.OnVibrationCompleteListener mControllerCallbacks;
+    @Mock private IBinder mVibrationToken;
+    @Mock private IBatteryStats mIBatteryStatsMock;
+
+    private final Map<Integer, FakeVibratorControllerProvider> mVibratorProviders = new HashMap<>();
+    private PowerManager.WakeLock mWakeLock;
+    private TestLooper mTestLooper;
+
+    @Before
+    public void setUp() throws Exception {
+        mTestLooper = new TestLooper();
+        mWakeLock = InstrumentationRegistry.getContext().getSystemService(
+                PowerManager.class).newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*vibrator*");
+
+        mockVibrators(VIBRATOR_ID);
+    }
+
+    @Test
+    public void vibrate_noVibrator_ignoresVibration() {
+        mVibratorProviders.clear();
+        long vibrationId = 1;
+        CombinedVibrationEffect effect = CombinedVibrationEffect.createSynced(
+                VibrationEffect.get(VibrationEffect.EFFECT_CLICK));
+        VibrationThread thread = startThreadAndDispatcher(vibrationId, effect);
+        waitForCompletion(thread);
+
+        verify(mControllerCallbacks, never()).onComplete(anyInt(), eq(vibrationId));
+        verify(mThreadCallbacks).onVibrationEnded(eq(vibrationId), eq(Vibration.Status.IGNORED));
+    }
+
+    @Test
+    public void vibrate_missingVibrators_ignoresVibration() {
+        long vibrationId = 1;
+        CombinedVibrationEffect effect = CombinedVibrationEffect.startSequential()
+                .addNext(2, VibrationEffect.get(VibrationEffect.EFFECT_CLICK))
+                .addNext(3, VibrationEffect.get(VibrationEffect.EFFECT_TICK))
+                .combine();
+        VibrationThread thread = startThreadAndDispatcher(vibrationId, effect);
+        waitForCompletion(thread);
+
+        verify(mControllerCallbacks, never()).onComplete(anyInt(), eq(vibrationId));
+        verify(mThreadCallbacks).onVibrationEnded(eq(vibrationId), eq(Vibration.Status.IGNORED));
+    }
+
+    @Test
+    public void vibrate_singleVibratorOneShot_runsVibrationAndSetsAmplitude() throws Exception {
+        mVibratorProviders.get(VIBRATOR_ID).setCapabilities(IVibrator.CAP_AMPLITUDE_CONTROL);
+
+        long vibrationId = 1;
+        VibrationEffect effect = VibrationEffect.createOneShot(10, 100);
+        VibrationThread thread = startThreadAndDispatcher(vibrationId, effect);
+        waitForCompletion(thread);
+
+        verify(mIBatteryStatsMock).noteVibratorOn(eq(UID), eq(10L));
+        verify(mIBatteryStatsMock).noteVibratorOff(eq(UID));
+        verify(mControllerCallbacks).onComplete(eq(VIBRATOR_ID), eq(vibrationId));
+        verify(mThreadCallbacks).onVibrationEnded(eq(vibrationId), eq(Vibration.Status.FINISHED));
+        assertFalse(thread.getVibrators().get(VIBRATOR_ID).isVibrating());
+
+        assertEquals(Arrays.asList(expectedOneShot(10)),
+                mVibratorProviders.get(VIBRATOR_ID).getEffects());
+        assertEquals(Arrays.asList(100), mVibratorProviders.get(VIBRATOR_ID).getAmplitudes());
+    }
+
+    @Test
+    public void vibrate_oneShotWithoutAmplitudeControl_runsVibrationWithDefaultAmplitude()
+            throws Exception {
+        long vibrationId = 1;
+        VibrationEffect effect = VibrationEffect.createOneShot(10, 100);
+        VibrationThread thread = startThreadAndDispatcher(vibrationId, effect);
+        waitForCompletion(thread);
+
+        verify(mIBatteryStatsMock).noteVibratorOn(eq(UID), eq(10L));
+        verify(mIBatteryStatsMock).noteVibratorOff(eq(UID));
+        verify(mControllerCallbacks).onComplete(eq(VIBRATOR_ID), eq(vibrationId));
+        verify(mThreadCallbacks).onVibrationEnded(eq(vibrationId), eq(Vibration.Status.FINISHED));
+        assertFalse(thread.getVibrators().get(VIBRATOR_ID).isVibrating());
+
+        assertEquals(Arrays.asList(expectedOneShot(10)),
+                mVibratorProviders.get(VIBRATOR_ID).getEffects());
+        assertTrue(mVibratorProviders.get(VIBRATOR_ID).getAmplitudes().isEmpty());
+    }
+
+    @Test
+    public void vibrate_singleVibratorWaveform_runsVibrationAndChangesAmplitudes()
+            throws Exception {
+        mVibratorProviders.get(VIBRATOR_ID).setCapabilities(IVibrator.CAP_AMPLITUDE_CONTROL);
+
+        long vibrationId = 1;
+        VibrationEffect effect = VibrationEffect.createWaveform(
+                new long[]{5, 5, 5}, new int[]{1, 2, 3}, -1);
+        VibrationThread thread = startThreadAndDispatcher(vibrationId, effect);
+        waitForCompletion(thread);
+
+        verify(mIBatteryStatsMock).noteVibratorOn(eq(UID), eq(15L));
+        verify(mIBatteryStatsMock).noteVibratorOff(eq(UID));
+        verify(mControllerCallbacks).onComplete(eq(VIBRATOR_ID), eq(vibrationId));
+        verify(mThreadCallbacks).onVibrationEnded(eq(vibrationId), eq(Vibration.Status.FINISHED));
+        assertFalse(thread.getVibrators().get(VIBRATOR_ID).isVibrating());
+
+        assertEquals(Arrays.asList(expectedOneShot(15)),
+                mVibratorProviders.get(VIBRATOR_ID).getEffects());
+        assertEquals(Arrays.asList(1, 2, 3), mVibratorProviders.get(VIBRATOR_ID).getAmplitudes());
+    }
+
+    @Test
+    public void vibrate_singleVibratorRepeatingWaveform_runsVibrationUntilThreadCancelled()
+            throws Exception {
+        mVibratorProviders.get(VIBRATOR_ID).setCapabilities(IVibrator.CAP_AMPLITUDE_CONTROL);
+
+        long vibrationId = 1;
+        int[] amplitudes = new int[]{1, 2, 3};
+        VibrationEffect effect = VibrationEffect.createWaveform(new long[]{5, 5, 5}, amplitudes, 0);
+        VibrationThread thread = startThreadAndDispatcher(vibrationId, effect);
+
+        Thread.sleep(35);
+        // Vibration still running after 2 cycles.
+        assertTrue(thread.isAlive());
+        assertTrue(thread.getVibrators().get(VIBRATOR_ID).isVibrating());
+
+        thread.cancel();
+        waitForCompletion(thread);
+
+        verify(mIBatteryStatsMock, never()).noteVibratorOn(eq(UID), anyLong());
+        verify(mIBatteryStatsMock, never()).noteVibratorOff(eq(UID));
+        verify(mThreadCallbacks).onVibrationEnded(eq(vibrationId), eq(Vibration.Status.CANCELLED));
+        assertFalse(thread.getVibrators().get(VIBRATOR_ID).isVibrating());
+
+        List<Integer> playedAmplitudes = mVibratorProviders.get(VIBRATOR_ID).getAmplitudes();
+        assertFalse(mVibratorProviders.get(VIBRATOR_ID).getEffects().isEmpty());
+        assertFalse(playedAmplitudes.isEmpty());
+
+        for (int i = 0; i < playedAmplitudes.size(); i++) {
+            assertEquals(amplitudes[i % amplitudes.length], playedAmplitudes.get(i).intValue());
+        }
+    }
+
+    @Test
+    public void vibrate_singleVibratorPrebaked_runsVibration() throws Exception {
+        mVibratorProviders.get(1).setSupportedEffects(VibrationEffect.EFFECT_THUD);
+
+        long vibrationId = 1;
+        VibrationEffect effect = VibrationEffect.get(VibrationEffect.EFFECT_THUD);
+        VibrationThread thread = startThreadAndDispatcher(vibrationId, effect);
+        waitForCompletion(thread);
+
+        verify(mIBatteryStatsMock).noteVibratorOn(eq(UID), eq(20L));
+        verify(mIBatteryStatsMock).noteVibratorOff(eq(UID));
+        verify(mControllerCallbacks).onComplete(eq(VIBRATOR_ID), eq(vibrationId));
+        verify(mThreadCallbacks).onVibrationEnded(eq(vibrationId), eq(Vibration.Status.FINISHED));
+        assertFalse(thread.getVibrators().get(VIBRATOR_ID).isVibrating());
+
+        assertEquals(Arrays.asList(expectedPrebaked(VibrationEffect.EFFECT_THUD)),
+                mVibratorProviders.get(VIBRATOR_ID).getEffects());
+    }
+
+    @Test
+    public void vibrate_singleVibratorPrebakedAndUnsupportedEffectWithFallback_runsFallback()
+            throws Exception {
+        mVibratorProviders.get(VIBRATOR_ID).setCapabilities(IVibrator.CAP_AMPLITUDE_CONTROL);
+
+        long vibrationId = 1;
+        VibrationEffect fallback = VibrationEffect.createOneShot(10, 100);
+        VibrationEffect.Prebaked effect = new VibrationEffect.Prebaked(VibrationEffect.EFFECT_CLICK,
+                VibrationEffect.EFFECT_STRENGTH_STRONG, fallback);
+        VibrationThread thread = startThreadAndDispatcher(vibrationId, effect);
+        waitForCompletion(thread);
+
+        verify(mIBatteryStatsMock).noteVibratorOn(eq(UID), eq(10L));
+        verify(mIBatteryStatsMock).noteVibratorOff(eq(UID));
+        verify(mControllerCallbacks).onComplete(eq(VIBRATOR_ID), eq(vibrationId));
+        verify(mThreadCallbacks).onVibrationEnded(eq(vibrationId), eq(Vibration.Status.FINISHED));
+        assertFalse(thread.getVibrators().get(VIBRATOR_ID).isVibrating());
+
+        assertEquals(Arrays.asList(expectedOneShot(10)),
+                mVibratorProviders.get(VIBRATOR_ID).getEffects());
+        assertEquals(Arrays.asList(100), mVibratorProviders.get(VIBRATOR_ID).getAmplitudes());
+    }
+
+    @Test
+    public void vibrate_singleVibratorPrebakedAndUnsupportedEffect_ignoresVibration()
+            throws Exception {
+        long vibrationId = 1;
+        VibrationEffect effect = VibrationEffect.get(VibrationEffect.EFFECT_CLICK);
+        VibrationThread thread = startThreadAndDispatcher(vibrationId, effect);
+        waitForCompletion(thread);
+
+        verify(mIBatteryStatsMock, never()).noteVibratorOn(eq(UID), anyLong());
+        verify(mIBatteryStatsMock, never()).noteVibratorOff(eq(UID));
+        verify(mControllerCallbacks, never()).onComplete(eq(VIBRATOR_ID), eq(vibrationId));
+        verify(mThreadCallbacks).onVibrationEnded(eq(vibrationId),
+                eq(Vibration.Status.IGNORED_UNSUPPORTED));
+        assertTrue(mVibratorProviders.get(VIBRATOR_ID).getEffects().isEmpty());
+    }
+
+    @Test
+    public void vibrate_singleVibratorComposed_runsVibration() throws Exception {
+        mVibratorProviders.get(VIBRATOR_ID).setCapabilities(IVibrator.CAP_COMPOSE_EFFECTS);
+
+        long vibrationId = 1;
+        VibrationEffect effect = VibrationEffect.startComposition()
+                .addPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK, 1f)
+                .addPrimitive(VibrationEffect.Composition.PRIMITIVE_TICK, 0.5f)
+                .compose();
+        VibrationThread thread = startThreadAndDispatcher(vibrationId, effect);
+        waitForCompletion(thread);
+
+        verify(mIBatteryStatsMock).noteVibratorOn(eq(UID), eq(40L));
+        verify(mIBatteryStatsMock).noteVibratorOff(eq(UID));
+        verify(mControllerCallbacks).onComplete(eq(VIBRATOR_ID), eq(vibrationId));
+        verify(mThreadCallbacks).onVibrationEnded(eq(vibrationId), eq(Vibration.Status.FINISHED));
+        assertFalse(thread.getVibrators().get(VIBRATOR_ID).isVibrating());
+        assertEquals(Arrays.asList(effect), mVibratorProviders.get(VIBRATOR_ID).getEffects());
+    }
+
+    @Test
+    public void vibrate_singleVibratorComposedAndNoCapability_ignoresVibration() throws Exception {
+        long vibrationId = 1;
+        VibrationEffect effect = VibrationEffect.startComposition()
+                .addPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK, 1f)
+                .compose();
+        VibrationThread thread = startThreadAndDispatcher(vibrationId, effect);
+        waitForCompletion(thread);
+
+        verify(mIBatteryStatsMock, never()).noteVibratorOn(eq(UID), anyLong());
+        verify(mIBatteryStatsMock, never()).noteVibratorOff(eq(UID));
+        verify(mControllerCallbacks, never()).onComplete(eq(VIBRATOR_ID), eq(vibrationId));
+        verify(mThreadCallbacks).onVibrationEnded(eq(vibrationId),
+                eq(Vibration.Status.IGNORED_UNSUPPORTED));
+        assertTrue(mVibratorProviders.get(VIBRATOR_ID).getEffects().isEmpty());
+    }
+
+    @Test
+    public void vibrate_singleVibratorCancelled_vibratorStopped() throws Exception {
+        long vibrationId = 1;
+        VibrationEffect effect = VibrationEffect.createWaveform(new long[]{5}, new int[]{100}, 0);
+        VibrationThread thread = startThreadAndDispatcher(vibrationId, effect);
+
+        Thread.sleep(15);
+        // Vibration still running after 2 cycles.
+        assertTrue(thread.isAlive());
+        assertTrue(thread.getVibrators().get(1).isVibrating());
+
+        thread.binderDied();
+        waitForCompletion(thread);
+        assertFalse(thread.getVibrators().get(1).isVibrating());
+
+        verify(mThreadCallbacks).onVibrationEnded(eq(vibrationId), eq(Vibration.Status.CANCELLED));
+    }
+
+    @Test
+    public void vibrate_multipleExistingAndMissingVibrators_vibratesOnlyExistingOnes()
+            throws Exception {
+        mVibratorProviders.get(1).setSupportedEffects(VibrationEffect.EFFECT_TICK);
+
+        long vibrationId = 1;
+        CombinedVibrationEffect effect = CombinedVibrationEffect.startSynced()
+                .addVibrator(VIBRATOR_ID, VibrationEffect.get(VibrationEffect.EFFECT_TICK))
+                .addVibrator(2, VibrationEffect.get(VibrationEffect.EFFECT_TICK))
+                .combine();
+        VibrationThread thread = startThreadAndDispatcher(vibrationId, effect);
+        waitForCompletion(thread);
+
+        verify(mIBatteryStatsMock).noteVibratorOn(eq(UID), eq(20L));
+        verify(mIBatteryStatsMock).noteVibratorOff(eq(UID));
+        verify(mControllerCallbacks).onComplete(eq(VIBRATOR_ID), eq(vibrationId));
+        verify(mControllerCallbacks, never()).onComplete(eq(2), eq(vibrationId));
+        verify(mThreadCallbacks).onVibrationEnded(eq(vibrationId), eq(Vibration.Status.FINISHED));
+        assertFalse(thread.getVibrators().get(VIBRATOR_ID).isVibrating());
+
+        assertEquals(Arrays.asList(expectedPrebaked(VibrationEffect.EFFECT_TICK)),
+                mVibratorProviders.get(VIBRATOR_ID).getEffects());
+    }
+
+    @Test
+    public void vibrate_multipleMono_runsSameEffectInAllVibrators() throws Exception {
+        mockVibrators(1, 2, 3);
+        mVibratorProviders.get(1).setSupportedEffects(VibrationEffect.EFFECT_CLICK);
+        mVibratorProviders.get(2).setSupportedEffects(VibrationEffect.EFFECT_CLICK);
+        mVibratorProviders.get(3).setSupportedEffects(VibrationEffect.EFFECT_CLICK);
+
+        long vibrationId = 1;
+        CombinedVibrationEffect effect = CombinedVibrationEffect.createSynced(
+                VibrationEffect.get(VibrationEffect.EFFECT_CLICK));
+        VibrationThread thread = startThreadAndDispatcher(vibrationId, effect);
+        waitForCompletion(thread);
+
+        verify(mIBatteryStatsMock).noteVibratorOn(eq(UID), eq(20L));
+        verify(mIBatteryStatsMock).noteVibratorOff(eq(UID));
+        verify(mControllerCallbacks).onComplete(eq(1), eq(vibrationId));
+        verify(mControllerCallbacks).onComplete(eq(2), eq(vibrationId));
+        verify(mControllerCallbacks).onComplete(eq(3), eq(vibrationId));
+        verify(mThreadCallbacks).onVibrationEnded(eq(vibrationId), eq(Vibration.Status.FINISHED));
+        assertFalse(thread.getVibrators().get(1).isVibrating());
+        assertFalse(thread.getVibrators().get(2).isVibrating());
+        assertFalse(thread.getVibrators().get(3).isVibrating());
+
+        VibrationEffect expected = expectedPrebaked(VibrationEffect.EFFECT_CLICK);
+        assertEquals(Arrays.asList(expected), mVibratorProviders.get(1).getEffects());
+        assertEquals(Arrays.asList(expected), mVibratorProviders.get(2).getEffects());
+        assertEquals(Arrays.asList(expected), mVibratorProviders.get(3).getEffects());
+    }
+
+    @Test
+    public void vibrate_multipleStereo_runsVibrationOnRightVibrators() throws Exception {
+        mockVibrators(1, 2, 3, 4);
+        mVibratorProviders.get(1).setSupportedEffects(VibrationEffect.EFFECT_CLICK);
+        mVibratorProviders.get(2).setCapabilities(IVibrator.CAP_AMPLITUDE_CONTROL);
+        mVibratorProviders.get(3).setCapabilities(IVibrator.CAP_AMPLITUDE_CONTROL);
+        mVibratorProviders.get(4).setCapabilities(IVibrator.CAP_COMPOSE_EFFECTS);
+
+        long vibrationId = 1;
+        VibrationEffect composed = VibrationEffect.startComposition()
+                .addPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK)
+                .compose();
+        CombinedVibrationEffect effect = CombinedVibrationEffect.startSynced()
+                .addVibrator(1, VibrationEffect.get(VibrationEffect.EFFECT_CLICK))
+                .addVibrator(2, VibrationEffect.createOneShot(10, 100))
+                .addVibrator(3, VibrationEffect.createWaveform(
+                        new long[]{10, 10}, new int[]{1, 2}, -1))
+                .addVibrator(4, composed)
+                .combine();
+        VibrationThread thread = startThreadAndDispatcher(vibrationId, effect);
+        waitForCompletion(thread);
+
+        verify(mIBatteryStatsMock).noteVibratorOn(eq(UID), eq(20L));
+        verify(mIBatteryStatsMock).noteVibratorOff(eq(UID));
+        verify(mControllerCallbacks).onComplete(eq(1), eq(vibrationId));
+        verify(mControllerCallbacks).onComplete(eq(2), eq(vibrationId));
+        verify(mControllerCallbacks).onComplete(eq(3), eq(vibrationId));
+        verify(mControllerCallbacks).onComplete(eq(4), eq(vibrationId));
+        verify(mThreadCallbacks).onVibrationEnded(eq(vibrationId), eq(Vibration.Status.FINISHED));
+        assertFalse(thread.getVibrators().get(1).isVibrating());
+        assertFalse(thread.getVibrators().get(2).isVibrating());
+        assertFalse(thread.getVibrators().get(3).isVibrating());
+        assertFalse(thread.getVibrators().get(4).isVibrating());
+
+        assertEquals(Arrays.asList(expectedPrebaked(VibrationEffect.EFFECT_CLICK)),
+                mVibratorProviders.get(1).getEffects());
+        assertEquals(Arrays.asList(expectedOneShot(10)), mVibratorProviders.get(2).getEffects());
+        assertEquals(Arrays.asList(100), mVibratorProviders.get(2).getAmplitudes());
+        assertEquals(Arrays.asList(expectedOneShot(20)), mVibratorProviders.get(3).getEffects());
+        assertEquals(Arrays.asList(1, 2), mVibratorProviders.get(3).getAmplitudes());
+        assertEquals(Arrays.asList(composed), mVibratorProviders.get(4).getEffects());
+    }
+
+    @Test
+    public void vibrate_multipleSequential_runsVibrationInOrderWithDelays()
+            throws Exception {
+        mockVibrators(1, 2, 3);
+        mVibratorProviders.get(1).setCapabilities(IVibrator.CAP_AMPLITUDE_CONTROL);
+        mVibratorProviders.get(2).setCapabilities(IVibrator.CAP_COMPOSE_EFFECTS);
+        mVibratorProviders.get(3).setSupportedEffects(VibrationEffect.EFFECT_CLICK);
+
+        long vibrationId = 1;
+        VibrationEffect composed = VibrationEffect.startComposition()
+                .addPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK)
+                .compose();
+        CombinedVibrationEffect effect = CombinedVibrationEffect.startSequential()
+                .addNext(3, VibrationEffect.get(VibrationEffect.EFFECT_CLICK), /* delay= */ 50)
+                .addNext(1, VibrationEffect.createOneShot(10, 100), /* delay= */ 50)
+                .addNext(2, composed, /* delay= */ 50)
+                .combine();
+        VibrationThread thread = startThreadAndDispatcher(vibrationId, effect);
+
+        waitForCompletion(thread);
+        InOrder controllerVerifier = inOrder(mControllerCallbacks);
+        controllerVerifier.verify(mControllerCallbacks).onComplete(eq(3), eq(vibrationId));
+        controllerVerifier.verify(mControllerCallbacks).onComplete(eq(1), eq(vibrationId));
+        controllerVerifier.verify(mControllerCallbacks).onComplete(eq(2), eq(vibrationId));
+
+        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));
+
+        verify(mThreadCallbacks).onVibrationEnded(eq(vibrationId), eq(Vibration.Status.FINISHED));
+        assertFalse(thread.getVibrators().get(1).isVibrating());
+        assertFalse(thread.getVibrators().get(2).isVibrating());
+        assertFalse(thread.getVibrators().get(3).isVibrating());
+
+        assertEquals(Arrays.asList(expectedOneShot(10)), mVibratorProviders.get(1).getEffects());
+        assertEquals(Arrays.asList(100), mVibratorProviders.get(1).getAmplitudes());
+        assertEquals(Arrays.asList(composed), mVibratorProviders.get(2).getEffects());
+        assertEquals(Arrays.asList(expectedPrebaked(VibrationEffect.EFFECT_CLICK)),
+                mVibratorProviders.get(3).getEffects());
+    }
+
+    @Test
+    public void vibrate_multipleWaveforms_playsWaveformsInParallel() throws Exception {
+        mockVibrators(1, 2, 3);
+        mVibratorProviders.get(1).setCapabilities(IVibrator.CAP_AMPLITUDE_CONTROL);
+        mVibratorProviders.get(2).setCapabilities(IVibrator.CAP_AMPLITUDE_CONTROL);
+        mVibratorProviders.get(3).setCapabilities(IVibrator.CAP_AMPLITUDE_CONTROL);
+
+        long vibrationId = 1;
+        CombinedVibrationEffect effect = CombinedVibrationEffect.startSynced()
+                .addVibrator(1, VibrationEffect.createWaveform(
+                        new long[]{5, 10, 10}, new int[]{1, 2, 3}, -1))
+                .addVibrator(2, VibrationEffect.createWaveform(
+                        new long[]{20, 60}, new int[]{4, 5}, -1))
+                .addVibrator(3, VibrationEffect.createWaveform(
+                        new long[]{60}, new int[]{6}, -1))
+                .combine();
+        VibrationThread thread = startThreadAndDispatcher(vibrationId, effect);
+
+        Thread.sleep(40);
+        // First waveform has finished.
+        verify(mControllerCallbacks).onComplete(eq(1), eq(vibrationId));
+        assertEquals(Arrays.asList(1, 2, 3), mVibratorProviders.get(1).getAmplitudes());
+        // Second waveform is halfway through.
+        assertEquals(Arrays.asList(4, 5), mVibratorProviders.get(2).getAmplitudes());
+        // Third waveform is almost ending.
+        assertEquals(Arrays.asList(6), mVibratorProviders.get(3).getAmplitudes());
+
+        waitForCompletion(thread);
+
+        verify(mIBatteryStatsMock).noteVibratorOn(eq(UID), eq(80L));
+        verify(mIBatteryStatsMock).noteVibratorOff(eq(UID));
+        verify(mControllerCallbacks).onComplete(eq(2), eq(vibrationId));
+        verify(mControllerCallbacks).onComplete(eq(3), eq(vibrationId));
+        verify(mThreadCallbacks).onVibrationEnded(eq(vibrationId), eq(Vibration.Status.FINISHED));
+        assertFalse(thread.getVibrators().get(1).isVibrating());
+        assertFalse(thread.getVibrators().get(2).isVibrating());
+        assertFalse(thread.getVibrators().get(3).isVibrating());
+
+        assertEquals(Arrays.asList(expectedOneShot(25)), mVibratorProviders.get(1).getEffects());
+        assertEquals(Arrays.asList(expectedOneShot(80)), mVibratorProviders.get(2).getEffects());
+        assertEquals(Arrays.asList(expectedOneShot(60)), mVibratorProviders.get(3).getEffects());
+        assertEquals(Arrays.asList(1, 2, 3), mVibratorProviders.get(1).getAmplitudes());
+        assertEquals(Arrays.asList(4, 5), mVibratorProviders.get(2).getAmplitudes());
+        assertEquals(Arrays.asList(6), mVibratorProviders.get(3).getAmplitudes());
+    }
+
+    @Test
+    public void vibrate_withWaveform_totalVibrationTimeRespected() {
+        int totalDuration = 10_000; // 10s
+        int stepDuration = 25; // 25ms
+
+        // 25% of the first waveform step will be spent on the native on() call.
+        // 25% of each waveform step will be spent on the native setAmplitude() call..
+        mVibratorProviders.get(VIBRATOR_ID).setLatency(stepDuration / 4);
+        mVibratorProviders.get(VIBRATOR_ID).setCapabilities(IVibrator.CAP_AMPLITUDE_CONTROL);
+
+        int stepCount = totalDuration / stepDuration;
+        long[] timings = new long[stepCount];
+        int[] amplitudes = new int[stepCount];
+        Arrays.fill(timings, stepDuration);
+        Arrays.fill(amplitudes, VibrationEffect.DEFAULT_AMPLITUDE);
+        VibrationEffect effect = VibrationEffect.createWaveform(timings, amplitudes, -1);
+
+        long vibrationId = 1;
+        VibrationThread thread = startThreadAndDispatcher(vibrationId, effect);
+        long startTime = SystemClock.elapsedRealtime();
+
+        waitForCompletion(thread, totalDuration + TEST_TIMEOUT_MILLIS);
+        long delay = Math.abs(SystemClock.elapsedRealtime() - startTime - totalDuration);
+
+        // Allow some delay for thread scheduling and callback triggering.
+        int maxDelay = (int) (0.05 * totalDuration); // < 5% of total duration
+        assertTrue("Waveform with perceived delay of " + delay + "ms,"
+                        + " expected less than " + maxDelay + "ms",
+                delay < maxDelay);
+    }
+
+    @Test
+    public void vibrate_multipleCancelled_allVibratorsStopped() throws Exception {
+        mockVibrators(1, 2, 3);
+        mVibratorProviders.get(1).setCapabilities(IVibrator.CAP_AMPLITUDE_CONTROL);
+        mVibratorProviders.get(2).setCapabilities(IVibrator.CAP_AMPLITUDE_CONTROL);
+        mVibratorProviders.get(3).setCapabilities(IVibrator.CAP_AMPLITUDE_CONTROL);
+
+        long vibrationId = 1;
+        CombinedVibrationEffect effect = CombinedVibrationEffect.startSynced()
+                .addVibrator(1, VibrationEffect.createWaveform(
+                        new long[]{5, 10}, new int[]{1, 2}, 0))
+                .addVibrator(2, VibrationEffect.createWaveform(
+                        new long[]{20, 30}, new int[]{3, 4}, 0))
+                .addVibrator(3, VibrationEffect.createWaveform(
+                        new long[]{10, 40}, new int[]{5, 6}, 0))
+                .combine();
+        VibrationThread thread = startThreadAndDispatcher(vibrationId, effect);
+
+        Thread.sleep(15);
+        assertTrue(thread.isAlive());
+        assertTrue(thread.getVibrators().get(1).isVibrating());
+        assertTrue(thread.getVibrators().get(2).isVibrating());
+        assertTrue(thread.getVibrators().get(3).isVibrating());
+
+        thread.cancel();
+        waitForCompletion(thread);
+        assertFalse(thread.getVibrators().get(1).isVibrating());
+        assertFalse(thread.getVibrators().get(2).isVibrating());
+        assertFalse(thread.getVibrators().get(3).isVibrating());
+
+        verify(mThreadCallbacks).onVibrationEnded(eq(vibrationId), eq(Vibration.Status.CANCELLED));
+    }
+
+    @Test
+    public void vibrate_binderDied_cancelsVibration() throws Exception {
+        long vibrationId = 1;
+        VibrationEffect effect = VibrationEffect.createWaveform(new long[]{5}, new int[]{100}, 0);
+        VibrationThread thread = startThreadAndDispatcher(vibrationId, effect);
+
+        Thread.sleep(15);
+        // Vibration still running after 2 cycles.
+        assertTrue(thread.isAlive());
+        assertTrue(thread.getVibrators().get(1).isVibrating());
+
+        thread.binderDied();
+        waitForCompletion(thread);
+
+        verify(mVibrationToken).linkToDeath(same(thread), eq(0));
+        verify(mVibrationToken).unlinkToDeath(same(thread), eq(0));
+        verify(mThreadCallbacks).onVibrationEnded(eq(vibrationId), eq(Vibration.Status.CANCELLED));
+        assertFalse(mVibratorProviders.get(VIBRATOR_ID).getEffects().isEmpty());
+        assertFalse(thread.getVibrators().get(1).isVibrating());
+    }
+
+    private void mockVibrators(int... vibratorIds) {
+        for (int vibratorId : vibratorIds) {
+            mVibratorProviders.put(vibratorId,
+                    new FakeVibratorControllerProvider(mTestLooper.getLooper()));
+        }
+    }
+
+    private VibrationThread startThreadAndDispatcher(long vibrationId, VibrationEffect effect) {
+        return startThreadAndDispatcher(vibrationId, CombinedVibrationEffect.createSynced(effect));
+    }
+
+    private VibrationThread startThreadAndDispatcher(long vibrationId,
+            CombinedVibrationEffect effect) {
+        VibrationThread thread = new VibrationThread(createVibration(vibrationId, effect),
+                createVibratorControllers(), mWakeLock, mIBatteryStatsMock, mThreadCallbacks);
+        doAnswer(answer -> {
+            thread.vibratorComplete(answer.getArgument(0));
+            return null;
+        }).when(mControllerCallbacks).onComplete(anyInt(), eq(vibrationId));
+        mTestLooper.startAutoDispatch();
+        thread.start();
+        return thread;
+    }
+
+    private void waitForCompletion(VibrationThread thread) {
+        waitForCompletion(thread, TEST_TIMEOUT_MILLIS);
+    }
+
+    private void waitForCompletion(VibrationThread thread, long timeout) {
+        try {
+            thread.join(timeout);
+        } catch (InterruptedException e) {
+        }
+        assertFalse(thread.isAlive());
+        mTestLooper.dispatchAll();
+    }
+
+    private Vibration createVibration(long id, CombinedVibrationEffect effect) {
+        return new Vibration(mVibrationToken, (int) id, effect, ATTRS, UID, PACKAGE_NAME, "reason");
+    }
+
+    private SparseArray<VibratorController> createVibratorControllers() {
+        SparseArray<VibratorController> array = new SparseArray<>();
+        for (Map.Entry<Integer, FakeVibratorControllerProvider> e : mVibratorProviders.entrySet()) {
+            int id = e.getKey();
+            array.put(id, e.getValue().newVibratorController(id, mControllerCallbacks));
+        }
+        return array;
+    }
+
+    private VibrationEffect expectedOneShot(long millis) {
+        return VibrationEffect.createOneShot(millis, VibrationEffect.DEFAULT_AMPLITUDE);
+    }
+
+    private VibrationEffect expectedPrebaked(int effectId) {
+        return new VibrationEffect.Prebaked(effectId, false,
+                VibrationEffect.EFFECT_STRENGTH_MEDIUM);
+    }
+}
