diff --git a/core/java/android/os/SystemVibrator.java b/core/java/android/os/SystemVibrator.java
index bf72b1d..2cda787 100644
--- a/core/java/android/os/SystemVibrator.java
+++ b/core/java/android/os/SystemVibrator.java
@@ -18,26 +18,19 @@
 
 import android.annotation.CallbackExecutor;
 import android.annotation.NonNull;
-import android.annotation.Nullable;
 import android.compat.annotation.UnsupportedAppUsage;
 import android.content.Context;
-import android.hardware.vibrator.IVibrator;
+import android.os.vibrator.VibratorInfoFactory;
 import android.util.ArrayMap;
 import android.util.Log;
-import android.util.Range;
-import android.util.Slog;
 import android.util.SparseArray;
-import android.util.SparseBooleanArray;
-import android.util.SparseIntArray;
 
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
 
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.Objects;
 import java.util.concurrent.Executor;
-import java.util.function.Function;
 
 /**
  * Vibrator implementation that controls the main system vibrator.
@@ -82,7 +75,7 @@
             if (vibratorIds.length == 0) {
                 // It is known that the device has no vibrator, so cache and return info that
                 // reflects the lack of support for effects/primitives.
-                return mVibratorInfo = new NoVibratorInfo();
+                return mVibratorInfo = VibratorInfo.EMPTY_VIBRATOR_INFO;
             }
             VibratorInfo[] vibratorInfos = new VibratorInfo[vibratorIds.length];
             for (int i = 0; i < vibratorIds.length; i++) {
@@ -96,12 +89,7 @@
                 }
                 vibratorInfos[i] = vibrator.getInfo();
             }
-            if (vibratorInfos.length == 1) {
-                // Device has a single vibrator info, cache and return successfully loaded info.
-                return mVibratorInfo = new VibratorInfo(/* id= */ -1, vibratorInfos[0]);
-            }
-            // Device has multiple vibrators, generate a single info representing all of them.
-            return mVibratorInfo = new MultiVibratorInfo(vibratorInfos);
+            return mVibratorInfo = VibratorInfoFactory.create(/* id= */ -1, vibratorInfos);
         }
     }
 
@@ -275,296 +263,6 @@
     }
 
     /**
-     * Represents a device with no vibrator as a single {@link VibratorInfo}.
-     *
-     * @hide
-     */
-    @VisibleForTesting
-    public static class NoVibratorInfo extends VibratorInfo {
-        public NoVibratorInfo() {
-            // Use empty arrays to indicate no support, while null would indicate support unknown.
-            super(/* id= */ -1,
-                    /* capabilities= */ 0,
-                    /* supportedEffects= */ new SparseBooleanArray(),
-                    /* supportedBraking= */ new SparseBooleanArray(),
-                    /* supportedPrimitives= */ new SparseIntArray(),
-                    /* primitiveDelayMax= */ 0,
-                    /* compositionSizeMax= */ 0,
-                    /* pwlePrimitiveDurationMax= */ 0,
-                    /* pwleSizeMax= */ 0,
-                    /* qFactor= */ Float.NaN,
-                    new FrequencyProfile(/* resonantFrequencyHz= */ Float.NaN,
-                            /* minFrequencyHz= */ Float.NaN,
-                            /* frequencyResolutionHz= */ Float.NaN,
-                            /* maxAmplitudes= */ null));
-        }
-    }
-
-    /**
-     * Represents multiple vibrator information as a single {@link VibratorInfo}.
-     *
-     * <p>This uses an intersection of all vibrators to decide the capabilities and effect/primitive
-     * support.
-     *
-     * @hide
-     */
-    @VisibleForTesting
-    public static class MultiVibratorInfo extends VibratorInfo {
-        // Epsilon used for float comparison applied in calculations for the merged info.
-        private static final float EPSILON = 1e-5f;
-
-        public MultiVibratorInfo(VibratorInfo[] vibrators) {
-            // Need to use an extra constructor to share the computation in super initialization.
-            this(vibrators, frequencyProfileIntersection(vibrators));
-        }
-
-        private MultiVibratorInfo(VibratorInfo[] vibrators,
-                VibratorInfo.FrequencyProfile mergedProfile) {
-            super(/* id= */ -1,
-                    capabilitiesIntersection(vibrators, mergedProfile.isEmpty()),
-                    supportedEffectsIntersection(vibrators),
-                    supportedBrakingIntersection(vibrators),
-                    supportedPrimitivesAndDurationsIntersection(vibrators),
-                    integerLimitIntersection(vibrators, VibratorInfo::getPrimitiveDelayMax),
-                    integerLimitIntersection(vibrators, VibratorInfo::getCompositionSizeMax),
-                    integerLimitIntersection(vibrators, VibratorInfo::getPwlePrimitiveDurationMax),
-                    integerLimitIntersection(vibrators, VibratorInfo::getPwleSizeMax),
-                    floatPropertyIntersection(vibrators, VibratorInfo::getQFactor),
-                    mergedProfile);
-        }
-
-        private static int capabilitiesIntersection(VibratorInfo[] infos,
-                boolean frequencyProfileIsEmpty) {
-            int intersection = ~0;
-            for (VibratorInfo info : infos) {
-                intersection &= info.getCapabilities();
-            }
-            if (frequencyProfileIsEmpty) {
-                // Revoke frequency control if the merged frequency profile ended up empty.
-                intersection &= ~IVibrator.CAP_FREQUENCY_CONTROL;
-            }
-            return intersection;
-        }
-
-        @Nullable
-        private static SparseBooleanArray supportedBrakingIntersection(VibratorInfo[] infos) {
-            for (VibratorInfo info : infos) {
-                if (!info.isBrakingSupportKnown()) {
-                    // If one vibrator support is unknown, then the intersection is also unknown.
-                    return null;
-                }
-            }
-
-            SparseBooleanArray intersection = new SparseBooleanArray();
-            SparseBooleanArray firstVibratorBraking = infos[0].getSupportedBraking();
-
-            brakingIdLoop:
-            for (int i = 0; i < firstVibratorBraking.size(); i++) {
-                int brakingId = firstVibratorBraking.keyAt(i);
-                if (!firstVibratorBraking.valueAt(i)) {
-                    // The first vibrator already doesn't support this braking, so skip it.
-                    continue brakingIdLoop;
-                }
-
-                for (int j = 1; j < infos.length; j++) {
-                    if (!infos[j].hasBrakingSupport(brakingId)) {
-                        // One vibrator doesn't support this braking, so the intersection doesn't.
-                        continue brakingIdLoop;
-                    }
-                }
-
-                intersection.put(brakingId, true);
-            }
-
-            return intersection;
-        }
-
-        @Nullable
-        private static SparseBooleanArray supportedEffectsIntersection(VibratorInfo[] infos) {
-            for (VibratorInfo info : infos) {
-                if (!info.isEffectSupportKnown()) {
-                    // If one vibrator support is unknown, then the intersection is also unknown.
-                    return null;
-                }
-            }
-
-            SparseBooleanArray intersection = new SparseBooleanArray();
-            SparseBooleanArray firstVibratorEffects = infos[0].getSupportedEffects();
-
-            effectIdLoop:
-            for (int i = 0; i < firstVibratorEffects.size(); i++) {
-                int effectId = firstVibratorEffects.keyAt(i);
-                if (!firstVibratorEffects.valueAt(i)) {
-                    // The first vibrator already doesn't support this effect, so skip it.
-                    continue effectIdLoop;
-                }
-
-                for (int j = 1; j < infos.length; j++) {
-                    if (infos[j].isEffectSupported(effectId) != VIBRATION_EFFECT_SUPPORT_YES) {
-                        // One vibrator doesn't support this effect, so the intersection doesn't.
-                        continue effectIdLoop;
-                    }
-                }
-
-                intersection.put(effectId, true);
-            }
-
-            return intersection;
-        }
-
-        @NonNull
-        private static SparseIntArray supportedPrimitivesAndDurationsIntersection(
-                VibratorInfo[] infos) {
-            SparseIntArray intersection = new SparseIntArray();
-            SparseIntArray firstVibratorPrimitives = infos[0].getSupportedPrimitives();
-
-            primitiveIdLoop:
-            for (int i = 0; i < firstVibratorPrimitives.size(); i++) {
-                int primitiveId = firstVibratorPrimitives.keyAt(i);
-                int primitiveDuration = firstVibratorPrimitives.valueAt(i);
-                if (primitiveDuration == 0) {
-                    // The first vibrator already doesn't support this primitive, so skip it.
-                    continue primitiveIdLoop;
-                }
-
-                for (int j = 1; j < infos.length; j++) {
-                    int vibratorPrimitiveDuration = infos[j].getPrimitiveDuration(primitiveId);
-                    if (vibratorPrimitiveDuration == 0) {
-                        // One vibrator doesn't support this primitive, so the intersection doesn't.
-                        continue primitiveIdLoop;
-                    } else {
-                        // The primitive vibration duration is the maximum among all vibrators.
-                        primitiveDuration = Math.max(primitiveDuration, vibratorPrimitiveDuration);
-                    }
-                }
-
-                intersection.put(primitiveId, primitiveDuration);
-            }
-            return intersection;
-        }
-
-        private static int integerLimitIntersection(VibratorInfo[] infos,
-                Function<VibratorInfo, Integer> propertyGetter) {
-            int limit = 0; // Limit 0 means unlimited
-            for (VibratorInfo info : infos) {
-                int vibratorLimit = propertyGetter.apply(info);
-                if ((limit == 0) || (vibratorLimit > 0 && vibratorLimit < limit)) {
-                    // This vibrator is limited and intersection is unlimited or has a larger limit:
-                    // use smaller limit here for the intersection.
-                    limit = vibratorLimit;
-                }
-            }
-            return limit;
-        }
-
-        private static float floatPropertyIntersection(VibratorInfo[] infos,
-                Function<VibratorInfo, Float> propertyGetter) {
-            float property = propertyGetter.apply(infos[0]);
-            if (Float.isNaN(property)) {
-                // If one vibrator is undefined then the intersection is undefined.
-                return Float.NaN;
-            }
-            for (int i = 1; i < infos.length; i++) {
-                if (Float.compare(property, propertyGetter.apply(infos[i])) != 0) {
-                    // If one vibrator has a different value then the intersection is undefined.
-                    return Float.NaN;
-                }
-            }
-            return property;
-        }
-
-        @NonNull
-        private static FrequencyProfile frequencyProfileIntersection(VibratorInfo[] infos) {
-            float freqResolution = floatPropertyIntersection(infos,
-                    info -> info.getFrequencyProfile().getFrequencyResolutionHz());
-            float resonantFreq = floatPropertyIntersection(infos,
-                    VibratorInfo::getResonantFrequencyHz);
-            Range<Float> freqRange = frequencyRangeIntersection(infos, freqResolution);
-
-            if ((freqRange == null) || Float.isNaN(freqResolution)) {
-                return new FrequencyProfile(resonantFreq, Float.NaN, freqResolution, null);
-            }
-
-            int amplitudeCount =
-                    Math.round(1 + (freqRange.getUpper() - freqRange.getLower()) / freqResolution);
-            float[] maxAmplitudes = new float[amplitudeCount];
-
-            // Use MAX_VALUE here to ensure that the FrequencyProfile constructor called with this
-            // will fail if the loop below is broken and do not replace filled values with actual
-            // vibrator measurements.
-            Arrays.fill(maxAmplitudes, Float.MAX_VALUE);
-
-            for (VibratorInfo info : infos) {
-                Range<Float> vibratorFreqRange = info.getFrequencyProfile().getFrequencyRangeHz();
-                float[] vibratorMaxAmplitudes = info.getFrequencyProfile().getMaxAmplitudes();
-                int vibratorStartIdx = Math.round(
-                        (freqRange.getLower() - vibratorFreqRange.getLower()) / freqResolution);
-                int vibratorEndIdx = vibratorStartIdx + maxAmplitudes.length - 1;
-
-                if ((vibratorStartIdx < 0) || (vibratorEndIdx >= vibratorMaxAmplitudes.length)) {
-                    Slog.w(TAG, "Error calculating the intersection of vibrator frequency"
-                            + " profiles: attempted to fetch from vibrator "
-                            + info.getId() + " max amplitude with bad index " + vibratorStartIdx);
-                    return new FrequencyProfile(resonantFreq, Float.NaN, Float.NaN, null);
-                }
-
-                for (int i = 0; i < maxAmplitudes.length; i++) {
-                    maxAmplitudes[i] = Math.min(maxAmplitudes[i],
-                            vibratorMaxAmplitudes[vibratorStartIdx + i]);
-                }
-            }
-
-            return new FrequencyProfile(resonantFreq, freqRange.getLower(),
-                    freqResolution, maxAmplitudes);
-        }
-
-        @Nullable
-        private static Range<Float> frequencyRangeIntersection(VibratorInfo[] infos,
-                float frequencyResolution) {
-            Range<Float> firstRange = infos[0].getFrequencyProfile().getFrequencyRangeHz();
-            if (firstRange == null) {
-                // If one vibrator is undefined then the intersection is undefined.
-                return null;
-            }
-            float intersectionLower = firstRange.getLower();
-            float intersectionUpper = firstRange.getUpper();
-
-            // Generate the intersection of all vibrator supported ranges, making sure that both
-            // min supported frequencies are aligned w.r.t. the frequency resolution.
-
-            for (int i = 1; i < infos.length; i++) {
-                Range<Float> vibratorRange = infos[i].getFrequencyProfile().getFrequencyRangeHz();
-                if (vibratorRange == null) {
-                    // If one vibrator is undefined then the intersection is undefined.
-                    return null;
-                }
-
-                if ((vibratorRange.getLower() >= intersectionUpper)
-                        || (vibratorRange.getUpper() <= intersectionLower)) {
-                    // If the range and intersection are disjoint then the intersection is undefined
-                    return null;
-                }
-
-                float frequencyDelta = Math.abs(intersectionLower - vibratorRange.getLower());
-                if ((frequencyDelta % frequencyResolution) > EPSILON) {
-                    // If the intersection is not aligned with one vibrator then it's undefined
-                    return null;
-                }
-
-                intersectionLower = Math.max(intersectionLower, vibratorRange.getLower());
-                intersectionUpper = Math.min(intersectionUpper, vibratorRange.getUpper());
-            }
-
-            if ((intersectionUpper - intersectionLower) < frequencyResolution) {
-                // If the intersection is empty then it's undefined.
-                return null;
-            }
-
-            return Range.create(intersectionLower, intersectionUpper);
-        }
-    }
-
-    /**
      * Listener for all vibrators state change.
      *
      * <p>This registers a listener to all vibrators to merge the callbacks into a single state
diff --git a/core/java/android/os/VibratorInfo.java b/core/java/android/os/VibratorInfo.java
index 0b7d7c3..4f8c24d 100644
--- a/core/java/android/os/VibratorInfo.java
+++ b/core/java/android/os/VibratorInfo.java
@@ -156,6 +156,16 @@
             return false;
         }
         VibratorInfo that = (VibratorInfo) o;
+        return mId == that.mId && equalContent(that);
+    }
+
+    /**
+     * Returns {@code true} only if the properties and capabilities of the provided info, except for
+     * the ID, equals to this info. Returns {@code false} otherwise.
+     *
+     * @hide
+     */
+    public boolean equalContent(VibratorInfo that) {
         int supportedPrimitivesCount = mSupportedPrimitives.size();
         if (supportedPrimitivesCount != that.mSupportedPrimitives.size()) {
             return false;
@@ -168,7 +178,7 @@
                 return false;
             }
         }
-        return mId == that.mId && mCapabilities == that.mCapabilities
+        return mCapabilities == that.mCapabilities
                 && mPrimitiveDelayMax == that.mPrimitiveDelayMax
                 && mCompositionSizeMax == that.mCompositionSizeMax
                 && mPwlePrimitiveDurationMax == that.mPwlePrimitiveDurationMax
@@ -445,7 +455,8 @@
         return mFrequencyProfile;
     }
 
-    protected long getCapabilities() {
+    /** Returns a single int representing all the capabilities of the vibrator. */
+    public long getCapabilities() {
         return mCapabilities;
     }
 
diff --git a/core/java/android/os/vibrator/MultiVibratorInfo.java b/core/java/android/os/vibrator/MultiVibratorInfo.java
new file mode 100644
index 0000000..5f32731
--- /dev/null
+++ b/core/java/android/os/vibrator/MultiVibratorInfo.java
@@ -0,0 +1,294 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.os.vibrator;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.hardware.vibrator.IVibrator;
+import android.os.Vibrator;
+import android.os.VibratorInfo;
+import android.util.Range;
+import android.util.Slog;
+import android.util.SparseBooleanArray;
+import android.util.SparseIntArray;
+
+import java.util.Arrays;
+import java.util.function.Function;
+
+/**
+ * Represents multiple vibrator information as a single {@link VibratorInfo}.
+ *
+ * <p>This uses an intersection of all vibrators to decide the capabilities and effect/primitive
+ * support.
+ *
+ * @hide
+ */
+public final class MultiVibratorInfo extends VibratorInfo {
+    private static final String TAG = "MultiVibratorInfo";
+
+    // Epsilon used for float comparison applied in calculations for the merged info.
+    private static final float EPSILON = 1e-5f;
+
+    public MultiVibratorInfo(int id, VibratorInfo[] vibrators) {
+        this(id, vibrators, frequencyProfileIntersection(vibrators));
+    }
+
+    private MultiVibratorInfo(
+            int id, VibratorInfo[] vibrators, VibratorInfo.FrequencyProfile mergedProfile) {
+        super(id,
+                capabilitiesIntersection(vibrators, mergedProfile.isEmpty()),
+                supportedEffectsIntersection(vibrators),
+                supportedBrakingIntersection(vibrators),
+                supportedPrimitivesAndDurationsIntersection(vibrators),
+                integerLimitIntersection(vibrators, VibratorInfo::getPrimitiveDelayMax),
+                integerLimitIntersection(vibrators, VibratorInfo::getCompositionSizeMax),
+                integerLimitIntersection(vibrators, VibratorInfo::getPwlePrimitiveDurationMax),
+                integerLimitIntersection(vibrators, VibratorInfo::getPwleSizeMax),
+                floatPropertyIntersection(vibrators, VibratorInfo::getQFactor),
+                mergedProfile);
+    }
+
+    private static int capabilitiesIntersection(VibratorInfo[] infos,
+            boolean frequencyProfileIsEmpty) {
+        int intersection = ~0;
+        for (VibratorInfo info : infos) {
+            intersection &= info.getCapabilities();
+        }
+        if (frequencyProfileIsEmpty) {
+            // Revoke frequency control if the merged frequency profile ended up empty.
+            intersection &= ~IVibrator.CAP_FREQUENCY_CONTROL;
+        }
+        return intersection;
+    }
+
+    @Nullable
+    private static SparseBooleanArray supportedBrakingIntersection(VibratorInfo[] infos) {
+        for (VibratorInfo info : infos) {
+            if (!info.isBrakingSupportKnown()) {
+                // If one vibrator support is unknown, then the intersection is also unknown.
+                return null;
+            }
+        }
+
+        SparseBooleanArray intersection = new SparseBooleanArray();
+        SparseBooleanArray firstVibratorBraking = infos[0].getSupportedBraking();
+
+        brakingIdLoop:
+        for (int i = 0; i < firstVibratorBraking.size(); i++) {
+            int brakingId = firstVibratorBraking.keyAt(i);
+            if (!firstVibratorBraking.valueAt(i)) {
+                // The first vibrator already doesn't support this braking, so skip it.
+                continue brakingIdLoop;
+            }
+
+            for (int j = 1; j < infos.length; j++) {
+                if (!infos[j].hasBrakingSupport(brakingId)) {
+                    // One vibrator doesn't support this braking, so the intersection doesn't.
+                    continue brakingIdLoop;
+                }
+            }
+
+            intersection.put(brakingId, true);
+        }
+
+        return intersection;
+    }
+
+    @Nullable
+    private static SparseBooleanArray supportedEffectsIntersection(VibratorInfo[] infos) {
+        for (VibratorInfo info : infos) {
+            if (!info.isEffectSupportKnown()) {
+                // If one vibrator support is unknown, then the intersection is also unknown.
+                return null;
+            }
+        }
+
+        SparseBooleanArray intersection = new SparseBooleanArray();
+        SparseBooleanArray firstVibratorEffects = infos[0].getSupportedEffects();
+
+        effectIdLoop:
+        for (int i = 0; i < firstVibratorEffects.size(); i++) {
+            int effectId = firstVibratorEffects.keyAt(i);
+            if (!firstVibratorEffects.valueAt(i)) {
+                // The first vibrator already doesn't support this effect, so skip it.
+                continue effectIdLoop;
+            }
+
+            for (int j = 1; j < infos.length; j++) {
+                if (infos[j].isEffectSupported(effectId) != Vibrator.VIBRATION_EFFECT_SUPPORT_YES) {
+                    // One vibrator doesn't support this effect, so the intersection doesn't.
+                    continue effectIdLoop;
+                }
+            }
+
+            intersection.put(effectId, true);
+        }
+
+        return intersection;
+    }
+
+    @NonNull
+    private static SparseIntArray supportedPrimitivesAndDurationsIntersection(
+            VibratorInfo[] infos) {
+        SparseIntArray intersection = new SparseIntArray();
+        SparseIntArray firstVibratorPrimitives = infos[0].getSupportedPrimitives();
+
+        primitiveIdLoop:
+        for (int i = 0; i < firstVibratorPrimitives.size(); i++) {
+            int primitiveId = firstVibratorPrimitives.keyAt(i);
+            int primitiveDuration = firstVibratorPrimitives.valueAt(i);
+            if (primitiveDuration == 0) {
+                // The first vibrator already doesn't support this primitive, so skip it.
+                continue primitiveIdLoop;
+            }
+
+            for (int j = 1; j < infos.length; j++) {
+                int vibratorPrimitiveDuration = infos[j].getPrimitiveDuration(primitiveId);
+                if (vibratorPrimitiveDuration == 0) {
+                    // One vibrator doesn't support this primitive, so the intersection doesn't.
+                    continue primitiveIdLoop;
+                } else {
+                    // The primitive vibration duration is the maximum among all vibrators.
+                    primitiveDuration = Math.max(primitiveDuration, vibratorPrimitiveDuration);
+                }
+            }
+
+            intersection.put(primitiveId, primitiveDuration);
+        }
+        return intersection;
+    }
+
+    private static int integerLimitIntersection(VibratorInfo[] infos,
+            Function<VibratorInfo, Integer> propertyGetter) {
+        int limit = 0; // Limit 0 means unlimited
+        for (VibratorInfo info : infos) {
+            int vibratorLimit = propertyGetter.apply(info);
+            if ((limit == 0) || (vibratorLimit > 0 && vibratorLimit < limit)) {
+                // This vibrator is limited and intersection is unlimited or has a larger limit:
+                // use smaller limit here for the intersection.
+                limit = vibratorLimit;
+            }
+        }
+        return limit;
+    }
+
+    private static float floatPropertyIntersection(VibratorInfo[] infos,
+            Function<VibratorInfo, Float> propertyGetter) {
+        float property = propertyGetter.apply(infos[0]);
+        if (Float.isNaN(property)) {
+            // If one vibrator is undefined then the intersection is undefined.
+            return Float.NaN;
+        }
+        for (int i = 1; i < infos.length; i++) {
+            if (Float.compare(property, propertyGetter.apply(infos[i])) != 0) {
+                // If one vibrator has a different value then the intersection is undefined.
+                return Float.NaN;
+            }
+        }
+        return property;
+    }
+
+    @NonNull
+    private static FrequencyProfile frequencyProfileIntersection(VibratorInfo[] infos) {
+        float freqResolution = floatPropertyIntersection(infos,
+                info -> info.getFrequencyProfile().getFrequencyResolutionHz());
+        float resonantFreq = floatPropertyIntersection(infos,
+                VibratorInfo::getResonantFrequencyHz);
+        Range<Float> freqRange = frequencyRangeIntersection(infos, freqResolution);
+
+        if ((freqRange == null) || Float.isNaN(freqResolution)) {
+            return new FrequencyProfile(resonantFreq, Float.NaN, freqResolution, null);
+        }
+
+        int amplitudeCount =
+                Math.round(1 + (freqRange.getUpper() - freqRange.getLower()) / freqResolution);
+        float[] maxAmplitudes = new float[amplitudeCount];
+
+        // Use MAX_VALUE here to ensure that the FrequencyProfile constructor called with this
+        // will fail if the loop below is broken and do not replace filled values with actual
+        // vibrator measurements.
+        Arrays.fill(maxAmplitudes, Float.MAX_VALUE);
+
+        for (VibratorInfo info : infos) {
+            Range<Float> vibratorFreqRange = info.getFrequencyProfile().getFrequencyRangeHz();
+            float[] vibratorMaxAmplitudes = info.getFrequencyProfile().getMaxAmplitudes();
+            int vibratorStartIdx = Math.round(
+                    (freqRange.getLower() - vibratorFreqRange.getLower()) / freqResolution);
+            int vibratorEndIdx = vibratorStartIdx + maxAmplitudes.length - 1;
+
+            if ((vibratorStartIdx < 0) || (vibratorEndIdx >= vibratorMaxAmplitudes.length)) {
+                Slog.w(TAG, "Error calculating the intersection of vibrator frequency"
+                        + " profiles: attempted to fetch from vibrator "
+                        + info.getId() + " max amplitude with bad index " + vibratorStartIdx);
+                return new FrequencyProfile(resonantFreq, Float.NaN, Float.NaN, null);
+            }
+
+            for (int i = 0; i < maxAmplitudes.length; i++) {
+                maxAmplitudes[i] = Math.min(maxAmplitudes[i],
+                        vibratorMaxAmplitudes[vibratorStartIdx + i]);
+            }
+        }
+
+        return new FrequencyProfile(resonantFreq, freqRange.getLower(),
+                freqResolution, maxAmplitudes);
+    }
+
+    @Nullable
+    private static Range<Float> frequencyRangeIntersection(VibratorInfo[] infos,
+            float frequencyResolution) {
+        Range<Float> firstRange = infos[0].getFrequencyProfile().getFrequencyRangeHz();
+        if (firstRange == null) {
+            // If one vibrator is undefined then the intersection is undefined.
+            return null;
+        }
+        float intersectionLower = firstRange.getLower();
+        float intersectionUpper = firstRange.getUpper();
+
+        // Generate the intersection of all vibrator supported ranges, making sure that both
+        // min supported frequencies are aligned w.r.t. the frequency resolution.
+
+        for (int i = 1; i < infos.length; i++) {
+            Range<Float> vibratorRange = infos[i].getFrequencyProfile().getFrequencyRangeHz();
+            if (vibratorRange == null) {
+                // If one vibrator is undefined then the intersection is undefined.
+                return null;
+            }
+
+            if ((vibratorRange.getLower() >= intersectionUpper)
+                    || (vibratorRange.getUpper() <= intersectionLower)) {
+                // If the range and intersection are disjoint then the intersection is undefined
+                return null;
+            }
+
+            float frequencyDelta = Math.abs(intersectionLower - vibratorRange.getLower());
+            if ((frequencyDelta % frequencyResolution) > EPSILON) {
+                // If the intersection is not aligned with one vibrator then it's undefined
+                return null;
+            }
+
+            intersectionLower = Math.max(intersectionLower, vibratorRange.getLower());
+            intersectionUpper = Math.min(intersectionUpper, vibratorRange.getUpper());
+        }
+
+        if ((intersectionUpper - intersectionLower) < frequencyResolution) {
+            // If the intersection is empty then it's undefined.
+            return null;
+        }
+
+        return Range.create(intersectionLower, intersectionUpper);
+    }
+}
diff --git a/core/java/android/os/vibrator/VibratorInfoFactory.java b/core/java/android/os/vibrator/VibratorInfoFactory.java
new file mode 100644
index 0000000..d10d7ec
--- /dev/null
+++ b/core/java/android/os/vibrator/VibratorInfoFactory.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.os.vibrator;
+
+import android.annotation.NonNull;
+import android.os.VibratorInfo;
+
+/**
+ * Factory for creating {@link VibratorInfo}s.
+ *
+ * @hide
+ */
+public final class VibratorInfoFactory {
+    /**
+     * Creates a single {@link VibratorInfo} that is an intersection of a given collection of
+     * {@link VibratorInfo}s. That is, the capabilities of the returned info will be an
+     * intersection of that of the provided infos.
+     *
+     * @param id the ID for the new {@link VibratorInfo}.
+     * @param vibratorInfos the {@link VibratorInfo}s from which to create a single
+     *      {@link VibratorInfo}.
+     * @return a {@link VibratorInfo} that represents the intersection of {@code vibratorInfos}.
+     */
+    @NonNull
+    public static VibratorInfo create(int id, @NonNull VibratorInfo[] vibratorInfos) {
+        if (vibratorInfos.length == 0) {
+            return new VibratorInfo.Builder(id).build();
+        }
+        if (vibratorInfos.length == 1) {
+            // Create an equivalent info with the requested ID.
+            return new VibratorInfo(id, vibratorInfos[0]);
+        }
+        // Create a MultiVibratorInfo that intersects all the given infos and has the requested ID.
+        return new MultiVibratorInfo(id, vibratorInfos);
+    }
+
+    private VibratorInfoFactory() {}
+}
diff --git a/core/tests/vibrator/src/android/os/VibratorInfoTest.java b/core/tests/vibrator/src/android/os/VibratorInfoTest.java
index 808c4ec..73cd464 100644
--- a/core/tests/vibrator/src/android/os/VibratorInfoTest.java
+++ b/core/tests/vibrator/src/android/os/VibratorInfoTest.java
@@ -257,8 +257,13 @@
 
     @Test
     public void testEquals() {
-        VibratorInfo.Builder completeBuilder = new VibratorInfo.Builder(TEST_VIBRATOR_ID)
-                .setCapabilities(IVibrator.CAP_AMPLITUDE_CONTROL)
+        VibratorInfo.Builder completeBuilder = new VibratorInfo.Builder(TEST_VIBRATOR_ID);
+        // Create a builder with a different ID, but same properties the same as the first one.
+        VibratorInfo.Builder completeBuilder2 = new VibratorInfo.Builder(TEST_VIBRATOR_ID + 2);
+
+        for (VibratorInfo.Builder builder :
+                new VibratorInfo.Builder[] {completeBuilder, completeBuilder2}) {
+            builder.setCapabilities(IVibrator.CAP_AMPLITUDE_CONTROL)
                 .setSupportedEffects(VibrationEffect.EFFECT_CLICK)
                 .setSupportedPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK, 20)
                 .setPrimitiveDelayMax(100)
@@ -268,31 +273,43 @@
                 .setPwleSizeMax(20)
                 .setQFactor(2f)
                 .setFrequencyProfile(TEST_FREQUENCY_PROFILE);
+        }
         VibratorInfo complete = completeBuilder.build();
 
         assertEquals(complete, complete);
+        assertTrue(complete.equalContent(complete));
         assertEquals(complete, completeBuilder.build());
+        assertTrue(complete.equalContent(completeBuilder.build()));
         assertEquals(complete.hashCode(), completeBuilder.build().hashCode());
 
+        // The infos from the two builders should have equal content, but should not be equal due to
+        // their different IDs.
+        assertNotEquals(complete, completeBuilder2.build());
+        assertTrue(complete.equalContent(completeBuilder2.build()));
+
         VibratorInfo completeWithComposeControl = completeBuilder
                 .setCapabilities(IVibrator.CAP_COMPOSE_EFFECTS)
                 .build();
         assertNotEquals(complete, completeWithComposeControl);
+        assertFalse(complete.equalContent(completeWithComposeControl));
 
         VibratorInfo completeWithNoEffects = completeBuilder
                 .setSupportedEffects(new int[0])
                 .build();
         assertNotEquals(complete, completeWithNoEffects);
+        assertFalse(complete.equalContent(completeWithNoEffects));
 
         VibratorInfo completeWithUnknownEffects = completeBuilder
                 .setSupportedEffects(null)
                 .build();
         assertNotEquals(complete, completeWithUnknownEffects);
+        assertFalse(complete.equalContent(completeWithUnknownEffects));
 
         VibratorInfo completeWithDifferentPrimitiveDuration = completeBuilder
                 .setSupportedPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK, 10)
                 .build();
         assertNotEquals(complete, completeWithDifferentPrimitiveDuration);
+        assertFalse(complete.equalContent(completeWithDifferentPrimitiveDuration));
 
         VibratorInfo completeWithDifferentFrequencyProfile = completeBuilder
                 .setFrequencyProfile(new VibratorInfo.FrequencyProfile(
@@ -302,31 +319,37 @@
                         TEST_AMPLITUDE_MAP))
                 .build();
         assertNotEquals(complete, completeWithDifferentFrequencyProfile);
+        assertFalse(complete.equalContent(completeWithDifferentFrequencyProfile));
 
         VibratorInfo completeWithEmptyFrequencyProfile = completeBuilder
                 .setFrequencyProfile(EMPTY_FREQUENCY_PROFILE)
                 .build();
         assertNotEquals(complete, completeWithEmptyFrequencyProfile);
+        assertFalse(complete.equalContent(completeWithEmptyFrequencyProfile));
 
         VibratorInfo completeWithUnknownQFactor = completeBuilder.setQFactor(Float.NaN).build();
         assertNotEquals(complete, completeWithUnknownQFactor);
+        assertFalse(complete.equalContent(completeWithUnknownQFactor));
 
         VibratorInfo completeWithDifferentQFactor = completeBuilder
                 .setQFactor(complete.getQFactor() + 3f)
                 .build();
         assertNotEquals(complete, completeWithDifferentQFactor);
+        assertFalse(complete.equalContent(completeWithDifferentQFactor));
 
         VibratorInfo unknownEffectSupport = new VibratorInfo.Builder(TEST_VIBRATOR_ID).build();
         VibratorInfo knownEmptyEffectSupport = new VibratorInfo.Builder(TEST_VIBRATOR_ID)
                 .setSupportedEffects(new int[0])
                 .build();
         assertNotEquals(unknownEffectSupport, knownEmptyEffectSupport);
+        assertFalse(unknownEffectSupport.equalContent(knownEmptyEffectSupport));
 
         VibratorInfo unknownBrakingSupport = new VibratorInfo.Builder(TEST_VIBRATOR_ID).build();
         VibratorInfo knownEmptyBrakingSupport = new VibratorInfo.Builder(TEST_VIBRATOR_ID)
                 .setSupportedBraking(new int[0])
                 .build();
         assertNotEquals(unknownBrakingSupport, knownEmptyBrakingSupport);
+        assertFalse(unknownBrakingSupport.equalContent(knownEmptyBrakingSupport));
     }
 
     @Test
diff --git a/core/tests/vibrator/src/android/os/VibratorTest.java b/core/tests/vibrator/src/android/os/VibratorTest.java
index 8141ca4..cfa12bb 100644
--- a/core/tests/vibrator/src/android/os/VibratorTest.java
+++ b/core/tests/vibrator/src/android/os/VibratorTest.java
@@ -37,7 +37,6 @@
 import android.content.ContentResolver;
 import android.content.Context;
 import android.content.ContextWrapper;
-import android.hardware.vibrator.IVibrator;
 import android.media.AudioAttributes;
 import android.os.test.TestLooper;
 
@@ -60,8 +59,6 @@
     @Rule
     public FakeSettingsProviderRule mSettingsProviderRule = FakeSettingsProvider.rule();
 
-    private static final float TEST_TOLERANCE = 1e-5f;
-
     private Context mContextSpy;
     private Vibrator mVibratorSpy;
     private TestLooper mTestLooper;
@@ -79,9 +76,6 @@
     @Test
     public void getId_returnsDefaultId() {
         assertEquals(-1, mVibratorSpy.getId());
-        assertEquals(-1, new SystemVibrator.NoVibratorInfo().getId());
-        assertEquals(-1, new SystemVibrator.MultiVibratorInfo(new VibratorInfo[] {
-                VibratorInfo.EMPTY_VIBRATOR_INFO, VibratorInfo.EMPTY_VIBRATOR_INFO }).getId());
     }
 
     @Test
@@ -95,53 +89,6 @@
     }
 
     @Test
-    public void areEffectsSupported_noVibrator_returnsAlwaysNo() {
-        VibratorInfo info = new SystemVibrator.NoVibratorInfo();
-        assertEquals(Vibrator.VIBRATION_EFFECT_SUPPORT_NO,
-                info.isEffectSupported(VibrationEffect.EFFECT_CLICK));
-    }
-
-    @Test
-    public void areEffectsSupported_unsupportedInOneVibrator_returnsNo() {
-        VibratorInfo supportedVibrator = new VibratorInfo.Builder(/* id= */ 1)
-                .setSupportedEffects(VibrationEffect.EFFECT_CLICK)
-                .build();
-        VibratorInfo unsupportedVibrator = new VibratorInfo.Builder(/* id= */ 2)
-                .setSupportedEffects(new int[0])
-                .build();
-        VibratorInfo info = new SystemVibrator.MultiVibratorInfo(
-                new VibratorInfo[]{supportedVibrator, unsupportedVibrator});
-        assertEquals(Vibrator.VIBRATION_EFFECT_SUPPORT_NO,
-                info.isEffectSupported(VibrationEffect.EFFECT_CLICK));
-    }
-
-    @Test
-    public void areEffectsSupported_unknownInOneVibrator_returnsUnknown() {
-        VibratorInfo supportedVibrator = new VibratorInfo.Builder(/* id= */ 1)
-                .setSupportedEffects(VibrationEffect.EFFECT_CLICK)
-                .build();
-        VibratorInfo unknownSupportVibrator = VibratorInfo.EMPTY_VIBRATOR_INFO;
-        VibratorInfo info = new SystemVibrator.MultiVibratorInfo(
-                new VibratorInfo[]{supportedVibrator, unknownSupportVibrator});
-        assertEquals(Vibrator.VIBRATION_EFFECT_SUPPORT_UNKNOWN,
-                info.isEffectSupported(VibrationEffect.EFFECT_CLICK));
-    }
-
-    @Test
-    public void arePrimitivesSupported_supportedInAllVibrators_returnsYes() {
-        VibratorInfo firstVibrator = new VibratorInfo.Builder(/* id= */ 1)
-                .setSupportedEffects(VibrationEffect.EFFECT_CLICK)
-                .build();
-        VibratorInfo secondVibrator = new VibratorInfo.Builder(/* id= */ 2)
-                .setSupportedEffects(VibrationEffect.EFFECT_CLICK)
-                .build();
-        VibratorInfo info = new SystemVibrator.MultiVibratorInfo(
-                new VibratorInfo[]{firstVibrator, secondVibrator});
-        assertEquals(Vibrator.VIBRATION_EFFECT_SUPPORT_YES,
-                info.isEffectSupported(VibrationEffect.EFFECT_CLICK));
-    }
-
-    @Test
     public void arePrimitivesSupported_returnsArrayOfSameSize() {
         assertEquals(0, mVibratorSpy.arePrimitivesSupported(new int[0]).length);
         assertEquals(1, mVibratorSpy.arePrimitivesSupported(
@@ -152,39 +99,6 @@
     }
 
     @Test
-    public void arePrimitivesSupported_noVibrator_returnsAlwaysFalse() {
-        VibratorInfo info = new SystemVibrator.NoVibratorInfo();
-        assertFalse(info.isPrimitiveSupported(VibrationEffect.Composition.PRIMITIVE_CLICK));
-    }
-
-    @Test
-    public void arePrimitivesSupported_unsupportedInOneVibrator_returnsFalse() {
-        VibratorInfo supportedVibrator = new VibratorInfo.Builder(/* id= */ 1)
-                .setCapabilities(IVibrator.CAP_COMPOSE_EFFECTS)
-                .setSupportedPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK, 10)
-                .build();
-        VibratorInfo unsupportedVibrator = VibratorInfo.EMPTY_VIBRATOR_INFO;
-        VibratorInfo info = new SystemVibrator.MultiVibratorInfo(
-                new VibratorInfo[]{supportedVibrator, unsupportedVibrator});
-        assertFalse(info.isPrimitiveSupported(VibrationEffect.Composition.PRIMITIVE_CLICK));
-    }
-
-    @Test
-    public void arePrimitivesSupported_supportedInAllVibrators_returnsTrue() {
-        VibratorInfo firstVibrator = new VibratorInfo.Builder(/* id= */ 1)
-                .setCapabilities(IVibrator.CAP_COMPOSE_EFFECTS)
-                .setSupportedPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK, 5)
-                .build();
-        VibratorInfo secondVibrator = new VibratorInfo.Builder(/* id= */ 2)
-                .setCapabilities(IVibrator.CAP_COMPOSE_EFFECTS)
-                .setSupportedPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK, 15)
-                .build();
-        VibratorInfo info = new SystemVibrator.MultiVibratorInfo(
-                new VibratorInfo[]{firstVibrator, secondVibrator});
-        assertTrue(info.isPrimitiveSupported(VibrationEffect.Composition.PRIMITIVE_CLICK));
-    }
-
-    @Test
     public void getPrimitivesDurations_returnsArrayOfSameSize() {
         assertEquals(0, mVibratorSpy.getPrimitiveDurations(new int[0]).length);
         assertEquals(1, mVibratorSpy.getPrimitiveDurations(
@@ -195,245 +109,6 @@
     }
 
     @Test
-    public void getPrimitivesDurations_noVibrator_returnsAlwaysZero() {
-        VibratorInfo info = new SystemVibrator.NoVibratorInfo();
-        assertEquals(0, info.getPrimitiveDuration(VibrationEffect.Composition.PRIMITIVE_CLICK));
-    }
-
-    @Test
-    public void getPrimitivesDurations_unsupportedInOneVibrator_returnsZero() {
-        VibratorInfo supportedVibrator = new VibratorInfo.Builder(/* id= */ 1)
-                .setCapabilities(IVibrator.CAP_COMPOSE_EFFECTS)
-                .setSupportedPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK, 10)
-                .build();
-        VibratorInfo unsupportedVibrator = VibratorInfo.EMPTY_VIBRATOR_INFO;
-        VibratorInfo info = new SystemVibrator.MultiVibratorInfo(
-                new VibratorInfo[]{supportedVibrator, unsupportedVibrator});
-        assertEquals(0, info.getPrimitiveDuration(VibrationEffect.Composition.PRIMITIVE_CLICK));
-    }
-
-    @Test
-    public void getPrimitivesDurations_supportedInAllVibrators_returnsMaxDuration() {
-        VibratorInfo firstVibrator = new VibratorInfo.Builder(/* id= */ 1)
-                .setCapabilities(IVibrator.CAP_COMPOSE_EFFECTS)
-                .setSupportedPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK, 10)
-                .build();
-        VibratorInfo secondVibrator = new VibratorInfo.Builder(/* id= */ 2)
-                .setCapabilities(IVibrator.CAP_COMPOSE_EFFECTS)
-                .setSupportedPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK, 20)
-                .build();
-        VibratorInfo info = new SystemVibrator.MultiVibratorInfo(
-                new VibratorInfo[]{firstVibrator, secondVibrator});
-        assertEquals(20, info.getPrimitiveDuration(VibrationEffect.Composition.PRIMITIVE_CLICK));
-    }
-
-    @Test
-    public void getQFactorAndResonantFrequency_noVibrator_returnsNaN() {
-        VibratorInfo info = new SystemVibrator.NoVibratorInfo();
-
-        assertTrue(Float.isNaN(info.getQFactor()));
-        assertTrue(Float.isNaN(info.getResonantFrequencyHz()));
-    }
-
-    @Test
-    public void getQFactorAndResonantFrequency_differentValues_returnsNaN() {
-        VibratorInfo firstVibrator = new VibratorInfo.Builder(/* id= */ 1)
-                .setCapabilities(IVibrator.CAP_FREQUENCY_CONTROL)
-                .setQFactor(1f)
-                .setFrequencyProfile(new VibratorInfo.FrequencyProfile(1, 1, 1, null))
-                .build();
-        VibratorInfo secondVibrator = new VibratorInfo.Builder(/* id= */ 2)
-                .setCapabilities(IVibrator.CAP_FREQUENCY_CONTROL)
-                .setQFactor(2f)
-                .setFrequencyProfile(new VibratorInfo.FrequencyProfile(2, 2, 2, null))
-                .build();
-        VibratorInfo info = new SystemVibrator.MultiVibratorInfo(
-                new VibratorInfo[]{firstVibrator, secondVibrator});
-
-        assertTrue(Float.isNaN(info.getQFactor()));
-        assertTrue(Float.isNaN(info.getResonantFrequencyHz()));
-        assertEmptyFrequencyProfileAndControl(info);
-
-        // One vibrator with values undefined.
-        VibratorInfo thirdVibrator = new VibratorInfo.Builder(/* id= */ 3).build();
-        info = new SystemVibrator.MultiVibratorInfo(
-                new VibratorInfo[]{firstVibrator, thirdVibrator});
-
-        assertTrue(Float.isNaN(info.getQFactor()));
-        assertTrue(Float.isNaN(info.getResonantFrequencyHz()));
-        assertEmptyFrequencyProfileAndControl(info);
-    }
-
-    @Test
-    public void getQFactorAndResonantFrequency_sameValues_returnsValue() {
-        VibratorInfo firstVibrator = new VibratorInfo.Builder(/* id= */ 1)
-                .setCapabilities(IVibrator.CAP_FREQUENCY_CONTROL)
-                .setQFactor(10f)
-                .setFrequencyProfile(new VibratorInfo.FrequencyProfile(
-                        /* resonantFrequencyHz= */ 11, 10, 0.5f, null))
-                .build();
-        VibratorInfo secondVibrator = new VibratorInfo.Builder(/* id= */ 2)
-                .setCapabilities(IVibrator.CAP_FREQUENCY_CONTROL)
-                .setQFactor(10f)
-                .setFrequencyProfile(new VibratorInfo.FrequencyProfile(
-                        /* resonantFrequencyHz= */ 11, 5, 1, null))
-                .build();
-        VibratorInfo info = new SystemVibrator.MultiVibratorInfo(
-                new VibratorInfo[]{firstVibrator, secondVibrator});
-
-        assertEquals(10f, info.getQFactor(), TEST_TOLERANCE);
-        assertEquals(11f, info.getResonantFrequencyHz(), TEST_TOLERANCE);
-
-        // No frequency range defined.
-        assertTrue(info.getFrequencyProfile().isEmpty());
-        assertEquals(false, info.hasCapability(IVibrator.CAP_FREQUENCY_CONTROL));
-    }
-
-    @Test
-    public void getFrequencyProfile_noVibrator_returnsEmpty() {
-        VibratorInfo info = new SystemVibrator.NoVibratorInfo();
-
-        assertEmptyFrequencyProfileAndControl(info);
-    }
-
-    @Test
-    public void getFrequencyProfile_differentResonantFrequencyOrResolutionValues_returnsEmpty() {
-        VibratorInfo firstVibrator = new VibratorInfo.Builder(/* id= */ 1)
-                .setCapabilities(IVibrator.CAP_FREQUENCY_CONTROL)
-                .setFrequencyProfile(new VibratorInfo.FrequencyProfile(1, 1, 1,
-                        new float[] { 0, 1 }))
-                .build();
-        VibratorInfo differentResonantFrequency = new VibratorInfo.Builder(/* id= */ 2)
-                .setCapabilities(IVibrator.CAP_FREQUENCY_CONTROL)
-                .setFrequencyProfile(new VibratorInfo.FrequencyProfile(2, 1, 1,
-                        new float[] { 0, 1 }))
-                .build();
-        VibratorInfo info = new SystemVibrator.MultiVibratorInfo(
-                new VibratorInfo[]{firstVibrator, differentResonantFrequency});
-
-        assertEmptyFrequencyProfileAndControl(info);
-
-        VibratorInfo differentFrequencyResolution = new VibratorInfo.Builder(/* id= */ 2)
-                .setCapabilities(IVibrator.CAP_FREQUENCY_CONTROL)
-                .setFrequencyProfile(new VibratorInfo.FrequencyProfile(1, 1, 2,
-                        new float[] { 0, 1 }))
-                .build();
-        info = new SystemVibrator.MultiVibratorInfo(
-                new VibratorInfo[]{firstVibrator, differentFrequencyResolution});
-
-        assertEmptyFrequencyProfileAndControl(info);
-    }
-
-    @Test
-    public void getFrequencyProfile_missingValues_returnsEmpty() {
-        VibratorInfo firstVibrator = new VibratorInfo.Builder(/* id= */ 1)
-                .setCapabilities(IVibrator.CAP_FREQUENCY_CONTROL)
-                .setFrequencyProfile(new VibratorInfo.FrequencyProfile(1, 1, 1,
-                        new float[] { 0, 1 }))
-                .build();
-        VibratorInfo missingResonantFrequency = new VibratorInfo.Builder(/* id= */ 2)
-                .setCapabilities(IVibrator.CAP_FREQUENCY_CONTROL)
-                .setFrequencyProfile(new VibratorInfo.FrequencyProfile(Float.NaN, 1, 1,
-                        new float[] { 0, 1 }))
-                .build();
-        VibratorInfo info = new SystemVibrator.MultiVibratorInfo(
-                new VibratorInfo[]{firstVibrator, missingResonantFrequency});
-
-        assertEmptyFrequencyProfileAndControl(info);
-
-        VibratorInfo missingMinFrequency = new VibratorInfo.Builder(/* id= */ 2)
-                .setCapabilities(IVibrator.CAP_FREQUENCY_CONTROL)
-                .setFrequencyProfile(new VibratorInfo.FrequencyProfile(1, Float.NaN, 1,
-                        new float[] { 0, 1 }))
-                .build();
-        info = new SystemVibrator.MultiVibratorInfo(
-                new VibratorInfo[]{firstVibrator, missingMinFrequency});
-
-        assertEmptyFrequencyProfileAndControl(info);
-
-        VibratorInfo missingFrequencyResolution = new VibratorInfo.Builder(/* id= */ 2)
-                .setCapabilities(IVibrator.CAP_FREQUENCY_CONTROL)
-                .setFrequencyProfile(new VibratorInfo.FrequencyProfile(1, 1, Float.NaN,
-                        new float[] { 0, 1 }))
-                .build();
-        info = new SystemVibrator.MultiVibratorInfo(
-                new VibratorInfo[]{firstVibrator, missingFrequencyResolution});
-
-        assertEmptyFrequencyProfileAndControl(info);
-
-        VibratorInfo missingMaxAmplitudes = new VibratorInfo.Builder(/* id= */ 2)
-                .setCapabilities(IVibrator.CAP_FREQUENCY_CONTROL)
-                .setFrequencyProfile(new VibratorInfo.FrequencyProfile(1, 1, 1, null))
-                .build();
-        info = new SystemVibrator.MultiVibratorInfo(
-                new VibratorInfo[]{firstVibrator, missingMaxAmplitudes});
-
-        assertEmptyFrequencyProfileAndControl(info);
-    }
-
-    @Test
-    public void getFrequencyProfile_unalignedMaxAmplitudes_returnsEmpty() {
-        VibratorInfo firstVibrator = new VibratorInfo.Builder(/* id= */ 1)
-                .setCapabilities(IVibrator.CAP_FREQUENCY_CONTROL)
-                .setFrequencyProfile(new VibratorInfo.FrequencyProfile(11, 10, 0.5f,
-                        new float[] { 0, 1, 1, 0 }))
-                .build();
-        VibratorInfo unalignedMinFrequency = new VibratorInfo.Builder(/* id= */ 2)
-                .setCapabilities(IVibrator.CAP_FREQUENCY_CONTROL)
-                .setFrequencyProfile(new VibratorInfo.FrequencyProfile(11, 10.1f, 0.5f,
-                        new float[] { 0, 1, 1, 0 }))
-                .build();
-        VibratorInfo thirdVibrator = new VibratorInfo.Builder(/* id= */ 2)
-                .setCapabilities(IVibrator.CAP_FREQUENCY_CONTROL)
-                .setFrequencyProfile(new VibratorInfo.FrequencyProfile(11, 10.5f, 0.5f,
-                        new float[] { 0, 1, 1, 0 }))
-                .build();
-        VibratorInfo info = new SystemVibrator.MultiVibratorInfo(
-                new VibratorInfo[]{firstVibrator, unalignedMinFrequency, thirdVibrator});
-
-        assertEmptyFrequencyProfileAndControl(info);
-    }
-
-    @Test
-    public void getFrequencyProfile_alignedProfiles_returnsIntersection() {
-        VibratorInfo firstVibrator = new VibratorInfo.Builder(/* id= */ 1)
-                .setCapabilities(IVibrator.CAP_FREQUENCY_CONTROL)
-                .setFrequencyProfile(new VibratorInfo.FrequencyProfile(11, 10, 0.5f,
-                        new float[] { 0.5f, 1, 1, 0.5f }))
-                .build();
-        VibratorInfo secondVibrator = new VibratorInfo.Builder(/* id= */ 2)
-                .setCapabilities(IVibrator.CAP_FREQUENCY_CONTROL)
-                .setFrequencyProfile(new VibratorInfo.FrequencyProfile(11, 10.5f, 0.5f,
-                        new float[] { 1, 1, 1 }))
-                .build();
-        VibratorInfo thirdVibrator = new VibratorInfo.Builder(/* id= */ 3)
-                .setCapabilities(IVibrator.CAP_FREQUENCY_CONTROL)
-                .setFrequencyProfile(new VibratorInfo.FrequencyProfile(11, 10.5f, 0.5f,
-                        new float[] { 0.8f, 1, 0.8f, 0.5f }))
-                .build();
-        VibratorInfo info = new SystemVibrator.MultiVibratorInfo(
-                new VibratorInfo[]{firstVibrator, secondVibrator, thirdVibrator});
-
-        assertEquals(
-                new VibratorInfo.FrequencyProfile(11, 10.5f, 0.5f, new float[] { 0.8f, 1, 0.5f }),
-                info.getFrequencyProfile());
-        assertEquals(true, info.hasCapability(IVibrator.CAP_FREQUENCY_CONTROL));
-
-        // Third vibrator without frequency control capability.
-        thirdVibrator = new VibratorInfo.Builder(/* id= */ 3)
-                .setFrequencyProfile(new VibratorInfo.FrequencyProfile(11, 10.5f, 0.5f,
-                        new float[] { 0.8f, 1, 0.8f, 0.5f }))
-                .build();
-        info = new SystemVibrator.MultiVibratorInfo(
-                new VibratorInfo[]{firstVibrator, secondVibrator, thirdVibrator});
-
-        assertEquals(
-                new VibratorInfo.FrequencyProfile(11, 10.5f, 0.5f, new float[] { 0.8f, 1, 0.5f }),
-                info.getFrequencyProfile());
-        assertEquals(false, info.hasCapability(IVibrator.CAP_FREQUENCY_CONTROL));
-    }
-
-    @Test
     public void onVibratorStateChanged_noVibrator_registersNoListenerToVibratorManager() {
         VibratorManager mockVibratorManager = mock(VibratorManager.class);
         when(mockVibratorManager.getVibratorIds()).thenReturn(new int[0]);
@@ -577,12 +252,4 @@
         VibrationAttributes vibrationAttributes = captor.getValue();
         assertEquals(new VibrationAttributes.Builder().build(), vibrationAttributes);
     }
-
-    /**
-     * Asserts that the frequency profile is empty, and therefore frequency control isn't supported.
-     */
-    void assertEmptyFrequencyProfileAndControl(VibratorInfo info) {
-        assertTrue(info.getFrequencyProfile().isEmpty());
-        assertEquals(false, info.hasCapability(IVibrator.CAP_FREQUENCY_CONTROL));
-    }
 }
diff --git a/core/tests/vibrator/src/android/os/vibrator/MultiVibratorInfoTest.java b/core/tests/vibrator/src/android/os/vibrator/MultiVibratorInfoTest.java
new file mode 100644
index 0000000..fc31ac4
--- /dev/null
+++ b/core/tests/vibrator/src/android/os/vibrator/MultiVibratorInfoTest.java
@@ -0,0 +1,361 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.os.vibrator;
+
+import static junit.framework.Assert.assertFalse;
+import static junit.framework.Assert.assertTrue;
+import static junit.framework.TestCase.assertEquals;
+
+import android.hardware.vibrator.IVibrator;
+import android.os.VibrationEffect;
+import android.os.Vibrator;
+import android.os.VibratorInfo;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+@RunWith(JUnit4.class)
+public class MultiVibratorInfoTest {
+    private static final float TEST_TOLERANCE = 1e-5f;
+
+    @Test
+    public void testGetId() {
+        VibratorInfo firstInfo = new VibratorInfo.Builder(/* id= */ 1)
+                .setSupportedEffects(VibrationEffect.EFFECT_CLICK)
+                .build();
+        VibratorInfo secondInfo = new VibratorInfo.Builder(/* id= */ 2)
+                .setSupportedEffects(new int[0])
+                .build();
+
+        VibratorInfo info = new MultiVibratorInfo(/* id= */ 3,
+                new VibratorInfo[]{firstInfo, secondInfo});
+
+        assertEquals(3, info.getId());
+    }
+
+    @Test
+    public void testIsEffectSupported_supportedInAllVibrators_returnsYes() {
+        VibratorInfo firstInfo = new VibratorInfo.Builder(/* id= */ 2)
+                .setCapabilities(IVibrator.CAP_COMPOSE_EFFECTS)
+                .setSupportedEffects(VibrationEffect.EFFECT_CLICK)
+                .build();
+        VibratorInfo secondInfo = new VibratorInfo.Builder(/* id= */ 2)
+                .setSupportedEffects(VibrationEffect.EFFECT_CLICK, VibrationEffect.EFFECT_TICK)
+                .build();
+
+        VibratorInfo info = new MultiVibratorInfo(/* id= */ 1,
+                new VibratorInfo[]{firstInfo, secondInfo});
+
+        assertEquals(Vibrator.VIBRATION_EFFECT_SUPPORT_YES,
+                info.isEffectSupported(VibrationEffect.EFFECT_CLICK));
+    }
+
+    @Test
+    public void testIsEffectSupported_unsupportedInOneVibrator_returnsNo() {
+        VibratorInfo supportedVibrator = new VibratorInfo.Builder(/* id= */ 1)
+                .setSupportedEffects(VibrationEffect.EFFECT_CLICK)
+                .build();
+        VibratorInfo unsupportedVibrator = new VibratorInfo.Builder(/* id= */ 2)
+                .setSupportedEffects(new int[0])
+                .build();
+
+        VibratorInfo info = new MultiVibratorInfo(/* id= */ 1,
+                new VibratorInfo[]{supportedVibrator, unsupportedVibrator});
+
+        assertEquals(Vibrator.VIBRATION_EFFECT_SUPPORT_NO,
+                info.isEffectSupported(VibrationEffect.EFFECT_CLICK));
+    }
+
+    @Test
+    public void testIsEffectSupported_unknownInOneVibrator_returnsUnknown() {
+        VibratorInfo supportedVibrator = new VibratorInfo.Builder(/* id= */ 1)
+                .setSupportedEffects(VibrationEffect.EFFECT_CLICK)
+                .build();
+        VibratorInfo unknownSupportVibrator = VibratorInfo.EMPTY_VIBRATOR_INFO;
+
+        VibratorInfo info = new MultiVibratorInfo(/* id= */ 1,
+                new VibratorInfo[]{supportedVibrator, unknownSupportVibrator});
+        assertEquals(Vibrator.VIBRATION_EFFECT_SUPPORT_UNKNOWN,
+                info.isEffectSupported(VibrationEffect.EFFECT_CLICK));
+    }
+
+    @Test
+    public void testIsPrimitiveSupported_unsupportedInOneVibrator_returnsFalse() {
+        VibratorInfo supportedVibrator = new VibratorInfo.Builder(/* id= */ 1)
+                .setCapabilities(IVibrator.CAP_COMPOSE_EFFECTS)
+                .setSupportedPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK, 10)
+                .build();
+        VibratorInfo unsupportedVibrator = VibratorInfo.EMPTY_VIBRATOR_INFO;
+
+        VibratorInfo info = new MultiVibratorInfo(/* id= */ 1,
+                new VibratorInfo[]{supportedVibrator, unsupportedVibrator});
+
+        assertFalse(info.isPrimitiveSupported(VibrationEffect.Composition.PRIMITIVE_CLICK));
+    }
+
+    @Test
+    public void testIsPrimitiveSupported_supportedInAllVibrators_returnsTrue() {
+        VibratorInfo firstInfo = new VibratorInfo.Builder(/* id= */ 1)
+                .setCapabilities(IVibrator.CAP_COMPOSE_EFFECTS)
+                .setSupportedPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK, 5)
+                .build();
+        VibratorInfo secondInfo = new VibratorInfo.Builder(/* id= */ 2)
+                .setCapabilities(IVibrator.CAP_COMPOSE_EFFECTS)
+                .setSupportedPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK, 15)
+                .build();
+
+        VibratorInfo info = new MultiVibratorInfo(/* id= */ 1,
+                new VibratorInfo[]{firstInfo, secondInfo});
+
+        assertTrue(info.isPrimitiveSupported(VibrationEffect.Composition.PRIMITIVE_CLICK));
+    }
+
+    @Test
+    public void testGetPrimitiveDuration_unsupportedInOneVibrator_returnsZero() {
+        VibratorInfo supportedVibrator = new VibratorInfo.Builder(/* id= */ 1)
+                .setCapabilities(IVibrator.CAP_COMPOSE_EFFECTS)
+                .setSupportedPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK, 10)
+                .build();
+        VibratorInfo unsupportedVibrator = VibratorInfo.EMPTY_VIBRATOR_INFO;
+
+        VibratorInfo info = new MultiVibratorInfo(/* id= */ 1,
+                new VibratorInfo[]{supportedVibrator, unsupportedVibrator});
+
+        assertEquals(0, info.getPrimitiveDuration(VibrationEffect.Composition.PRIMITIVE_CLICK));
+    }
+
+    @Test
+    public void testGetPrimitiveDuration_supportedInAllVibrators_returnsMaxDuration() {
+        VibratorInfo firstInfo = new VibratorInfo.Builder(/* id= */ 1)
+                .setCapabilities(IVibrator.CAP_COMPOSE_EFFECTS)
+                .setSupportedPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK, 10)
+                .build();
+        VibratorInfo secondInfo = new VibratorInfo.Builder(/* id= */ 2)
+                .setCapabilities(IVibrator.CAP_COMPOSE_EFFECTS)
+                .setSupportedPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK, 20)
+                .build();
+
+        VibratorInfo info = new MultiVibratorInfo(/* id= */ 1,
+                new VibratorInfo[]{firstInfo, secondInfo});
+
+        assertEquals(20, info.getPrimitiveDuration(VibrationEffect.Composition.PRIMITIVE_CLICK));
+    }
+
+    @Test
+    public void testGetQFactorAndResonantFrequency_differentValues_returnsNaN() {
+        VibratorInfo firstInfo = new VibratorInfo.Builder(/* id= */ 1)
+                .setCapabilities(IVibrator.CAP_FREQUENCY_CONTROL)
+                .setQFactor(1f)
+                .setFrequencyProfile(new VibratorInfo.FrequencyProfile(1, 1, 1, null))
+                .build();
+        VibratorInfo secondInfo = new VibratorInfo.Builder(/* id= */ 2)
+                .setCapabilities(IVibrator.CAP_FREQUENCY_CONTROL)
+                .setQFactor(2f)
+                .setFrequencyProfile(new VibratorInfo.FrequencyProfile(2, 2, 2, null))
+                .build();
+
+        VibratorInfo info = new MultiVibratorInfo(/* id= */ 1,
+                new VibratorInfo[]{firstInfo, secondInfo});
+
+        assertTrue(Float.isNaN(info.getQFactor()));
+        assertTrue(Float.isNaN(info.getResonantFrequencyHz()));
+        assertEmptyFrequencyProfileAndControl(info);
+
+        // One vibrator with values undefined.
+        VibratorInfo thirdVibrator = new VibratorInfo.Builder(/* id= */ 3).build();
+        info = new MultiVibratorInfo(/* id= */ 1,
+                new VibratorInfo[]{firstInfo, thirdVibrator});
+
+        assertTrue(Float.isNaN(info.getQFactor()));
+        assertTrue(Float.isNaN(info.getResonantFrequencyHz()));
+        assertEmptyFrequencyProfileAndControl(info);
+    }
+
+    @Test
+    public void testGetQFactorAndResonantFrequency_sameValues_returnsValue() {
+        VibratorInfo firstInfo = new VibratorInfo.Builder(/* id= */ 1)
+                .setCapabilities(IVibrator.CAP_FREQUENCY_CONTROL)
+                .setQFactor(10f)
+                .setFrequencyProfile(new VibratorInfo.FrequencyProfile(
+                        /* resonantFrequencyHz= */ 11, 10, 0.5f, null))
+                .build();
+        VibratorInfo secondInfo = new VibratorInfo.Builder(/* id= */ 2)
+                .setCapabilities(IVibrator.CAP_FREQUENCY_CONTROL)
+                .setQFactor(10f)
+                .setFrequencyProfile(new VibratorInfo.FrequencyProfile(
+                        /* resonantFrequencyHz= */ 11, 5, 1, null))
+                .build();
+
+        VibratorInfo info = new MultiVibratorInfo(/* id= */ 1,
+                new VibratorInfo[]{firstInfo, secondInfo});
+
+        assertEquals(10f, info.getQFactor(), TEST_TOLERANCE);
+        assertEquals(11f, info.getResonantFrequencyHz(), TEST_TOLERANCE);
+        // No frequency range defined.
+        assertTrue(info.getFrequencyProfile().isEmpty());
+        assertEquals(false, info.hasCapability(IVibrator.CAP_FREQUENCY_CONTROL));
+    }
+
+    @Test
+    public void testGetFrequencyProfile_differentResonantFrequencyOrResolutions_returnsEmpty() {
+        VibratorInfo firstInfo = new VibratorInfo.Builder(/* id= */ 1)
+                .setCapabilities(IVibrator.CAP_FREQUENCY_CONTROL)
+                .setFrequencyProfile(new VibratorInfo.FrequencyProfile(1, 1, 1,
+                        new float[] { 0, 1 }))
+                .build();
+        VibratorInfo differentResonantFrequency = new VibratorInfo.Builder(/* id= */ 2)
+                .setCapabilities(IVibrator.CAP_FREQUENCY_CONTROL)
+                .setFrequencyProfile(new VibratorInfo.FrequencyProfile(2, 1, 1,
+                        new float[] { 0, 1 }))
+                .build();
+        VibratorInfo info = new MultiVibratorInfo(/* id= */ 1,
+                new VibratorInfo[]{firstInfo, differentResonantFrequency});
+
+        assertEmptyFrequencyProfileAndControl(info);
+
+        VibratorInfo differentFrequencyResolution = new VibratorInfo.Builder(/* id= */ 2)
+                .setCapabilities(IVibrator.CAP_FREQUENCY_CONTROL)
+                .setFrequencyProfile(new VibratorInfo.FrequencyProfile(1, 1, 2,
+                        new float[] { 0, 1 }))
+                .build();
+        info = new MultiVibratorInfo(/* id= */ 1,
+                new VibratorInfo[]{firstInfo, differentFrequencyResolution});
+
+        assertEmptyFrequencyProfileAndControl(info);
+    }
+
+    @Test
+    public void testGetFrequencyProfile_missingValues_returnsEmpty() {
+        VibratorInfo firstInfo = new VibratorInfo.Builder(/* id= */ 1)
+                .setCapabilities(IVibrator.CAP_FREQUENCY_CONTROL)
+                .setFrequencyProfile(new VibratorInfo.FrequencyProfile(1, 1, 1,
+                        new float[] { 0, 1 }))
+                .build();
+        VibratorInfo missingResonantFrequency = new VibratorInfo.Builder(/* id= */ 2)
+                .setCapabilities(IVibrator.CAP_FREQUENCY_CONTROL)
+                .setFrequencyProfile(new VibratorInfo.FrequencyProfile(Float.NaN, 1, 1,
+                        new float[] { 0, 1 }))
+                .build();
+
+        VibratorInfo info = new MultiVibratorInfo(/* id= */ 1,
+                new VibratorInfo[]{firstInfo, missingResonantFrequency});
+
+        assertEmptyFrequencyProfileAndControl(info);
+
+        VibratorInfo missingMinFrequency = new VibratorInfo.Builder(/* id= */ 2)
+                .setCapabilities(IVibrator.CAP_FREQUENCY_CONTROL)
+                .setFrequencyProfile(new VibratorInfo.FrequencyProfile(1, Float.NaN, 1,
+                        new float[] { 0, 1 }))
+                .build();
+        info = new MultiVibratorInfo(/* id= */ 1,
+                new VibratorInfo[]{firstInfo, missingMinFrequency});
+
+        assertEmptyFrequencyProfileAndControl(info);
+
+        VibratorInfo missingFrequencyResolution = new VibratorInfo.Builder(/* id= */ 2)
+                .setCapabilities(IVibrator.CAP_FREQUENCY_CONTROL)
+                .setFrequencyProfile(new VibratorInfo.FrequencyProfile(1, 1, Float.NaN,
+                        new float[] { 0, 1 }))
+                .build();
+        info = new MultiVibratorInfo(/* id= */ 1,
+                new VibratorInfo[]{firstInfo, missingFrequencyResolution});
+
+        assertEmptyFrequencyProfileAndControl(info);
+
+        VibratorInfo missingMaxAmplitudes = new VibratorInfo.Builder(/* id= */ 2)
+                .setCapabilities(IVibrator.CAP_FREQUENCY_CONTROL)
+                .setFrequencyProfile(new VibratorInfo.FrequencyProfile(1, 1, 1, null))
+                .build();
+        info = new MultiVibratorInfo(/* id= */ 1,
+                new VibratorInfo[]{firstInfo, missingMaxAmplitudes});
+
+        assertEmptyFrequencyProfileAndControl(info);
+    }
+
+    @Test
+    public void testGetFrequencyProfile_unalignedMaxAmplitudes_returnsEmpty() {
+        VibratorInfo firstInfo = new VibratorInfo.Builder(/* id= */ 1)
+                .setCapabilities(IVibrator.CAP_FREQUENCY_CONTROL)
+                .setFrequencyProfile(new VibratorInfo.FrequencyProfile(11, 10, 0.5f,
+                        new float[] { 0, 1, 1, 0 }))
+                .build();
+        VibratorInfo unalignedMinFrequency = new VibratorInfo.Builder(/* id= */ 2)
+                .setCapabilities(IVibrator.CAP_FREQUENCY_CONTROL)
+                .setFrequencyProfile(new VibratorInfo.FrequencyProfile(11, 10.1f, 0.5f,
+                        new float[] { 0, 1, 1, 0 }))
+                .build();
+        VibratorInfo thirdVibrator = new VibratorInfo.Builder(/* id= */ 2)
+                .setCapabilities(IVibrator.CAP_FREQUENCY_CONTROL)
+                .setFrequencyProfile(new VibratorInfo.FrequencyProfile(11, 10.5f, 0.5f,
+                        new float[] { 0, 1, 1, 0 }))
+                .build();
+
+        VibratorInfo info = new MultiVibratorInfo(/* id= */ 1,
+                new VibratorInfo[]{firstInfo, unalignedMinFrequency, thirdVibrator});
+
+        assertEmptyFrequencyProfileAndControl(info);
+    }
+
+    @Test
+    public void testGetFrequencyProfile_alignedProfiles_returnsIntersection() {
+        VibratorInfo firstInfo = new VibratorInfo.Builder(/* id= */ 1)
+                .setCapabilities(IVibrator.CAP_FREQUENCY_CONTROL)
+                .setFrequencyProfile(new VibratorInfo.FrequencyProfile(11, 10, 0.5f,
+                        new float[] { 0.5f, 1, 1, 0.5f }))
+                .build();
+        VibratorInfo secondInfo = new VibratorInfo.Builder(/* id= */ 2)
+                .setCapabilities(IVibrator.CAP_FREQUENCY_CONTROL)
+                .setFrequencyProfile(new VibratorInfo.FrequencyProfile(11, 10.5f, 0.5f,
+                        new float[] { 1, 1, 1 }))
+                .build();
+        VibratorInfo thirdVibrator = new VibratorInfo.Builder(/* id= */ 3)
+                .setCapabilities(IVibrator.CAP_FREQUENCY_CONTROL)
+                .setFrequencyProfile(new VibratorInfo.FrequencyProfile(11, 10.5f, 0.5f,
+                        new float[] { 0.8f, 1, 0.8f, 0.5f }))
+                .build();
+
+        VibratorInfo info = new MultiVibratorInfo(/* id= */ 1,
+                new VibratorInfo[]{firstInfo, secondInfo, thirdVibrator});
+
+        assertEquals(
+                new VibratorInfo.FrequencyProfile(11, 10.5f, 0.5f, new float[] { 0.8f, 1, 0.5f }),
+                info.getFrequencyProfile());
+        assertEquals(true, info.hasCapability(IVibrator.CAP_FREQUENCY_CONTROL));
+
+        // Third vibrator without frequency control capability.
+        thirdVibrator = new VibratorInfo.Builder(/* id= */ 3)
+                .setFrequencyProfile(new VibratorInfo.FrequencyProfile(11, 10.5f, 0.5f,
+                        new float[] { 0.8f, 1, 0.8f, 0.5f }))
+                .build();
+        info = new MultiVibratorInfo(/* id= */ 1,
+                new VibratorInfo[]{firstInfo, secondInfo, thirdVibrator});
+
+        assertEquals(
+                new VibratorInfo.FrequencyProfile(11, 10.5f, 0.5f, new float[] { 0.8f, 1, 0.5f }),
+                info.getFrequencyProfile());
+        assertEquals(false, info.hasCapability(IVibrator.CAP_FREQUENCY_CONTROL));
+    }
+
+    /**
+     * Asserts that the frequency profile is empty, and therefore frequency control isn't supported.
+     */
+    private void assertEmptyFrequencyProfileAndControl(VibratorInfo info) {
+        assertTrue(info.getFrequencyProfile().isEmpty());
+        assertEquals(false, info.hasCapability(IVibrator.CAP_FREQUENCY_CONTROL));
+    }
+}
diff --git a/core/tests/vibrator/src/android/os/vibrator/VibratorInfoFactoryTest.java b/core/tests/vibrator/src/android/os/vibrator/VibratorInfoFactoryTest.java
new file mode 100644
index 0000000..df4822f
--- /dev/null
+++ b/core/tests/vibrator/src/android/os/vibrator/VibratorInfoFactoryTest.java
@@ -0,0 +1,130 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.os.vibrator;
+
+import static junit.framework.Assert.assertTrue;
+import static junit.framework.TestCase.assertEquals;
+
+import android.hardware.vibrator.IVibrator;
+import android.os.VibrationEffect;
+import android.os.VibratorInfo;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+@RunWith(JUnit4.class)
+public class VibratorInfoFactoryTest {
+
+    @Test
+    public void testCreatedInfo_hasTheRequestedId() {
+        // Empty info list.
+        VibratorInfo infoFromEmptyInfos =
+                VibratorInfoFactory.create(/* id= */ 3, new VibratorInfo[] {});
+        VibratorInfo info1 = new VibratorInfo.Builder(/* id= */ 1)
+                .setSupportedEffects(VibrationEffect.EFFECT_CLICK)
+                .build();
+        VibratorInfo info2 = new VibratorInfo.Builder(/* id= */ 2)
+                .setCapabilities(IVibrator.CAP_COMPOSE_EFFECTS)
+                .setSupportedPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK, 10)
+                .build();
+        VibratorInfo infoFromOneInfo =
+                VibratorInfoFactory.create(/* id= */ -1, new VibratorInfo[] {info1});
+        VibratorInfo infoFromTwoInfos =
+                VibratorInfoFactory.create(/* id= */ -3, new VibratorInfo[] {info1, info2});
+
+        assertEquals(3, infoFromEmptyInfos.getId());
+        assertEquals(-1, infoFromOneInfo.getId());
+        assertEquals(-3, infoFromTwoInfos.getId());
+    }
+
+    @Test
+    public void testCreatedInfo_fromEmptyVibratorInfos_returnsEmptyVibratorInfo() {
+        VibratorInfo info = VibratorInfoFactory.create(/* id= */ 2, new VibratorInfo[] {});
+
+        assertEqualContent(VibratorInfo.EMPTY_VIBRATOR_INFO, info);
+    }
+
+    @Test
+    public void testCreatedInfo_fromSingleVibratorInfo_hasEqualContent() {
+        VibratorInfo info = new VibratorInfo.Builder(/* id= */ 2)
+                .setCapabilities(IVibrator.CAP_COMPOSE_EFFECTS | IVibrator.CAP_FREQUENCY_CONTROL)
+                .setSupportedEffects(VibrationEffect.EFFECT_TICK, VibrationEffect.EFFECT_THUD)
+                .setSupportedPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK, 20)
+                .setSupportedPrimitive(VibrationEffect.Composition.PRIMITIVE_TICK, 30)
+                .build();
+
+        VibratorInfo createdInfo =
+                VibratorInfoFactory.create(/* id= */ -1, new VibratorInfo[] {info});
+
+        assertEqualContent(info, createdInfo);
+    }
+
+    @Test
+    public void testCreatedInfo_hasEqualContentRegardlessOfSourceInfoOrder() {
+        VibratorInfo info1 = new VibratorInfo.Builder(/* id= */ 1)
+                .setCapabilities(IVibrator.CAP_FREQUENCY_CONTROL)
+                .setSupportedEffects(VibrationEffect.EFFECT_CLICK)
+                .build();
+        VibratorInfo info2 = new VibratorInfo.Builder(/* id= */ 2)
+                .setCapabilities(IVibrator.CAP_COMPOSE_EFFECTS)
+                .setSupportedPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK, 10)
+                .build();
+
+        assertEqualContent(
+                VibratorInfoFactory.create(/* id= */ -1, new VibratorInfo[] {info1, info2}),
+                VibratorInfoFactory.create(/* id= */ -1, new VibratorInfo[] {info2, info1}));
+    }
+
+    @Test
+    public void testCreatedInfoContents() {
+        VibratorInfo info1 = new VibratorInfo.Builder(/* id= */ -1)
+                .setCapabilities(IVibrator.CAP_COMPOSE_EFFECTS | IVibrator.CAP_FREQUENCY_CONTROL)
+                .setSupportedEffects(VibrationEffect.EFFECT_CLICK, VibrationEffect.EFFECT_POP)
+                .setSupportedPrimitive(VibrationEffect.Composition.PRIMITIVE_THUD, 5)
+                .build();
+        VibratorInfo info2 = new VibratorInfo.Builder(/* id= */ -2)
+                .setCapabilities(IVibrator.CAP_COMPOSE_EFFECTS | IVibrator.CAP_AMPLITUDE_CONTROL)
+                .setSupportedEffects(VibrationEffect.EFFECT_POP, VibrationEffect.EFFECT_THUD)
+                .setSupportedPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK, 10)
+                .setSupportedPrimitive(VibrationEffect.Composition.PRIMITIVE_THUD, 20)
+                .build();
+        VibratorInfo info3 = new VibratorInfo.Builder(/* id= */ -3)
+                .setCapabilities(IVibrator.CAP_AMPLITUDE_CONTROL)
+                .build();
+
+        assertEquals(
+                new VibratorInfo.Builder(/* id= */ 3)
+                        .setCapabilities(IVibrator.CAP_COMPOSE_EFFECTS)
+                        .setSupportedEffects(VibrationEffect.EFFECT_POP)
+                        .setSupportedPrimitive(VibrationEffect.Composition.PRIMITIVE_THUD, 20)
+                        .build(),
+                VibratorInfoFactory.create(/* id= */ 3, new VibratorInfo[] {info1, info2}));
+        assertEquals(
+                new VibratorInfo.Builder(/* id= */ 3)
+                        .setCapabilities(IVibrator.CAP_AMPLITUDE_CONTROL)
+                        .build(),
+                VibratorInfoFactory.create(/* id= */ 3, new VibratorInfo[] {info2, info3}));
+        assertEquals(
+                new VibratorInfo.Builder(/* id= */ 3).build(),
+                VibratorInfoFactory.create(/* id= */ 3, new VibratorInfo[] {info1, info3}));
+    }
+
+    private static void assertEqualContent(VibratorInfo info1, VibratorInfo info2) {
+        assertTrue(info1.equalContent(info2));
+    }
+}
