diff --git a/libs/WindowManager/Shell/Android.bp b/libs/WindowManager/Shell/Android.bp
index 5ad144d..45540e0 100644
--- a/libs/WindowManager/Shell/Android.bp
+++ b/libs/WindowManager/Shell/Android.bp
@@ -175,3 +175,74 @@
     plugins: ["dagger2-compiler"],
     use_resource_processor: true,
 }
+
+android_app {
+    name: "WindowManagerShellRobolectric",
+    platform_apis: true,
+    static_libs: [
+        "WindowManager-Shell",
+    ],
+    manifest: "multivalentTests/AndroidManifestRobolectric.xml",
+    use_resource_processor: true,
+}
+
+android_robolectric_test {
+    name: "WMShellRobolectricTests",
+    instrumentation_for: "WindowManagerShellRobolectric",
+    upstream: true,
+    java_resource_dirs: [
+        "multivalentTests/robolectric/config",
+    ],
+    srcs: [
+        "multivalentTests/src/**/*.kt",
+    ],
+    static_libs: [
+        "junit",
+        "androidx.test.runner",
+        "androidx.test.rules",
+        "androidx.test.ext.junit",
+        "mockito-robolectric-prebuilt",
+        "mockito-kotlin2",
+        "truth",
+    ],
+}
+
+android_test {
+    name: "WMShellMultivalentTestsOnDevice",
+    srcs: [
+        "multivalentTests/src/**/*.kt",
+    ],
+    static_libs: [
+        "WindowManager-Shell",
+        "junit",
+        "androidx.test.runner",
+        "androidx.test.rules",
+        "androidx.test.ext.junit",
+        "frameworks-base-testutils",
+        "mockito-kotlin2",
+        "mockito-target-extended-minus-junit4",
+        "truth",
+        "platform-test-annotations",
+        "platform-test-rules",
+    ],
+    libs: [
+        "android.test.base",
+        "android.test.runner",
+    ],
+    jni_libs: [
+        "libdexmakerjvmtiagent",
+        "libstaticjvmtiagent",
+    ],
+    kotlincflags: ["-Xjvm-default=all"],
+    optimize: {
+        enabled: false,
+    },
+    test_suites: ["device-tests"],
+    platform_apis: true,
+    certificate: "platform",
+    aaptflags: [
+        "--extra-packages",
+        "com.android.wm.shell",
+    ],
+    manifest: "multivalentTests/AndroidManifest.xml",
+}
diff --git a/libs/WindowManager/Shell/multivalentTests/AndroidManifest.xml b/libs/WindowManager/Shell/multivalentTests/AndroidManifest.xml
new file mode 100644
index 0000000..f8f8338
--- /dev/null
+++ b/libs/WindowManager/Shell/multivalentTests/AndroidManifest.xml
@@ -0,0 +1,13 @@
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.android.wm.shell.multivalenttests">
+
+    <application android:debuggable="true" android:supportsRtl="true" >
+        <uses-library android:name="android.test.runner" />
+    </application>
+
+    <instrumentation
+        android:name="androidx.test.runner.AndroidJUnitRunner"
+        android:label="Multivalent tests for WindowManager-Shell"
+        android:targetPackage="com.android.wm.shell.multivalenttests">
+    </instrumentation>
+</manifest>
diff --git a/libs/WindowManager/Shell/multivalentTests/AndroidManifestRobolectric.xml b/libs/WindowManager/Shell/multivalentTests/AndroidManifestRobolectric.xml
new file mode 100644
index 0000000..ffcd7d4
--- /dev/null
+++ b/libs/WindowManager/Shell/multivalentTests/AndroidManifestRobolectric.xml
@@ -0,0 +1,3 @@
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.android.wm.shell.multivalenttests">
+</manifest>
diff --git a/libs/WindowManager/Shell/multivalentTests/AndroidTest.xml b/libs/WindowManager/Shell/multivalentTests/AndroidTest.xml
new file mode 100644
index 0000000..36fe8ec
--- /dev/null
+++ b/libs/WindowManager/Shell/multivalentTests/AndroidTest.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 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.
+-->
+<configuration description="Runs Tests for WindowManagerShellLib">
+    <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <option name="install-arg" value="-t" />
+        <option name="test-file-name" value="WMShellMultivalentTestsOnDevice.apk" />
+    </target_preparer>
+
+    <option name="test-suite-tag" value="apct" />
+    <option name="test-suite-tag" value="framework-base-presubmit" />
+    <option name="test-tag" value="WMShellMultivalentTestsOnDevice" />
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <option name="package" value="com.android.wm.shell.multivalenttests" />
+        <option name="runner" value="androidx.test.runner.AndroidJUnitRunner" />
+        <option name="hidden-api-checks" value="false"/>
+    </test>
+</configuration>
diff --git a/libs/WindowManager/Shell/multivalentTests/robolectric/config/robolectric.properties b/libs/WindowManager/Shell/multivalentTests/robolectric/config/robolectric.properties
new file mode 100644
index 0000000..7a0527c
--- /dev/null
+++ b/libs/WindowManager/Shell/multivalentTests/robolectric/config/robolectric.properties
@@ -0,0 +1,2 @@
+sdk=NEWEST_SDK
+
diff --git a/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/BubblePositionerTest.kt b/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/BubblePositionerTest.kt
new file mode 100644
index 0000000..ea7c6ed
--- /dev/null
+++ b/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/BubblePositionerTest.kt
@@ -0,0 +1,481 @@
+/*
+ * Copyright (C) 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 com.android.wm.shell.bubbles
+
+import android.content.Context
+import android.content.Intent
+import android.content.pm.ShortcutInfo
+import android.graphics.Insets
+import android.graphics.PointF
+import android.graphics.Rect
+import android.os.UserHandle
+import android.view.WindowManager
+import androidx.test.core.app.ApplicationProvider
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.wm.shell.R
+import com.android.wm.shell.bubbles.BubblePositioner.MAX_HEIGHT
+import com.google.common.truth.Truth.assertThat
+import com.google.common.util.concurrent.MoreExecutors.directExecutor
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+
+/** Tests operations and the resulting state managed by [BubblePositioner]. */
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class BubblePositionerTest {
+
+    private lateinit var positioner: BubblePositioner
+    private val context = ApplicationProvider.getApplicationContext<Context>()
+    private val defaultDeviceConfig =
+        DeviceConfig(
+            windowBounds = Rect(0, 0, 1000, 2000),
+            isLargeScreen = false,
+            isSmallTablet = false,
+            isLandscape = false,
+            isRtl = false,
+            insets = Insets.of(0, 0, 0, 0)
+        )
+
+    @Before
+    fun setUp() {
+        val windowManager = context.getSystemService(WindowManager::class.java)
+        positioner = BubblePositioner(context, windowManager)
+    }
+
+    @Test
+    fun testUpdate() {
+        val insets = Insets.of(10, 20, 5, 15)
+        val screenBounds = Rect(0, 0, 1000, 1200)
+        val availableRect = Rect(screenBounds)
+        availableRect.inset(insets)
+        positioner.update(defaultDeviceConfig.copy(insets = insets, windowBounds = screenBounds))
+        assertThat(positioner.availableRect).isEqualTo(availableRect)
+        assertThat(positioner.isLandscape).isFalse()
+        assertThat(positioner.isLargeScreen).isFalse()
+        assertThat(positioner.insets).isEqualTo(insets)
+    }
+
+    @Test
+    fun testShowBubblesVertically_phonePortrait() {
+        positioner.update(defaultDeviceConfig)
+        assertThat(positioner.showBubblesVertically()).isFalse()
+    }
+
+    @Test
+    fun testShowBubblesVertically_phoneLandscape() {
+        positioner.update(defaultDeviceConfig.copy(isLandscape = true))
+        assertThat(positioner.isLandscape).isTrue()
+        assertThat(positioner.showBubblesVertically()).isTrue()
+    }
+
+    @Test
+    fun testShowBubblesVertically_tablet() {
+        positioner.update(defaultDeviceConfig.copy(isLargeScreen = true))
+        assertThat(positioner.showBubblesVertically()).isTrue()
+    }
+
+    /** If a resting position hasn't been set, calling it will return the default position. */
+    @Test
+    fun testGetRestingPosition_returnsDefaultPosition() {
+        positioner.update(defaultDeviceConfig)
+        val restingPosition = positioner.getRestingPosition()
+        val defaultPosition = positioner.defaultStartPosition
+        assertThat(restingPosition).isEqualTo(defaultPosition)
+    }
+
+    /** If a resting position has been set, it'll return that instead of the default position. */
+    @Test
+    fun testGetRestingPosition_returnsRestingPosition() {
+        positioner.update(defaultDeviceConfig)
+        val restingPosition = PointF(100f, 100f)
+        positioner.restingPosition = restingPosition
+        assertThat(positioner.getRestingPosition()).isEqualTo(restingPosition)
+    }
+
+    /** Test that the default resting position on phone is in upper left. */
+    @Test
+    fun testGetRestingPosition_bubble_onPhone() {
+        positioner.update(defaultDeviceConfig)
+        val allowableStackRegion = positioner.getAllowableStackPositionRegion(1 /* bubbleCount */)
+        val restingPosition = positioner.getRestingPosition()
+        assertThat(restingPosition.x).isEqualTo(allowableStackRegion.left)
+        assertThat(restingPosition.y).isEqualTo(defaultYPosition)
+    }
+
+    @Test
+    fun testGetRestingPosition_bubble_onPhone_RTL() {
+        positioner.update(defaultDeviceConfig.copy(isRtl = true))
+        val allowableStackRegion = positioner.getAllowableStackPositionRegion(1 /* bubbleCount */)
+        val restingPosition = positioner.getRestingPosition()
+        assertThat(restingPosition.x).isEqualTo(allowableStackRegion.right)
+        assertThat(restingPosition.y).isEqualTo(defaultYPosition)
+    }
+
+    /** Test that the default resting position on tablet is middle left. */
+    @Test
+    fun testGetRestingPosition_chatBubble_onTablet() {
+        positioner.update(defaultDeviceConfig.copy(isLargeScreen = true))
+        val allowableStackRegion = positioner.getAllowableStackPositionRegion(1 /* bubbleCount */)
+        val restingPosition = positioner.getRestingPosition()
+        assertThat(restingPosition.x).isEqualTo(allowableStackRegion.left)
+        assertThat(restingPosition.y).isEqualTo(defaultYPosition)
+    }
+
+    @Test
+    fun testGetRestingPosition_chatBubble_onTablet_RTL() {
+        positioner.update(defaultDeviceConfig.copy(isLargeScreen = true, isRtl = true))
+        val allowableStackRegion = positioner.getAllowableStackPositionRegion(1 /* bubbleCount */)
+        val restingPosition = positioner.getRestingPosition()
+        assertThat(restingPosition.x).isEqualTo(allowableStackRegion.right)
+        assertThat(restingPosition.y).isEqualTo(defaultYPosition)
+    }
+
+    /** Test that the default resting position on tablet is middle right. */
+    @Test
+    fun testGetDefaultPosition_appBubble_onTablet() {
+        positioner.update(defaultDeviceConfig.copy(isLargeScreen = true))
+        val allowableStackRegion = positioner.getAllowableStackPositionRegion(1 /* bubbleCount */)
+        val startPosition = positioner.getDefaultStartPosition(true /* isAppBubble */)
+        assertThat(startPosition.x).isEqualTo(allowableStackRegion.right)
+        assertThat(startPosition.y).isEqualTo(defaultYPosition)
+    }
+
+    @Test
+    fun testGetRestingPosition_appBubble_onTablet_RTL() {
+        positioner.update(defaultDeviceConfig.copy(isLargeScreen = true, isRtl = true))
+        val allowableStackRegion = positioner.getAllowableStackPositionRegion(1 /* bubbleCount */)
+        val startPosition = positioner.getDefaultStartPosition(true /* isAppBubble */)
+        assertThat(startPosition.x).isEqualTo(allowableStackRegion.left)
+        assertThat(startPosition.y).isEqualTo(defaultYPosition)
+    }
+
+    @Test
+    fun testHasUserModifiedDefaultPosition_false() {
+        positioner.update(defaultDeviceConfig.copy(isLargeScreen = true, isRtl = true))
+        assertThat(positioner.hasUserModifiedDefaultPosition()).isFalse()
+        positioner.restingPosition = positioner.defaultStartPosition
+        assertThat(positioner.hasUserModifiedDefaultPosition()).isFalse()
+    }
+
+    @Test
+    fun testHasUserModifiedDefaultPosition_true() {
+        positioner.update(defaultDeviceConfig.copy(isLargeScreen = true, isRtl = true))
+        assertThat(positioner.hasUserModifiedDefaultPosition()).isFalse()
+        positioner.restingPosition = PointF(0f, 100f)
+        assertThat(positioner.hasUserModifiedDefaultPosition()).isTrue()
+    }
+
+    @Test
+    fun testGetExpandedViewHeight_max() {
+        val deviceConfig =
+            defaultDeviceConfig.copy(
+                isLargeScreen = true,
+                insets = Insets.of(10, 20, 5, 15),
+                windowBounds = Rect(0, 0, 1800, 2600)
+            )
+        positioner.update(deviceConfig)
+        val intent = Intent(Intent.ACTION_VIEW).setPackage(context.packageName)
+        val bubble = Bubble.createAppBubble(intent, UserHandle(1), null, directExecutor())
+
+        assertThat(positioner.getExpandedViewHeight(bubble)).isEqualTo(MAX_HEIGHT)
+    }
+
+    @Test
+    fun testGetExpandedViewHeight_customHeight_valid() {
+        val deviceConfig =
+            defaultDeviceConfig.copy(
+                isLargeScreen = true,
+                insets = Insets.of(10, 20, 5, 15),
+                windowBounds = Rect(0, 0, 1800, 2600)
+            )
+        positioner.update(deviceConfig)
+        val minHeight =
+            context.resources.getDimensionPixelSize(R.dimen.bubble_expanded_default_height)
+        val bubble =
+            Bubble(
+                "key",
+                ShortcutInfo.Builder(context, "id").build(),
+                minHeight + 100 /* desiredHeight */,
+                0 /* desiredHeightResId */,
+                "title",
+                0 /* taskId */,
+                null /* locus */,
+                true /* isDismissable */,
+                directExecutor()) {}
+
+        // Ensure the height is the same as the desired value
+        assertThat(positioner.getExpandedViewHeight(bubble))
+            .isEqualTo(bubble.getDesiredHeight(context))
+    }
+
+    @Test
+    fun testGetExpandedViewHeight_customHeight_tooSmall() {
+        val deviceConfig =
+            defaultDeviceConfig.copy(
+                isLargeScreen = true,
+                insets = Insets.of(10, 20, 5, 15),
+                windowBounds = Rect(0, 0, 1800, 2600)
+            )
+        positioner.update(deviceConfig)
+
+        val bubble =
+            Bubble(
+                "key",
+                ShortcutInfo.Builder(context, "id").build(),
+                10 /* desiredHeight */,
+                0 /* desiredHeightResId */,
+                "title",
+                0 /* taskId */,
+                null /* locus */,
+                true /* isDismissable */,
+                directExecutor()) {}
+
+        // Ensure the height is the same as the desired value
+        val minHeight =
+            context.resources.getDimensionPixelSize(R.dimen.bubble_expanded_default_height)
+        assertThat(positioner.getExpandedViewHeight(bubble)).isEqualTo(minHeight)
+    }
+
+    @Test
+    fun testGetMaxExpandedViewHeight_onLargeTablet() {
+        val deviceConfig =
+            defaultDeviceConfig.copy(
+                isLargeScreen = true,
+                insets = Insets.of(10, 20, 5, 15),
+                windowBounds = Rect(0, 0, 1800, 2600)
+            )
+        positioner.update(deviceConfig)
+
+        val manageButtonHeight =
+            context.resources.getDimensionPixelSize(R.dimen.bubble_manage_button_height)
+        val pointerWidth = context.resources.getDimensionPixelSize(R.dimen.bubble_pointer_width)
+        val expandedViewPadding =
+            context.resources.getDimensionPixelSize(R.dimen.bubble_expanded_view_padding)
+        val expectedHeight =
+            1800 - 2 * 20 - manageButtonHeight - pointerWidth - expandedViewPadding * 2
+        assertThat(positioner.getMaxExpandedViewHeight(false /* isOverflow */))
+            .isEqualTo(expectedHeight)
+    }
+
+    @Test
+    fun testAreBubblesBottomAligned_largeScreen_true() {
+        val deviceConfig =
+            defaultDeviceConfig.copy(
+                isLargeScreen = true,
+                insets = Insets.of(10, 20, 5, 15),
+                windowBounds = Rect(0, 0, 1800, 2600)
+            )
+        positioner.update(deviceConfig)
+
+        assertThat(positioner.areBubblesBottomAligned()).isTrue()
+    }
+
+    @Test
+    fun testAreBubblesBottomAligned_largeScreen_landscape_false() {
+        val deviceConfig =
+            defaultDeviceConfig.copy(
+                isLargeScreen = true,
+                isLandscape = true,
+                insets = Insets.of(10, 20, 5, 15),
+                windowBounds = Rect(0, 0, 1800, 2600)
+            )
+        positioner.update(deviceConfig)
+
+        assertThat(positioner.areBubblesBottomAligned()).isFalse()
+    }
+
+    @Test
+    fun testAreBubblesBottomAligned_smallTablet_false() {
+        val deviceConfig =
+            defaultDeviceConfig.copy(
+                isLargeScreen = true,
+                isSmallTablet = true,
+                insets = Insets.of(10, 20, 5, 15),
+                windowBounds = Rect(0, 0, 1800, 2600)
+            )
+        positioner.update(deviceConfig)
+
+        assertThat(positioner.areBubblesBottomAligned()).isFalse()
+    }
+
+    @Test
+    fun testAreBubblesBottomAligned_phone_false() {
+        val deviceConfig =
+            defaultDeviceConfig.copy(
+                insets = Insets.of(10, 20, 5, 15),
+                windowBounds = Rect(0, 0, 1800, 2600)
+            )
+        positioner.update(deviceConfig)
+
+        assertThat(positioner.areBubblesBottomAligned()).isFalse()
+    }
+
+    @Test
+    fun testExpandedViewY_phoneLandscape() {
+        val deviceConfig =
+            defaultDeviceConfig.copy(
+                isLandscape = true,
+                insets = Insets.of(10, 20, 5, 15),
+                windowBounds = Rect(0, 0, 1800, 2600)
+            )
+        positioner.update(deviceConfig)
+
+        val intent = Intent(Intent.ACTION_VIEW).setPackage(context.packageName)
+        val bubble = Bubble.createAppBubble(intent, UserHandle(1), null, directExecutor())
+
+        // This bubble will have max height so it'll always be top aligned
+        assertThat(positioner.getExpandedViewY(bubble, 0f /* bubblePosition */))
+            .isEqualTo(positioner.getExpandedViewYTopAligned())
+    }
+
+    @Test
+    fun testExpandedViewY_phonePortrait() {
+        val deviceConfig =
+            defaultDeviceConfig.copy(
+                insets = Insets.of(10, 20, 5, 15),
+                windowBounds = Rect(0, 0, 1800, 2600)
+            )
+        positioner.update(deviceConfig)
+
+        val intent = Intent(Intent.ACTION_VIEW).setPackage(context.packageName)
+        val bubble = Bubble.createAppBubble(intent, UserHandle(1), null, directExecutor())
+
+        // Always top aligned in phone portrait
+        assertThat(positioner.getExpandedViewY(bubble, 0f /* bubblePosition */))
+            .isEqualTo(positioner.getExpandedViewYTopAligned())
+    }
+
+    @Test
+    fun testExpandedViewY_smallTabletLandscape() {
+        val deviceConfig =
+            defaultDeviceConfig.copy(
+                isSmallTablet = true,
+                isLandscape = true,
+                insets = Insets.of(10, 20, 5, 15),
+                windowBounds = Rect(0, 0, 1800, 2600)
+            )
+        positioner.update(deviceConfig)
+
+        val intent = Intent(Intent.ACTION_VIEW).setPackage(context.packageName)
+        val bubble = Bubble.createAppBubble(intent, UserHandle(1), null, directExecutor())
+
+        // This bubble will have max height which is always top aligned on small tablets
+        assertThat(positioner.getExpandedViewY(bubble, 0f /* bubblePosition */))
+            .isEqualTo(positioner.getExpandedViewYTopAligned())
+    }
+
+    @Test
+    fun testExpandedViewY_smallTabletPortrait() {
+        val deviceConfig =
+            defaultDeviceConfig.copy(
+                isSmallTablet = true,
+                insets = Insets.of(10, 20, 5, 15),
+                windowBounds = Rect(0, 0, 1800, 2600)
+            )
+        positioner.update(deviceConfig)
+
+        val intent = Intent(Intent.ACTION_VIEW).setPackage(context.packageName)
+        val bubble = Bubble.createAppBubble(intent, UserHandle(1), null, directExecutor())
+
+        // This bubble will have max height which is always top aligned on small tablets
+        assertThat(positioner.getExpandedViewY(bubble, 0f /* bubblePosition */))
+            .isEqualTo(positioner.getExpandedViewYTopAligned())
+    }
+
+    @Test
+    fun testExpandedViewY_largeScreenLandscape() {
+        val deviceConfig =
+            defaultDeviceConfig.copy(
+                isLargeScreen = true,
+                isLandscape = true,
+                insets = Insets.of(10, 20, 5, 15),
+                windowBounds = Rect(0, 0, 1800, 2600)
+            )
+        positioner.update(deviceConfig)
+
+        val intent = Intent(Intent.ACTION_VIEW).setPackage(context.packageName)
+        val bubble = Bubble.createAppBubble(intent, UserHandle(1), null, directExecutor())
+
+        // This bubble will have max height which is always top aligned on landscape, large tablet
+        assertThat(positioner.getExpandedViewY(bubble, 0f /* bubblePosition */))
+            .isEqualTo(positioner.getExpandedViewYTopAligned())
+    }
+
+    @Test
+    fun testExpandedViewY_largeScreenPortrait() {
+        val deviceConfig =
+            defaultDeviceConfig.copy(
+                isLargeScreen = true,
+                insets = Insets.of(10, 20, 5, 15),
+                windowBounds = Rect(0, 0, 1800, 2600)
+            )
+        positioner.update(deviceConfig)
+
+        val intent = Intent(Intent.ACTION_VIEW).setPackage(context.packageName)
+        val bubble = Bubble.createAppBubble(intent, UserHandle(1), null, directExecutor())
+
+        val manageButtonHeight =
+            context.resources.getDimensionPixelSize(R.dimen.bubble_manage_button_height)
+        val manageButtonPlusMargin =
+            manageButtonHeight +
+                2 * context.resources.getDimensionPixelSize(R.dimen.bubble_manage_button_margin)
+        val pointerWidth = context.resources.getDimensionPixelSize(R.dimen.bubble_pointer_width)
+
+        val expectedExpandedViewY =
+            positioner.availableRect.bottom -
+                manageButtonPlusMargin -
+                positioner.getExpandedViewHeightForLargeScreen() -
+                pointerWidth
+
+        // Bubbles are bottom aligned on portrait, large tablet
+        assertThat(positioner.getExpandedViewY(bubble, 0f /* bubblePosition */))
+            .isEqualTo(expectedExpandedViewY)
+    }
+
+    private val defaultYPosition: Float
+        /**
+         * Calculates the Y position bubbles should be placed based on the config. Based on the
+         * calculations in [BubblePositioner.getDefaultStartPosition] and
+         * [BubbleStackView.RelativeStackPosition].
+         */
+        get() {
+            val isTablet = positioner.isLargeScreen
+
+            // On tablet the position is centered, on phone it is an offset from the top.
+            val desiredY =
+                if (isTablet) {
+                    positioner.screenRect.height() / 2f - positioner.bubbleSize / 2f
+                } else {
+                    context.resources
+                        .getDimensionPixelOffset(R.dimen.bubble_stack_starting_offset_y)
+                        .toFloat()
+                }
+            // Since we're visually centering the bubbles on tablet, use total screen height rather
+            // than the available height.
+            val height =
+                if (isTablet) {
+                    positioner.screenRect.height()
+                } else {
+                    positioner.availableRect.height()
+                }
+            val offsetPercent = (desiredY / height).coerceIn(0f, 1f)
+            val allowableStackRegion =
+                positioner.getAllowableStackPositionRegion(1 /* bubbleCount */)
+            return allowableStackRegion.top + allowableStackRegion.height() * offsetPercent
+        }
+}
diff --git a/libs/WindowManager/Shell/multivalentTestsForDevice b/libs/WindowManager/Shell/multivalentTestsForDevice
new file mode 120000
index 0000000..20ee34a
--- /dev/null
+++ b/libs/WindowManager/Shell/multivalentTestsForDevice
@@ -0,0 +1 @@
+multivalentTests
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/multivalentTestsForDeviceless b/libs/WindowManager/Shell/multivalentTestsForDeviceless
new file mode 120000
index 0000000..20ee34a
--- /dev/null
+++ b/libs/WindowManager/Shell/multivalentTestsForDeviceless
@@ -0,0 +1 @@
+multivalentTests
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubblePositionerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubblePositionerTest.java
deleted file mode 100644
index 6ebee73..0000000
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubblePositionerTest.java
+++ /dev/null
@@ -1,602 +0,0 @@
-/*
- * Copyright (C) 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 com.android.wm.shell.bubbles;
-
-import static com.android.wm.shell.bubbles.BubblePositioner.MAX_HEIGHT;
-
-import static com.google.common.truth.Truth.assertThat;
-import static com.google.common.util.concurrent.MoreExecutors.directExecutor;
-
-import static org.mockito.Mockito.mock;
-
-import android.content.Intent;
-import android.content.pm.ShortcutInfo;
-import android.graphics.Insets;
-import android.graphics.PointF;
-import android.graphics.Rect;
-import android.graphics.RectF;
-import android.os.UserHandle;
-import android.testing.AndroidTestingRunner;
-import android.view.WindowManager;
-
-import androidx.test.filters.SmallTest;
-
-import com.android.wm.shell.R;
-import com.android.wm.shell.ShellTestCase;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-/**
- * Tests operations and the resulting state managed by {@link BubblePositioner}.
- */
-@SmallTest
-@RunWith(AndroidTestingRunner.class)
-public class BubblePositionerTest extends ShellTestCase {
-
-    private BubblePositioner mPositioner;
-
-    @Before
-    public void setUp() {
-        WindowManager windowManager = mContext.getSystemService(WindowManager.class);
-        mPositioner = new BubblePositioner(mContext, windowManager);
-    }
-
-    @Test
-    public void testUpdate() {
-        Insets insets = Insets.of(10, 20, 5, 15);
-        Rect screenBounds = new Rect(0, 0, 1000, 1200);
-        Rect availableRect = new Rect(screenBounds);
-        availableRect.inset(insets);
-
-        DeviceConfig deviceConfig = new ConfigBuilder()
-                .setInsets(insets)
-                .setScreenBounds(screenBounds)
-                .build();
-        mPositioner.update(deviceConfig);
-
-        assertThat(mPositioner.getAvailableRect()).isEqualTo(availableRect);
-        assertThat(mPositioner.isLandscape()).isFalse();
-        assertThat(mPositioner.isLargeScreen()).isFalse();
-        assertThat(mPositioner.getInsets()).isEqualTo(insets);
-    }
-
-    @Test
-    public void testShowBubblesVertically_phonePortrait() {
-        DeviceConfig deviceConfig = new ConfigBuilder().build();
-        mPositioner.update(deviceConfig);
-
-        assertThat(mPositioner.showBubblesVertically()).isFalse();
-    }
-
-    @Test
-    public void testShowBubblesVertically_phoneLandscape() {
-        DeviceConfig deviceConfig = new ConfigBuilder().setLandscape().build();
-        mPositioner.update(deviceConfig);
-
-        assertThat(mPositioner.isLandscape()).isTrue();
-        assertThat(mPositioner.showBubblesVertically()).isTrue();
-    }
-
-    @Test
-    public void testShowBubblesVertically_tablet() {
-        DeviceConfig deviceConfig = new ConfigBuilder().setLargeScreen().build();
-        mPositioner.update(deviceConfig);
-
-        assertThat(mPositioner.showBubblesVertically()).isTrue();
-    }
-
-    /** If a resting position hasn't been set, calling it will return the default position. */
-    @Test
-    public void testGetRestingPosition_returnsDefaultPosition() {
-        DeviceConfig deviceConfig = new ConfigBuilder().build();
-        mPositioner.update(deviceConfig);
-
-        PointF restingPosition = mPositioner.getRestingPosition();
-        PointF defaultPosition = mPositioner.getDefaultStartPosition();
-
-        assertThat(restingPosition).isEqualTo(defaultPosition);
-    }
-
-    /** If a resting position has been set, it'll return that instead of the default position. */
-    @Test
-    public void testGetRestingPosition_returnsRestingPosition() {
-        DeviceConfig deviceConfig = new ConfigBuilder().build();
-        mPositioner.update(deviceConfig);
-
-        PointF restingPosition = new PointF(100, 100);
-        mPositioner.setRestingPosition(restingPosition);
-
-        assertThat(mPositioner.getRestingPosition()).isEqualTo(restingPosition);
-    }
-
-    /** Test that the default resting position on phone is in upper left. */
-    @Test
-    public void testGetRestingPosition_bubble_onPhone() {
-        DeviceConfig deviceConfig = new ConfigBuilder().build();
-        mPositioner.update(deviceConfig);
-
-        RectF allowableStackRegion =
-                mPositioner.getAllowableStackPositionRegion(1 /* bubbleCount */);
-        PointF restingPosition = mPositioner.getRestingPosition();
-
-        assertThat(restingPosition.x).isEqualTo(allowableStackRegion.left);
-        assertThat(restingPosition.y).isEqualTo(getDefaultYPosition());
-    }
-
-    @Test
-    public void testGetRestingPosition_bubble_onPhone_RTL() {
-        DeviceConfig deviceConfig = new ConfigBuilder().setRtl().build();
-        mPositioner.update(deviceConfig);
-
-        RectF allowableStackRegion =
-                mPositioner.getAllowableStackPositionRegion(1 /* bubbleCount */);
-        PointF restingPosition = mPositioner.getRestingPosition();
-
-        assertThat(restingPosition.x).isEqualTo(allowableStackRegion.right);
-        assertThat(restingPosition.y).isEqualTo(getDefaultYPosition());
-    }
-
-    /** Test that the default resting position on tablet is middle left. */
-    @Test
-    public void testGetRestingPosition_chatBubble_onTablet() {
-        DeviceConfig deviceConfig = new ConfigBuilder().setLargeScreen().build();
-        mPositioner.update(deviceConfig);
-
-        RectF allowableStackRegion =
-                mPositioner.getAllowableStackPositionRegion(1 /* bubbleCount */);
-        PointF restingPosition = mPositioner.getRestingPosition();
-
-        assertThat(restingPosition.x).isEqualTo(allowableStackRegion.left);
-        assertThat(restingPosition.y).isEqualTo(getDefaultYPosition());
-    }
-
-    @Test
-    public void testGetRestingPosition_chatBubble_onTablet_RTL() {
-        DeviceConfig deviceConfig = new ConfigBuilder().setLargeScreen().setRtl().build();
-        mPositioner.update(deviceConfig);
-
-        RectF allowableStackRegion =
-                mPositioner.getAllowableStackPositionRegion(1 /* bubbleCount */);
-        PointF restingPosition = mPositioner.getRestingPosition();
-
-        assertThat(restingPosition.x).isEqualTo(allowableStackRegion.right);
-        assertThat(restingPosition.y).isEqualTo(getDefaultYPosition());
-    }
-
-    /** Test that the default resting position on tablet is middle right. */
-    @Test
-    public void testGetDefaultPosition_appBubble_onTablet() {
-        DeviceConfig deviceConfig = new ConfigBuilder().setLargeScreen().build();
-        mPositioner.update(deviceConfig);
-
-        RectF allowableStackRegion =
-                mPositioner.getAllowableStackPositionRegion(1 /* bubbleCount */);
-        PointF startPosition = mPositioner.getDefaultStartPosition(true /* isAppBubble */);
-
-        assertThat(startPosition.x).isEqualTo(allowableStackRegion.right);
-        assertThat(startPosition.y).isEqualTo(getDefaultYPosition());
-    }
-
-    @Test
-    public void testGetRestingPosition_appBubble_onTablet_RTL() {
-        DeviceConfig deviceConfig = new ConfigBuilder().setLargeScreen().setRtl().build();
-        mPositioner.update(deviceConfig);
-
-        RectF allowableStackRegion =
-                mPositioner.getAllowableStackPositionRegion(1 /* bubbleCount */);
-        PointF startPosition = mPositioner.getDefaultStartPosition(true /* isAppBubble */);
-
-        assertThat(startPosition.x).isEqualTo(allowableStackRegion.left);
-        assertThat(startPosition.y).isEqualTo(getDefaultYPosition());
-    }
-
-    @Test
-    public void testHasUserModifiedDefaultPosition_false() {
-        DeviceConfig deviceConfig = new ConfigBuilder().setLargeScreen().setRtl().build();
-        mPositioner.update(deviceConfig);
-
-        assertThat(mPositioner.hasUserModifiedDefaultPosition()).isFalse();
-
-        mPositioner.setRestingPosition(mPositioner.getDefaultStartPosition());
-
-        assertThat(mPositioner.hasUserModifiedDefaultPosition()).isFalse();
-    }
-
-    @Test
-    public void testHasUserModifiedDefaultPosition_true() {
-        DeviceConfig deviceConfig = new ConfigBuilder().setLargeScreen().setRtl().build();
-        mPositioner.update(deviceConfig);
-
-        assertThat(mPositioner.hasUserModifiedDefaultPosition()).isFalse();
-
-        mPositioner.setRestingPosition(new PointF(0, 100));
-
-        assertThat(mPositioner.hasUserModifiedDefaultPosition()).isTrue();
-    }
-
-    @Test
-    public void testGetExpandedViewHeight_max() {
-        Insets insets = Insets.of(10, 20, 5, 15);
-        Rect screenBounds = new Rect(0, 0, 1800, 2600);
-
-        DeviceConfig deviceConfig = new ConfigBuilder()
-                .setLargeScreen()
-                .setInsets(insets)
-                .setScreenBounds(screenBounds)
-                .build();
-        mPositioner.update(deviceConfig);
-
-        Intent intent = new Intent(Intent.ACTION_VIEW).setPackage(mContext.getPackageName());
-        Bubble bubble = Bubble.createAppBubble(intent, new UserHandle(1), null, directExecutor());
-
-        assertThat(mPositioner.getExpandedViewHeight(bubble)).isEqualTo(MAX_HEIGHT);
-    }
-
-    @Test
-    public void testGetExpandedViewHeight_customHeight_valid() {
-        Insets insets = Insets.of(10, 20, 5, 15);
-        Rect screenBounds = new Rect(0, 0, 1800, 2600);
-
-        DeviceConfig deviceConfig = new ConfigBuilder()
-                .setLargeScreen()
-                .setInsets(insets)
-                .setScreenBounds(screenBounds)
-                .build();
-        mPositioner.update(deviceConfig);
-
-        final int minHeight = mContext.getResources().getDimensionPixelSize(
-                R.dimen.bubble_expanded_default_height);
-        Bubble bubble = new Bubble("key",
-                mock(ShortcutInfo.class),
-                minHeight + 100 /* desiredHeight */,
-                0 /* desiredHeightResId */,
-                "title",
-                0 /* taskId */,
-                null /* locus */,
-                true /* isDismissable */,
-                directExecutor(),
-                mock(Bubbles.BubbleMetadataFlagListener.class));
-
-        // Ensure the height is the same as the desired value
-        assertThat(mPositioner.getExpandedViewHeight(bubble)).isEqualTo(
-                bubble.getDesiredHeight(mContext));
-    }
-
-
-    @Test
-    public void testGetExpandedViewHeight_customHeight_tooSmall() {
-        Insets insets = Insets.of(10, 20, 5, 15);
-        Rect screenBounds = new Rect(0, 0, 1800, 2600);
-
-        DeviceConfig deviceConfig = new ConfigBuilder()
-                .setLargeScreen()
-                .setInsets(insets)
-                .setScreenBounds(screenBounds)
-                .build();
-        mPositioner.update(deviceConfig);
-
-        Bubble bubble = new Bubble("key",
-                mock(ShortcutInfo.class),
-                10 /* desiredHeight */,
-                0 /* desiredHeightResId */,
-                "title",
-                0 /* taskId */,
-                null /* locus */,
-                true /* isDismissable */,
-                directExecutor(),
-                mock(Bubbles.BubbleMetadataFlagListener.class));
-
-        // Ensure the height is the same as the minimum value
-        final int minHeight = mContext.getResources().getDimensionPixelSize(
-                R.dimen.bubble_expanded_default_height);
-        assertThat(mPositioner.getExpandedViewHeight(bubble)).isEqualTo(minHeight);
-    }
-
-    @Test
-    public void testGetMaxExpandedViewHeight_onLargeTablet() {
-        Insets insets = Insets.of(10, 20, 5, 15);
-        Rect screenBounds = new Rect(0, 0, 1800, 2600);
-
-        DeviceConfig deviceConfig = new ConfigBuilder()
-                .setLargeScreen()
-                .setInsets(insets)
-                .setScreenBounds(screenBounds)
-                .build();
-        mPositioner.update(deviceConfig);
-
-        int manageButtonHeight =
-                mContext.getResources().getDimensionPixelSize(R.dimen.bubble_manage_button_height);
-        int pointerWidth = mContext.getResources().getDimensionPixelSize(
-                R.dimen.bubble_pointer_width);
-        int expandedViewPadding = mContext.getResources().getDimensionPixelSize(R
-                .dimen.bubble_expanded_view_padding);
-        float expectedHeight = 1800 - 2 * 20 - manageButtonHeight - pointerWidth
-                - expandedViewPadding * 2;
-        assertThat(((float) mPositioner.getMaxExpandedViewHeight(false /* isOverflow */)))
-                .isWithin(0.1f).of(expectedHeight);
-    }
-
-    @Test
-    public void testAreBubblesBottomAligned_largeScreen_true() {
-        Insets insets = Insets.of(10, 20, 5, 15);
-        Rect screenBounds = new Rect(0, 0, 1800, 2600);
-
-        DeviceConfig deviceConfig = new ConfigBuilder()
-                .setLargeScreen()
-                .setInsets(insets)
-                .setScreenBounds(screenBounds)
-                .build();
-        mPositioner.update(deviceConfig);
-
-        assertThat(mPositioner.areBubblesBottomAligned()).isTrue();
-    }
-
-    @Test
-    public void testAreBubblesBottomAligned_largeScreen_false() {
-        Insets insets = Insets.of(10, 20, 5, 15);
-        Rect screenBounds = new Rect(0, 0, 1800, 2600);
-
-        DeviceConfig deviceConfig = new ConfigBuilder()
-                .setLargeScreen()
-                .setLandscape()
-                .setInsets(insets)
-                .setScreenBounds(screenBounds)
-                .build();
-        mPositioner.update(deviceConfig);
-
-        assertThat(mPositioner.areBubblesBottomAligned()).isFalse();
-    }
-
-    @Test
-    public void testAreBubblesBottomAligned_smallTablet_false() {
-        Insets insets = Insets.of(10, 20, 5, 15);
-        Rect screenBounds = new Rect(0, 0, 1800, 2600);
-
-        DeviceConfig deviceConfig = new ConfigBuilder()
-                .setLargeScreen()
-                .setSmallTablet()
-                .setInsets(insets)
-                .setScreenBounds(screenBounds)
-                .build();
-        mPositioner.update(deviceConfig);
-
-        assertThat(mPositioner.areBubblesBottomAligned()).isFalse();
-    }
-
-    @Test
-    public void testAreBubblesBottomAligned_phone_false() {
-        Insets insets = Insets.of(10, 20, 5, 15);
-        Rect screenBounds = new Rect(0, 0, 1800, 2600);
-
-        DeviceConfig deviceConfig = new ConfigBuilder()
-                .setInsets(insets)
-                .setScreenBounds(screenBounds)
-                .build();
-        mPositioner.update(deviceConfig);
-
-        assertThat(mPositioner.areBubblesBottomAligned()).isFalse();
-    }
-
-    @Test
-    public void testExpandedViewY_phoneLandscape() {
-        Insets insets = Insets.of(10, 20, 5, 15);
-        Rect screenBounds = new Rect(0, 0, 1800, 2600);
-
-        DeviceConfig deviceConfig = new ConfigBuilder()
-                .setLandscape()
-                .setInsets(insets)
-                .setScreenBounds(screenBounds)
-                .build();
-        mPositioner.update(deviceConfig);
-
-        Intent intent = new Intent(Intent.ACTION_VIEW).setPackage(mContext.getPackageName());
-        Bubble bubble = Bubble.createAppBubble(intent, new UserHandle(1), null, directExecutor());
-
-        // This bubble will have max height so it'll always be top aligned
-        assertThat(mPositioner.getExpandedViewY(bubble, 0f /* bubblePosition */))
-                .isEqualTo(mPositioner.getExpandedViewYTopAligned());
-    }
-
-    @Test
-    public void testExpandedViewY_phonePortrait() {
-        Insets insets = Insets.of(10, 20, 5, 15);
-        Rect screenBounds = new Rect(0, 0, 1800, 2600);
-
-        DeviceConfig deviceConfig = new ConfigBuilder()
-                .setInsets(insets)
-                .setScreenBounds(screenBounds)
-                .build();
-        mPositioner.update(deviceConfig);
-
-        Intent intent = new Intent(Intent.ACTION_VIEW).setPackage(mContext.getPackageName());
-        Bubble bubble = Bubble.createAppBubble(intent, new UserHandle(1), null, directExecutor());
-
-        // Always top aligned in phone portrait
-        assertThat(mPositioner.getExpandedViewY(bubble, 0f /* bubblePosition */))
-                .isEqualTo(mPositioner.getExpandedViewYTopAligned());
-    }
-
-    @Test
-    public void testExpandedViewY_smallTabletLandscape() {
-        Insets insets = Insets.of(10, 20, 5, 15);
-        Rect screenBounds = new Rect(0, 0, 1800, 2600);
-
-        DeviceConfig deviceConfig = new ConfigBuilder()
-                .setSmallTablet()
-                .setLandscape()
-                .setInsets(insets)
-                .setScreenBounds(screenBounds)
-                .build();
-        mPositioner.update(deviceConfig);
-
-        Intent intent = new Intent(Intent.ACTION_VIEW).setPackage(mContext.getPackageName());
-        Bubble bubble = Bubble.createAppBubble(intent, new UserHandle(1), null, directExecutor());
-
-        // This bubble will have max height which is always top aligned on small tablets
-        assertThat(mPositioner.getExpandedViewY(bubble, 0f /* bubblePosition */))
-                .isEqualTo(mPositioner.getExpandedViewYTopAligned());
-    }
-
-    @Test
-    public void testExpandedViewY_smallTabletPortrait() {
-        Insets insets = Insets.of(10, 20, 5, 15);
-        Rect screenBounds = new Rect(0, 0, 1800, 2600);
-
-        DeviceConfig deviceConfig = new ConfigBuilder()
-                .setSmallTablet()
-                .setInsets(insets)
-                .setScreenBounds(screenBounds)
-                .build();
-        mPositioner.update(deviceConfig);
-
-        Intent intent = new Intent(Intent.ACTION_VIEW).setPackage(mContext.getPackageName());
-        Bubble bubble = Bubble.createAppBubble(intent, new UserHandle(1), null, directExecutor());
-
-        // This bubble will have max height which is always top aligned on small tablets
-        assertThat(mPositioner.getExpandedViewY(bubble, 0f /* bubblePosition */))
-                .isEqualTo(mPositioner.getExpandedViewYTopAligned());
-    }
-
-    @Test
-    public void testExpandedViewY_largeScreenLandscape() {
-        Insets insets = Insets.of(10, 20, 5, 15);
-        Rect screenBounds = new Rect(0, 0, 1800, 2600);
-
-        DeviceConfig deviceConfig = new ConfigBuilder()
-                .setLargeScreen()
-                .setLandscape()
-                .setInsets(insets)
-                .setScreenBounds(screenBounds)
-                .build();
-        mPositioner.update(deviceConfig);
-
-        Intent intent = new Intent(Intent.ACTION_VIEW).setPackage(mContext.getPackageName());
-        Bubble bubble = Bubble.createAppBubble(intent, new UserHandle(1), null, directExecutor());
-
-        // This bubble will have max height which is always top aligned on landscape, large tablet
-        assertThat(mPositioner.getExpandedViewY(bubble, 0f /* bubblePosition */))
-                .isEqualTo(mPositioner.getExpandedViewYTopAligned());
-    }
-
-    @Test
-    public void testExpandedViewY_largeScreenPortrait() {
-        Insets insets = Insets.of(10, 20, 5, 15);
-        Rect screenBounds = new Rect(0, 0, 1800, 2600);
-
-        DeviceConfig deviceConfig = new ConfigBuilder()
-                .setLargeScreen()
-                .setInsets(insets)
-                .setScreenBounds(screenBounds)
-                .build();
-        mPositioner.update(deviceConfig);
-
-        Intent intent = new Intent(Intent.ACTION_VIEW).setPackage(mContext.getPackageName());
-        Bubble bubble = Bubble.createAppBubble(intent, new UserHandle(1), null, directExecutor());
-
-        int manageButtonHeight =
-                mContext.getResources().getDimensionPixelSize(R.dimen.bubble_manage_button_height);
-        int manageButtonPlusMargin = manageButtonHeight + 2
-                * mContext.getResources().getDimensionPixelSize(
-                        R.dimen.bubble_manage_button_margin);
-        int pointerWidth = mContext.getResources().getDimensionPixelSize(
-                R.dimen.bubble_pointer_width);
-
-        final float expectedExpandedViewY = mPositioner.getAvailableRect().bottom
-                - manageButtonPlusMargin
-                - mPositioner.getExpandedViewHeightForLargeScreen()
-                - pointerWidth;
-
-        // Bubbles are bottom aligned on portrait, large tablet
-        assertThat(mPositioner.getExpandedViewY(bubble, 0f /* bubblePosition */))
-                .isEqualTo(expectedExpandedViewY);
-    }
-
-    /**
-     * Calculates the Y position bubbles should be placed based on the config. Based on
-     * the calculations in {@link BubblePositioner#getDefaultStartPosition()} and
-     * {@link BubbleStackView.RelativeStackPosition}.
-     */
-    private float getDefaultYPosition() {
-        final boolean isTablet = mPositioner.isLargeScreen();
-
-        // On tablet the position is centered, on phone it is an offset from the top.
-        final float desiredY = isTablet
-                ? mPositioner.getScreenRect().height() / 2f - (mPositioner.getBubbleSize() / 2f)
-                : mContext.getResources().getDimensionPixelOffset(
-                        R.dimen.bubble_stack_starting_offset_y);
-        // Since we're visually centering the bubbles on tablet, use total screen height rather
-        // than the available height.
-        final float height = isTablet
-                ? mPositioner.getScreenRect().height()
-                : mPositioner.getAvailableRect().height();
-        float offsetPercent = desiredY / height;
-        offsetPercent = Math.max(0f, Math.min(1f, offsetPercent));
-        final RectF allowableStackRegion =
-                mPositioner.getAllowableStackPositionRegion(1 /* bubbleCount */);
-        return allowableStackRegion.top + allowableStackRegion.height() * offsetPercent;
-    }
-
-    /**
-     * Sets up window manager to return config values based on what you need for the test.
-     * By default it sets up a portrait phone without any insets.
-     */
-    private static class ConfigBuilder {
-        private Rect mScreenBounds = new Rect(0, 0, 1000, 2000);
-        private boolean mIsLargeScreen = false;
-        private boolean mIsSmallTablet = false;
-        private boolean mIsLandscape = false;
-        private boolean mIsRtl = false;
-        private Insets mInsets = Insets.of(0, 0, 0, 0);
-
-        public ConfigBuilder setScreenBounds(Rect screenBounds) {
-            mScreenBounds = screenBounds;
-            return this;
-        }
-
-        public ConfigBuilder setLargeScreen() {
-            mIsLargeScreen = true;
-            return this;
-        }
-
-        public ConfigBuilder setSmallTablet() {
-            mIsSmallTablet = true;
-            return this;
-        }
-
-        public ConfigBuilder setLandscape() {
-            mIsLandscape = true;
-            return this;
-        }
-
-        public ConfigBuilder setRtl() {
-            mIsRtl = true;
-            return this;
-        }
-
-        public ConfigBuilder setInsets(Insets insets) {
-            mInsets = insets;
-            return this;
-        }
-
-        private DeviceConfig build() {
-            return new DeviceConfig(mIsLargeScreen, mIsSmallTablet, mIsLandscape, mIsRtl,
-                    mScreenBounds, mInsets);
-        }
-    }
-}
