Merge "A new exception when export is unavailable" into androidx-main
diff --git a/appfunctions/appfunctions/api/current.txt b/appfunctions/appfunctions/api/current.txt
index fa4c2b4..054bdd4 100644
--- a/appfunctions/appfunctions/api/current.txt
+++ b/appfunctions/appfunctions/api/current.txt
@@ -60,6 +60,7 @@
   }
 
   public static final class AppFunctionData.Builder {
+    ctor public AppFunctionData.Builder(androidx.appfunctions.metadata.AppFunctionAllOfTypeMetadata allOfTypeMetadata, androidx.appfunctions.metadata.AppFunctionComponentsMetadata componentMetadata);
     ctor public AppFunctionData.Builder(androidx.appfunctions.metadata.AppFunctionObjectTypeMetadata objectTypeMetadata, androidx.appfunctions.metadata.AppFunctionComponentsMetadata componentMetadata);
     ctor public AppFunctionData.Builder(androidx.appfunctions.metadata.AppFunctionResponseMetadata responseMetadata, androidx.appfunctions.metadata.AppFunctionComponentsMetadata componentMetadata);
     ctor public AppFunctionData.Builder(java.util.List<androidx.appfunctions.metadata.AppFunctionParameterMetadata> parameterMetadataList, androidx.appfunctions.metadata.AppFunctionComponentsMetadata componentMetadata);
diff --git a/appfunctions/appfunctions/api/restricted_current.txt b/appfunctions/appfunctions/api/restricted_current.txt
index a954eb6..17de581 100644
--- a/appfunctions/appfunctions/api/restricted_current.txt
+++ b/appfunctions/appfunctions/api/restricted_current.txt
@@ -60,6 +60,7 @@
   }
 
   public static final class AppFunctionData.Builder {
+    ctor public AppFunctionData.Builder(androidx.appfunctions.metadata.AppFunctionAllOfTypeMetadata allOfTypeMetadata, androidx.appfunctions.metadata.AppFunctionComponentsMetadata componentMetadata);
     ctor public AppFunctionData.Builder(androidx.appfunctions.metadata.AppFunctionObjectTypeMetadata objectTypeMetadata, androidx.appfunctions.metadata.AppFunctionComponentsMetadata componentMetadata);
     ctor public AppFunctionData.Builder(androidx.appfunctions.metadata.AppFunctionResponseMetadata responseMetadata, androidx.appfunctions.metadata.AppFunctionComponentsMetadata componentMetadata);
     ctor public AppFunctionData.Builder(java.util.List<androidx.appfunctions.metadata.AppFunctionParameterMetadata> parameterMetadataList, androidx.appfunctions.metadata.AppFunctionComponentsMetadata componentMetadata);
diff --git a/appfunctions/appfunctions/src/androidTest/java/androidx/appfunctions/AppFunctionDataTest.kt b/appfunctions/appfunctions/src/androidTest/java/androidx/appfunctions/AppFunctionDataTest.kt
index f8d9888..344e5d9 100644
--- a/appfunctions/appfunctions/src/androidTest/java/androidx/appfunctions/AppFunctionDataTest.kt
+++ b/appfunctions/appfunctions/src/androidTest/java/androidx/appfunctions/AppFunctionDataTest.kt
@@ -52,6 +52,7 @@
 import kotlin.test.assertFailsWith
 import org.junit.Assume.assumeTrue
 import org.junit.Before
+import org.junit.Ignore
 import org.junit.Test
 
 @SdkSuppress(minSdkVersion = Build.VERSION_CODES.TIRAMISU)
@@ -928,6 +929,7 @@
     }
 
     @Test
+    @Ignore("b/447064745: Re-enable when the child object validation is fixed")
     fun testWrite_nestedAppFunctionData_notConformSpec() {
         val innerObjectType =
             AppFunctionObjectTypeMetadata(
@@ -967,6 +969,7 @@
     }
 
     @Test
+    @Ignore("b/447064745: Re-enable when the child object validation is fixed")
     fun testWrite_nestedListAppFunctionData_notConformSpec() {
         val innerObjectType =
             AppFunctionObjectTypeMetadata(
@@ -1400,6 +1403,96 @@
         }
     }
 
+    @Test
+    fun buildAllOfTypeObject_allRequiredField_success() {
+        val data =
+            AppFunctionData.Builder(
+                    OpenableNote.OPENABLE_NOTE_ALL_OF_TYPE_METADATA,
+                    OpenableNote.COMPONENT_METADATA,
+                )
+                .setString("title", "test")
+                .setAppFunctionData(
+                    "attachment",
+                    AppFunctionData.Builder(
+                            ATTACHMENT_OBJECT_TYPE_METADATA,
+                            AppFunctionComponentsMetadata(),
+                        )
+                        .setString("uri", "test")
+                        .build(),
+                )
+                .setPendingIntent(
+                    "intentToOpen",
+                    PendingIntent.getActivity(context, 0, Intent(), PendingIntent.FLAG_IMMUTABLE),
+                )
+                .build()
+
+        assertThat(data.getString("title")).isEqualTo("test")
+        assertThat(data.getAppFunctionData("attachment")?.getString("uri")).isEqualTo("test")
+        assertThat(data.getPendingIntent("intentToOpen")).isNotNull()
+    }
+
+    @Test
+    fun serializeAllOfTypeObject_allRequiredField_success() {
+        val data =
+            AppFunctionData.serialize(
+                OpenableNote(
+                    title = "test",
+                    attachment = Attachment(uri = "test"),
+                    intentToOpen =
+                        PendingIntent.getActivity(
+                            context,
+                            0,
+                            Intent(),
+                            PendingIntent.FLAG_IMMUTABLE,
+                        ),
+                ),
+                OpenableNote::class.java,
+            )
+
+        assertThat(data.getString("title")).isEqualTo("test")
+        assertThat(data.getAppFunctionData("attachment")?.getString("uri")).isEqualTo("test")
+        assertThat(data.getPendingIntent("intentToOpen")).isNotNull()
+        // Also ensure that read validation is applied
+        assertFailsWith<IllegalArgumentException> { data.getInt("intentToOpen") }
+    }
+
+    @Test
+    fun buildAllOfTypeObject_missOriginalClassField_fail() {
+        assertFailsWith<IllegalArgumentException> {
+            AppFunctionData.Builder(
+                    OpenableNote.OPENABLE_NOTE_ALL_OF_TYPE_METADATA,
+                    OpenableNote.COMPONENT_METADATA,
+                )
+                .setString("title", "test")
+                .setPendingIntent(
+                    "intentToOpen",
+                    PendingIntent.getActivity(context, 0, Intent(), PendingIntent.FLAG_IMMUTABLE),
+                )
+                .build()
+        }
+    }
+
+    @Test
+    fun buildAllOfTypeObject_missCapabilityField_fail() {
+        assertFailsWith<IllegalArgumentException> {
+            AppFunctionData.Builder(
+                    OpenableNote.OPENABLE_NOTE_ALL_OF_TYPE_METADATA,
+                    OpenableNote.COMPONENT_METADATA,
+                )
+                .setString("title", "test")
+                .setAppFunctionData(
+                    "attachment",
+                    AppFunctionData.Builder(
+                            ATTACHMENT_OBJECT_TYPE_METADATA,
+                            AppFunctionComponentsMetadata(),
+                        )
+                        .setString("uri", "test")
+                        .build(),
+                )
+                .build()
+        }
+    }
+
     companion object {
         val TEST_OBJECT_METADATA =
             AppFunctionObjectTypeMetadata(
diff --git a/appfunctions/appfunctions/src/androidTest/java/androidx/appfunctions/SerializableTestEntities.kt b/appfunctions/appfunctions/src/androidTest/java/androidx/appfunctions/SerializableTestEntities.kt
index 9084598..8e0b6a3 100644
--- a/appfunctions/appfunctions/src/androidTest/java/androidx/appfunctions/SerializableTestEntities.kt
+++ b/appfunctions/appfunctions/src/androidTest/java/androidx/appfunctions/SerializableTestEntities.kt
@@ -16,11 +16,16 @@
 
 package androidx.appfunctions
 
+import android.app.PendingIntent
 import android.os.Build
 import androidx.annotation.RequiresApi
 import androidx.appfunctions.Attachment.Companion.ATTACHMENT_OBJECT_TYPE_METADATA
 import androidx.appfunctions.internal.AppFunctionSerializableFactory
+import androidx.appfunctions.metadata.AppFunctionAllOfTypeMetadata
+import androidx.appfunctions.metadata.AppFunctionComponentsMetadata
 import androidx.appfunctions.metadata.AppFunctionObjectTypeMetadata
+import androidx.appfunctions.metadata.AppFunctionPendingIntentTypeMetadata
+import androidx.appfunctions.metadata.AppFunctionReferenceTypeMetadata
 import androidx.appfunctions.metadata.AppFunctionStringTypeMetadata
 
 class MissingFactoryClass(val item: String)
@@ -47,13 +52,52 @@
                         "title" to AppFunctionStringTypeMetadata(isNullable = false),
                         "attachment" to ATTACHMENT_OBJECT_TYPE_METADATA,
                     ),
-                required = listOf("title"),
+                required = listOf("title", "attachment"),
                 qualifiedName = "androidx.appfunctions.Note",
                 isNullable = true,
             )
     }
 }
 
+data class OpenableNote(
+    val title: String,
+    val attachment: Attachment,
+    val intentToOpen: PendingIntent,
+) {
+    companion object {
+        val OPENABLE_NOTE_ALL_OF_TYPE_METADATA: AppFunctionAllOfTypeMetadata =
+            AppFunctionAllOfTypeMetadata(
+                qualifiedName = checkNotNull(OpenableNote::class.java.canonicalName),
+                isNullable = true,
+                matchAll =
+                    listOf(
+                        Note.NOTE_OBJECT_TYPE_METADATA,
+                        AppFunctionReferenceTypeMetadata(
+                            referenceDataType = "com.example.AppFunctionOpenable",
+                            isNullable = false,
+                        ),
+                    ),
+            )
+
+        val COMPONENT_METADATA: AppFunctionComponentsMetadata =
+            AppFunctionComponentsMetadata(
+                mapOf(
+                    "com.example.AppFunctionOpenable" to
+                        AppFunctionObjectTypeMetadata(
+                            properties =
+                                mapOf(
+                                    "intentToOpen" to
+                                        AppFunctionPendingIntentTypeMetadata(isNullable = false)
+                                ),
+                            required = listOf("intentToOpen"),
+                            qualifiedName = "com.example.AppFunctionOpenable",
+                            isNullable = true,
+                        )
+                )
+            )
+    }
+}
+
 @RequiresApi(Build.VERSION_CODES.TIRAMISU)
 class `$AttachmentFactory` : AppFunctionSerializableFactory<Attachment> {
     override fun fromAppFunctionData(appFunctionData: AppFunctionData): Attachment {
@@ -91,3 +135,30 @@
             .build()
     }
 }
+
+@RequiresApi(Build.VERSION_CODES.TIRAMISU)
+class `$OpenableNoteFactory` : AppFunctionSerializableFactory<OpenableNote> {
+    override fun fromAppFunctionData(appFunctionData: AppFunctionData): OpenableNote {
+        return OpenableNote(
+            title = checkNotNull(appFunctionData.getString("title")),
+            attachment =
+                checkNotNull(appFunctionData.getAppFunctionData("attachment"))
+                    .deserialize(Attachment::class.java),
+            intentToOpen = checkNotNull(appFunctionData.getPendingIntent("intentToOpen")),
+        )
+    }
+
+    override fun toAppFunctionData(appFunctionSerializable: OpenableNote): AppFunctionData {
+        return getAppFunctionDataBuilder("androidx.appfunctions.OpenableNote")
+            .setString("title", appFunctionSerializable.title)
+            .setAppFunctionData(
+                "attachment",
+                AppFunctionData.serialize(
+                    appFunctionSerializable.attachment,
+                    Attachment::class.java,
+                ),
+            )
+            .setPendingIntent("intentToOpen", appFunctionSerializable.intentToOpen)
+            .build()
+    }
+}
diff --git a/appfunctions/appfunctions/src/androidTest/java/androidx/appfunctions/internal/$AggregatedAppFunctionInventory_Impl.kt b/appfunctions/appfunctions/src/androidTest/java/androidx/appfunctions/internal/$AggregatedAppFunctionInventory_Impl.kt
index be0d419..b45309e 100644
--- a/appfunctions/appfunctions/src/androidTest/java/androidx/appfunctions/internal/$AggregatedAppFunctionInventory_Impl.kt
+++ b/appfunctions/appfunctions/src/androidTest/java/androidx/appfunctions/internal/$AggregatedAppFunctionInventory_Impl.kt
@@ -20,6 +20,7 @@
 import androidx.annotation.RequiresApi
 import androidx.appfunctions.Attachment.Companion.ATTACHMENT_OBJECT_TYPE_METADATA
 import androidx.appfunctions.Note.Companion.NOTE_OBJECT_TYPE_METADATA
+import androidx.appfunctions.OpenableNote
 import androidx.appfunctions.metadata.AppFunctionArrayTypeMetadata
 import androidx.appfunctions.metadata.AppFunctionComponentsMetadata
 import androidx.appfunctions.metadata.AppFunctionIntTypeMetadata
@@ -104,11 +105,16 @@
             mapOf(
                 "androidx.appfunctions.Attachment" to ATTACHMENT_OBJECT_TYPE_METADATA,
                 "androidx.appfunctions.Note" to NOTE_OBJECT_TYPE_METADATA,
+                "androidx.appfunctions.OpenableNote" to
+                    OpenableNote.OPENABLE_NOTE_ALL_OF_TYPE_METADATA,
             )
 
         val TEST_COMPONENT_METADATA =
             AppFunctionComponentsMetadata(
-                dataTypes = URI_GRANT_COMPONENT_METADATA_MAP + NOTE_COMPONENT_METADATA_MAP
+                dataTypes =
+                    URI_GRANT_COMPONENT_METADATA_MAP +
+                        NOTE_COMPONENT_METADATA_MAP +
+                        OpenableNote.COMPONENT_METADATA.dataTypes
             )
     }
 }
diff --git a/appfunctions/appfunctions/src/main/java/androidx/appfunctions/AppFunctionData.kt b/appfunctions/appfunctions/src/main/java/androidx/appfunctions/AppFunctionData.kt
index 529cd0c..ec5fcc0 100644
--- a/appfunctions/appfunctions/src/main/java/androidx/appfunctions/AppFunctionData.kt
+++ b/appfunctions/appfunctions/src/main/java/androidx/appfunctions/AppFunctionData.kt
@@ -30,6 +30,7 @@
 import androidx.annotation.WorkerThread
 import androidx.appfunctions.internal.AppFunctionSerializableFactory
 import androidx.appfunctions.internal.Constants.APP_FUNCTIONS_TAG
+import androidx.appfunctions.metadata.AppFunctionAllOfTypeMetadata
 import androidx.appfunctions.metadata.AppFunctionComponentsMetadata
 import androidx.appfunctions.metadata.AppFunctionObjectTypeMetadata
 import androidx.appfunctions.metadata.AppFunctionParameterMetadata
@@ -1054,9 +1055,8 @@
         /**
          * Constructs a [Builder] to create input data for an AppFunction execution call.
          *
-         * This constructor is used when you need to write data that will be passed as input when
-         * executing an AppFunction. The [parameterMetadataList] defines the expected input
-         * parameters for that function.
+         * The caller can use this to construct the [AppFunctionData] for
+         * [ExecuteAppFunctionRequest.functionParameters].
          *
          * @param parameterMetadataList List of [AppFunctionParameterMetadata] defining the input
          *   parameters.
@@ -1072,10 +1072,8 @@
         /**
          * Constructs a [Builder] to create [AppFunctionData] representing an object.
          *
-         * This constructor is used when you need to create [AppFunctionData] that represents an
-         * object used as either function parameters or return values, as defined by an
-         * [AppFunctionObjectTypeMetadata]. This metadata specifies the properties and their types
-         * for the object.
+         * The caller can use this to construct the [AppFunctionData] that conforms with the
+         * provided [objectTypeMetadata].
          *
          * @param objectTypeMetadata [AppFunctionObjectTypeMetadata] defining the object structure.
          * @param componentMetadata [AppFunctionComponentsMetadata] that has the shared data types.
@@ -1088,11 +1086,31 @@
         ) : this(AppFunctionDataSpec.create(objectTypeMetadata, componentMetadata))
 
         /**
+         * Constructs a [Builder] to create [AppFunctionData] representing an all-of object.
+         *
+         * The caller can use this to construct the [AppFunctionData] that conforms with the
+         * provided [allOfTypeMetadata].
+         *
+         * @param allOfTypeMetadata [AppFunctionAllOfTypeMetadata] defining the object structure.
+         * @param componentMetadata [AppFunctionComponentsMetadata] that has the shared data types.
+         * @see [AppFunctionAllOfTypeMetadata]
+         * @see [AppFunctionComponentsMetadata]
+         */
+        public constructor(
+            allOfTypeMetadata: AppFunctionAllOfTypeMetadata,
+            componentMetadata: AppFunctionComponentsMetadata,
+        ) : this(
+            AppFunctionDataSpec.create(
+                allOfTypeMetadata.getPseudoObjectTypeMetadata(componentMetadata),
+                componentMetadata,
+            )
+        )
+
+        /**
          * Constructs a [Builder] to create [AppFunctionData] representing a response.
          *
-         * This constructor is used when you need to create [AppFunctionData] that represents a
-         * response, as defined by an [AppFunctionResponseMetadata]. This metadata specifies the
-         * properties and their types for the response.
+         * The caller can use this to construct the [AppFunctionData] for
+         * [ExecuteAppFunctionResponse.Success.returnValue].
          *
          * @param responseMetadata [AppFunctionResponseMetadata] defining the response structure.
          * @param componentMetadata [AppFunctionComponentsMetadata] that has the shared data types.
diff --git a/appfunctions/appfunctions/src/main/java/androidx/appfunctions/AppFunctionDataSpec.kt b/appfunctions/appfunctions/src/main/java/androidx/appfunctions/AppFunctionDataSpec.kt
index ee984b4..5569a8c 100644
--- a/appfunctions/appfunctions/src/main/java/androidx/appfunctions/AppFunctionDataSpec.kt
+++ b/appfunctions/appfunctions/src/main/java/androidx/appfunctions/AppFunctionDataSpec.kt
@@ -97,8 +97,10 @@
      * @throws IllegalArgumentException If the [data] does not match the specification.
      */
     fun validateDataSpecMatches(data: AppFunctionData) {
-        val otherSpec = data.spec ?: return
-        require(this == otherSpec) { "$data does not match the metadata specification of $this" }
+        // TODO(b/447064745): Fix child object validation when spec is from schema inventory
+        val unused = data.spec ?: return
+        //        require(this == otherSpec) { "$data does not match the metadata specification of
+        // $this" }
     }
 
     /**
diff --git a/appfunctions/appfunctions/src/main/java/androidx/appfunctions/internal/AppFunctionSerializableFactory.kt b/appfunctions/appfunctions/src/main/java/androidx/appfunctions/internal/AppFunctionSerializableFactory.kt
index 529e235..b3f797f 100644
--- a/appfunctions/appfunctions/src/main/java/androidx/appfunctions/internal/AppFunctionSerializableFactory.kt
+++ b/appfunctions/appfunctions/src/main/java/androidx/appfunctions/internal/AppFunctionSerializableFactory.kt
@@ -21,6 +21,7 @@
 import androidx.annotation.RequiresApi
 import androidx.annotation.RestrictTo
 import androidx.appfunctions.AppFunctionData
+import androidx.appfunctions.metadata.AppFunctionAllOfTypeMetadata
 import androidx.appfunctions.metadata.AppFunctionComponentsMetadata
 import androidx.appfunctions.metadata.AppFunctionObjectTypeMetadata
 
@@ -57,13 +58,24 @@
     public fun getAppFunctionDataBuilder(qualifiedName: String): AppFunctionData.Builder {
         val componentsMetadata = getAppFunctionComponentsMetadata()
 
-        val dataTypeMetadata =
-            componentsMetadata.dataTypes[qualifiedName] as? AppFunctionObjectTypeMetadata
+        val dataTypeMetadata = componentsMetadata.dataTypes[qualifiedName]
 
         // TODO(b/447302747): Remove after resolving affected tests.
         if (dataTypeMetadata == null) return AppFunctionData.Builder(qualifiedName)
 
-        return AppFunctionData.Builder(dataTypeMetadata, componentsMetadata)
+        return when (dataTypeMetadata) {
+            is AppFunctionObjectTypeMetadata -> {
+                AppFunctionData.Builder(dataTypeMetadata, componentsMetadata)
+            }
+            is AppFunctionAllOfTypeMetadata -> {
+                AppFunctionData.Builder(dataTypeMetadata, componentsMetadata)
+            }
+            else -> {
+                throw IllegalStateException(
+                    "Unable to serialize $qualifiedName with $dataTypeMetadata"
+                )
+            }
+        }
     }
 
     /**
diff --git a/appfunctions/integration-tests/multi-modules-testapp/app/src/androidTest/AndroidManifest.xml b/appfunctions/integration-tests/multi-modules-testapp/app/src/androidTest/AndroidManifest.xml
index d904dfc..1960f7d 100644
--- a/appfunctions/integration-tests/multi-modules-testapp/app/src/androidTest/AndroidManifest.xml
+++ b/appfunctions/integration-tests/multi-modules-testapp/app/src/androidTest/AndroidManifest.xml
@@ -14,6 +14,9 @@
   limitations under the License.
   -->
 <manifest xmlns:android="http://schemas.android.com/apk/res/android">
+    <queries>
+        <package android:name="com.google.android.app.notes" />
+    </queries>
     <application
         android:name="androidx.appfunctions.integration.tests.TestApplication"
         android:supportsRtl="true">
diff --git a/appfunctions/integration-tests/multi-modules-testapp/app/src/androidTest/java/androidx/appfunctions/integration/tests/AppSearchMetadataHelper.kt b/appfunctions/integration-tests/multi-modules-testapp/app/src/androidTest/java/androidx/appfunctions/integration/tests/AppSearchMetadataHelper.kt
index 3f362ad..551e933 100644
--- a/appfunctions/integration-tests/multi-modules-testapp/app/src/androidTest/java/androidx/appfunctions/integration/tests/AppSearchMetadataHelper.kt
+++ b/appfunctions/integration-tests/multi-modules-testapp/app/src/androidTest/java/androidx/appfunctions/integration/tests/AppSearchMetadataHelper.kt
@@ -23,8 +23,8 @@
 import androidx.concurrent.futures.await
 
 internal object AppSearchMetadataHelper {
-    /** Returns function IDs that belong to the given context's package. */
-    suspend fun collectSelfFunctionIds(context: Context): Set<String> {
+    /** Returns function IDs that belong to the given [targetPackage]. */
+    suspend fun collectFunctionIds(context: Context, targetPackage: String): Set<String> {
         val functionIds = mutableSetOf<String>()
         createSearchSession(context).use { session ->
             val searchResults =
@@ -40,7 +40,7 @@
             while (nextPage.isNotEmpty()) {
                 for (result in nextPage) {
                     val packageName = result.genericDocument.getPropertyString("packageName")
-                    if (packageName != context.packageName) {
+                    if (packageName != targetPackage) {
                         continue
                     }
                     val functionId = result.genericDocument.getPropertyString("functionId")
diff --git a/appfunctions/integration-tests/multi-modules-testapp/app/src/androidTest/java/androidx/appfunctions/integration/tests/IntegrationTest.kt b/appfunctions/integration-tests/multi-modules-testapp/app/src/androidTest/java/androidx/appfunctions/integration/tests/IntegrationTest.kt
index 6094762..e22e82a 100644
--- a/appfunctions/integration-tests/multi-modules-testapp/app/src/androidTest/java/androidx/appfunctions/integration/tests/IntegrationTest.kt
+++ b/appfunctions/integration-tests/multi-modules-testapp/app/src/androidTest/java/androidx/appfunctions/integration/tests/IntegrationTest.kt
@@ -16,6 +16,13 @@
 
 package androidx.appfunctions.integration.tests
 
+import android.Manifest
+import android.app.PendingIntent
+import android.content.BroadcastReceiver
+import android.content.Context
+import android.content.Intent
+import android.content.IntentFilter
+import android.content.pm.PackageInstaller
 import android.net.Uri
 import androidx.appfunctions.AppFunctionData
 import androidx.appfunctions.AppFunctionFunctionNotFoundException
@@ -42,11 +49,15 @@
 import androidx.test.filters.LargeTest
 import androidx.test.platform.app.InstrumentationRegistry
 import com.google.common.truth.Truth.assertThat
+import java.io.InputStream
 import java.time.LocalDateTime
+import kotlin.coroutines.resumeWithException
 import kotlin.test.assertFailsWith
 import kotlin.test.assertIs
+import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.async
 import kotlinx.coroutines.flow.first
+import kotlinx.coroutines.suspendCancellableCoroutine
 import org.junit.After
 import org.junit.Assert.assertThrows
 import org.junit.Assume.assumeFalse
@@ -73,16 +84,20 @@
             // "androidx.appfunctions.integration.testapp",
             // while the app functions are defined under
             // "androidx.appfunctions.integration.testapp.test"
-            adoptShellPermissionIdentity("android.permission.EXECUTE_APP_FUNCTIONS")
+            adoptShellPermissionIdentity(
+                Manifest.permission.INSTALL_PACKAGES,
+                "android.permission.EXECUTE_APP_FUNCTIONS",
+            )
             executeShellCommand(
                 "device_config put appsearch max_allowed_app_function_doc_size_in_bytes $TEST_APP_FUNCTION_DOC_SIZE_LIMIT"
             )
         }
-        awaitAppFunctionsIndexed(FUNCTION_IDS)
+        context.awaitAppFunctionsIndexed(context.packageName, FUNCTION_IDS)
     }
 
     @After
     fun tearDown() {
+        uiAutomation.executeShellCommand("pm uninstall $ADDITIONAL_APP_PACKAGE")
         uiAutomation.dropShellPermissionIdentity()
     }
 
@@ -817,6 +832,110 @@
     }
 
     @Test
+    fun executeAppFunction_legacySchemaCreateNote_success() = doBlocking {
+        targetContext.installApk(ADDITIONAL_APK_FILE)
+        targetContext.awaitAppFunctionsIndexed(
+            ADDITIONAL_APP_PACKAGE,
+            setOf(ADDITIONAL_LEGACY_CREATE_NOTE),
+        )
+        val createNoteMetadata =
+            appFunctionManager
+                .observeAppFunctions(
+                    AppFunctionSearchSpec(packageNames = setOf(ADDITIONAL_APP_PACKAGE))
+                )
+                .first()
+                .flatMap { it.appFunctions }
+                .single()
+
+        val response =
+            appFunctionManager.executeAppFunction(
+                ExecuteAppFunctionRequest(
+                    functionIdentifier = createNoteMetadata.id,
+                    targetPackageName = createNoteMetadata.packageName,
+                    functionParameters =
+                        AppFunctionData.Builder(
+                                createNoteMetadata.parameters,
+                                createNoteMetadata.components,
+                            )
+                            .setAppFunctionData(
+                                "createNoteParams",
+                                AppFunctionData.Builder(
+                                        requireTargetObjectTypeMetadata(
+                                            "createNoteParams",
+                                            createNoteMetadata.parameters,
+                                            createNoteMetadata.components,
+                                        ),
+                                        createNoteMetadata.components,
+                                    )
+                                    .setString("title", "Test Title")
+                                    .setString("content", "Test Content")
+                                    .build(),
+                            )
+                            .build(),
+                )
+            )
+
+        assertIs<ExecuteAppFunctionResponse.Success>(response)
+        val returnValue =
+            response.returnValue.getAppFunctionData(
+                ExecuteAppFunctionResponse.Success.PROPERTY_RETURN_VALUE
+            )
+        assertThat(returnValue).isNotNull()
+        assertThat(checkNotNull(returnValue).getString("title")).isEqualTo("Test Title")
+        assertThat(returnValue.getString("content")).isEqualTo("Test Content")
+    }
+
+    @Test
+    fun executeAppFunction_legacySchemaCreateNoteSerialization_success() = doBlocking {
+        targetContext.installApk(ADDITIONAL_APK_FILE)
+        targetContext.awaitAppFunctionsIndexed(
+            ADDITIONAL_APP_PACKAGE,
+            setOf(ADDITIONAL_LEGACY_CREATE_NOTE),
+        )
+        val createNoteMetadata =
+            appFunctionManager
+                .observeAppFunctions(
+                    AppFunctionSearchSpec(packageNames = setOf(ADDITIONAL_APP_PACKAGE))
+                )
+                .first()
+                .flatMap { it.appFunctions }
+                .single()
+        val createNoteParams =
+            LegacyCreateNoteParams(title = "Test Title", content = "Test Content")
+
+        val response =
+            appFunctionManager.executeAppFunction(
+                ExecuteAppFunctionRequest(
+                    functionIdentifier = createNoteMetadata.id,
+                    targetPackageName = createNoteMetadata.packageName,
+                    functionParameters =
+                        AppFunctionData.Builder(
+                                createNoteMetadata.parameters,
+                                createNoteMetadata.components,
+                            )
+                            .setAppFunctionData(
+                                "createNoteParams",
+                                AppFunctionData.serialize(
+                                    createNoteParams,
+                                    LegacyCreateNoteParams::class.java,
+                                ),
+                            )
+                            .build(),
+                )
+            )
+
+        assertIs<ExecuteAppFunctionResponse.Success>(response)
+        val returnValue =
+            response.returnValue.getAppFunctionData(
+                ExecuteAppFunctionResponse.Success.PROPERTY_RETURN_VALUE
+            )
+        assertThat(returnValue).isNotNull()
+        val note = checkNotNull(returnValue).deserialize(LegacyNote::class.java)
+        assertThat(note.title).isEqualTo("Test Title")
+        assertThat(note.content).isEqualTo("Test Content")
+    }
+
+    @Test
     fun executeAppFunction_schemaCreateNote_success() = doBlocking {
         val createNoteMetadata =
             appFunctionManager
@@ -872,6 +991,59 @@
     }
 
     @Test
+    fun executeAppFunction_schemaCreateNoteSerialization_success() = doBlocking {
+        val createNoteMetadata =
+            appFunctionManager
+                .observeAppFunctions(
+                    AppFunctionSearchSpec(
+                        packageNames = setOf(context.packageName),
+                        schemaCategory = "myNotes",
+                        schemaName = "createNote",
+                        minSchemaVersion = 2,
+                    )
+                )
+                .first()
+                .flatMap { it.appFunctions }
+                .single()
+        val parameters =
+            CreateNoteAppFunction.Parameters(
+                title = "Test Title",
+                content = "Some valid content",
+                attachments = emptyList(),
+                groupId = "testGroupId",
+                externalUuid = "testExternalUuid",
+            )
+        val request =
+            ExecuteAppFunctionRequest(
+                functionIdentifier = createNoteMetadata.id,
+                targetPackageName = createNoteMetadata.packageName,
+                functionParameters =
+                    AppFunctionData.Builder(
+                            createNoteMetadata.parameters,
+                            createNoteMetadata.components,
+                        )
+                        .setAppFunctionData(
+                            "parameters",
+                            AppFunctionData.serialize(
+                                parameters,
+                                CreateNoteAppFunction.Parameters::class.java,
+                            ),
+                        )
+                        .build(),
+            )
+
+        val response = appFunctionManager.executeAppFunction(request)
+
+        assertIs<ExecuteAppFunctionResponse.Success>(response)
+        val resultNote =
+            response.returnValue
+                .getAppFunctionData(ExecuteAppFunctionResponse.Success.PROPERTY_RETURN_VALUE)
+                ?.getAppFunctionData("createdNote")
+        assertThat(resultNote?.getString("id")).isEqualTo("testId")
+        assertThat(resultNote?.getString("title")).isEqualTo("Test Title")
+    }
+
+    @Test
     fun executeAppFunction_schemaCreateNote_readInvalidFieldFail() = doBlocking {
         val createNoteMetadata =
             appFunctionManager
@@ -1500,14 +1672,92 @@
             .single { it.id == id }
     }
 
-    private suspend fun awaitAppFunctionsIndexed(expectedFunctionIds: Set<String>) {
+    private suspend fun Context.awaitAppFunctionsIndexed(
+        targetPackage: String,
+        expectedFunctionIds: Set<String>,
+    ) {
         retryAssert {
-            val functionIds = AppSearchMetadataHelper.collectSelfFunctionIds(context)
+            val functionIds =
+                AppSearchMetadataHelper.collectFunctionIds(
+                    this@awaitAppFunctionsIndexed,
+                    targetPackage,
+                )
             assertThat(functionIds).containsAtLeastElementsIn(expectedFunctionIds)
         }
     }
 
+    private suspend fun Context.installApk(apk: String) {
+        val installer = packageManager.packageInstaller
+        val sessionParams =
+            PackageInstaller.SessionParams(PackageInstaller.SessionParams.MODE_FULL_INSTALL)
+
+        val sessionId = installer.createSession(sessionParams)
+
+        installer.openSession(sessionId).use { session ->
+            session.openWrite("apk_install", 0, -1).use { outputStream ->
+                getResourceAsStream(apk).transferTo(outputStream)
+            }
+            assertThat(session.commitSession(this@installApk)).isTrue()
+        }
+    }
+
+    fun getResourceAsStream(name: String): InputStream {
+        return checkNotNull(Thread.currentThread().contextClassLoader).getResourceAsStream(name)
+    }
+
+    @OptIn(ExperimentalCoroutinesApi::class)
+    private suspend fun PackageInstaller.Session.commitSession(context: Context): Boolean {
+        val action = "com.example.COMMIT_COMPLETE.${System.currentTimeMillis()}"
+
+        return suspendCancellableCoroutine { continuation ->
+            val receiver =
+                object : BroadcastReceiver() {
+                    override fun onReceive(context: Context, intent: Intent) {
+                        context.unregisterReceiver(this)
+
+                        val status =
+                            intent.getIntExtra(
+                                PackageInstaller.EXTRA_STATUS,
+                                PackageInstaller.STATUS_FAILURE,
+                            )
+                        val message = intent.getStringExtra(PackageInstaller.EXTRA_STATUS_MESSAGE)
+
+                        if (status == PackageInstaller.STATUS_SUCCESS) {
+                            continuation.resume(true) { cause, _, _ -> }
+                        } else {
+                            continuation.resumeWithException(
+                                Exception("Installation failed: $message")
+                            )
+                        }
+                    }
+                }
+
+            val filter = IntentFilter(action)
+            context.registerReceiver(receiver, filter, Context.RECEIVER_EXPORTED)
+
+            val intent = Intent(action).setPackage(context.packageName)
+            val sender =
+                PendingIntent.getBroadcast(
+                    context,
+                    0,
+                    intent,
+                    PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_MUTABLE,
+                )
+
+            this.commit(sender.intentSender)
+
+            continuation.invokeOnCancellation {
+                // Unregister the receiver if the coroutine is cancelled
+                context.unregisterReceiver(receiver)
+            }
+        }
+    }
+
     private companion object {
+        const val ADDITIONAL_APK_FILE = "notes.apk"
+        const val ADDITIONAL_APP_PACKAGE = "com.google.android.app.notes"
+        const val ADDITIONAL_LEGACY_CREATE_NOTE =
+            "com.example.android.architecture.blueprints.todoapp#NoteFunctions_createNote"
         const val TEST_APP_FUNCTION_DOC_SIZE_LIMIT = 512 * 1024 // 512kb
 
         val FUNCTION_IDS =
diff --git a/appfunctions/integration-tests/multi-modules-testapp/app/src/androidTest/java/androidx/appfunctions/integration/tests/LegacyNoteSchema.kt b/appfunctions/integration-tests/multi-modules-testapp/app/src/androidTest/java/androidx/appfunctions/integration/tests/LegacyNoteSchema.kt
new file mode 100644
index 0000000..7edf8ac
--- /dev/null
+++ b/appfunctions/integration-tests/multi-modules-testapp/app/src/androidTest/java/androidx/appfunctions/integration/tests/LegacyNoteSchema.kt
@@ -0,0 +1,139 @@
+/*
+ * Copyright 2025 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 androidx.appfunctions.integration.tests
+
+import android.net.Uri
+import androidx.appfunctions.AppFunctionContext
+import androidx.appfunctions.AppFunctionSchemaDefinition
+import androidx.appfunctions.AppFunctionSerializable
+import java.util.Objects
+
+const val APP_FUNCTION_SCHEMA_CATEGORY_NOTES = "notes"
+
+const val APP_FUNCTION_SCHEMA_VERSION_NOTES: Int = 1
+
+/** Creates a [Note]. */
+@AppFunctionSchemaDefinition(
+    name = "createNote",
+    version = APP_FUNCTION_SCHEMA_VERSION_NOTES,
+    category = APP_FUNCTION_SCHEMA_CATEGORY_NOTES,
+)
+interface CreateNote {
+    /**
+     * Creates a [Note].
+     *
+     * The implementing app should throw an appropriate subclass of
+     * [androidx.appfunctions.AppFunctionException] in exceptional cases.
+     *
+     * @param appFunctionContext The AppFunction execution context.
+     * @param createNoteParams The parameters for creating a note.
+     * @return The created note.
+     */
+    suspend fun createNote(
+        appFunctionContext: AppFunctionContext,
+        createNoteParams: LegacyCreateNoteParams,
+    ): LegacyNote
+}
+
+/** A note entity. */
+@AppFunctionSerializable(isDescribedByKdoc = true)
+class LegacyNote(
+    /** The ID of the note. */
+    val id: String,
+    /** The title of the note. */
+    val title: String,
+    /** The content of the note. */
+    val content: String? = null,
+    /** The attachments of the note. */
+    val attachments: List<LegacyAttachment> = emptyList(),
+    /** The ID of the folder the note is in, if any. */
+    val folderId: String? = null,
+) {
+    override fun equals(other: Any?) =
+        other is LegacyNote &&
+            id == other.id &&
+            title == other.title &&
+            content == other.content &&
+            attachments == other.attachments &&
+            folderId == other.folderId
+
+    override fun hashCode() = Objects.hash(id, title, content, attachments, folderId)
+}
+
+/** A file attached to the note. */
+@AppFunctionSerializable(isDescribedByKdoc = true)
+class LegacyAttachment(
+    /** The display name of the attachment. */
+    val displayName: String,
+    /** The MIME type of the attachment. Format defined in RFC 6838. */
+    val mimeType: String? = null,
+    /** The URI of the attachment. */
+    val uri: Uri,
+) {
+    override fun equals(other: Any?) =
+        other is LegacyAttachment &&
+            displayName == other.displayName &&
+            mimeType == other.mimeType &&
+            uri == other.uri
+
+    override fun hashCode() = Objects.hash(displayName, mimeType, uri)
+}
+
+/** The parameters for creating a note. */
+@AppFunctionSerializable(isDescribedByKdoc = true)
+class LegacyCreateNoteParams(
+    /** The title of the note. */
+    val title: String,
+    /** The content of the note. */
+    val content: String? = null,
+
+    /** The attachments of the note. */
+    val attachments: List<LegacyAttachment> = emptyList(),
+
+    /**
+     * The ID of the folder the note is in, if any.
+     *
+     * [androidx.appfunctions.AppFunctionElementNotFoundException] should be thrown when a folder
+     * with the specified folderId doesn't exist.
+     */
+    val folderId: String? = null,
+
+    /**
+     * An optional UUID for this note provided by the caller. If provided, the caller can use this
+     * UUID as well as the returned [LegacyNote.id] to reference this specific note in subsequent
+     * requests, such as a request to update the note that was just created.
+     *
+     * To support [externalId], the application should maintain a mapping between the [externalId]
+     * and the internal id of this note. This allows the application to retrieve the correct note
+     * when the caller references it using the provided `externalId` in subsequent requests.
+     *
+     * If the `externalId` is not provided by the caller in the creation request, the application
+     * should expect subsequent requests from the caller to reference the note using the application
+     * generated [LegacyNote.id].
+     */
+    val externalId: String? = null,
+) {
+    override fun equals(other: Any?) =
+        other is LegacyCreateNoteParams &&
+            title == other.title &&
+            content == other.content &&
+            attachments == other.attachments &&
+            folderId == other.folderId &&
+            externalId == other.externalId
+
+    override fun hashCode() = Objects.hash(title, content, attachments, folderId, externalId)
+}
diff --git a/appfunctions/integration-tests/multi-modules-testapp/app/src/androidTest/java/androidx/appfunctions/integration/tests/NoteSchema.kt b/appfunctions/integration-tests/multi-modules-testapp/app/src/androidTest/java/androidx/appfunctions/integration/tests/NoteSchema.kt
index 35a7efe..de4bcc6 100644
--- a/appfunctions/integration-tests/multi-modules-testapp/app/src/androidTest/java/androidx/appfunctions/integration/tests/NoteSchema.kt
+++ b/appfunctions/integration-tests/multi-modules-testapp/app/src/androidTest/java/androidx/appfunctions/integration/tests/NoteSchema.kt
@@ -42,7 +42,7 @@
     ): Response
 
     /** The parameters for creating a note. */
-    @AppFunctionSerializable
+    @AppFunctionSerializable(isDescribedByKdoc = true)
     public data class Parameters(
         /** The title of the note. */
         val title: String,
@@ -79,7 +79,7 @@
     )
 
     /** The response including the created note. */
-    @AppFunctionSerializable
+    @AppFunctionSerializable(isDescribedByKdoc = true)
     public data class Response(
         /** The created note. */
         public val createdNote: AppFunctionNote,
@@ -89,7 +89,7 @@
 }
 
 /** A note entity. */
-@AppFunctionSerializable
+@AppFunctionSerializable(isDescribedByKdoc = true)
 public data class AppFunctionNote(
     /** The ID of the note. */
     val id: String,
@@ -104,7 +104,7 @@
     val attachments: List<Attachment> = emptyList(),
 ) {
     /** An attached file. */
-    @AppFunctionSerializable
+    @AppFunctionSerializable(isDescribedByKdoc = true)
     data class Attachment(
         /**
          * The URI of the attached file.
diff --git a/appfunctions/integration-tests/multi-modules-testapp/app/src/androidTest/java/androidx/appfunctions/integration/tests/TestFunctions.kt b/appfunctions/integration-tests/multi-modules-testapp/app/src/androidTest/java/androidx/appfunctions/integration/tests/TestFunctions.kt
index ec20c44..df20116 100644
--- a/appfunctions/integration-tests/multi-modules-testapp/app/src/androidTest/java/androidx/appfunctions/integration/tests/TestFunctions.kt
+++ b/appfunctions/integration-tests/multi-modules-testapp/app/src/androidTest/java/androidx/appfunctions/integration/tests/TestFunctions.kt
@@ -493,7 +493,14 @@
 
 class NotesFunctions : CreateNoteAppFunction {
 
-    @AppFunction
+    /**
+     * Create a note.
+     *
+     * @param parameters The parameters.
+     * @param tag The optional tag.
+     * @return [CreateNoteAppFunction.Response] as response.
+     */
+    @AppFunction(isDescribedByKdoc = true)
     override suspend fun createNote(
         appFunctionContext: AppFunctionContext,
         parameters: CreateNoteAppFunction.Parameters,
diff --git a/appfunctions/integration-tests/multi-modules-testapp/app/src/androidTest/resources/notes.apk b/appfunctions/integration-tests/multi-modules-testapp/app/src/androidTest/resources/notes.apk
new file mode 100644
index 0000000..d27c6ac
--- /dev/null
+++ b/appfunctions/integration-tests/multi-modules-testapp/app/src/androidTest/resources/notes.apk
Binary files differ
diff --git a/appfunctions/integration-tests/multi-modules-testapp/app/src/main/AndroidManifest.xml b/appfunctions/integration-tests/multi-modules-testapp/app/src/main/AndroidManifest.xml
index 3714982..b3b20ce 100644
--- a/appfunctions/integration-tests/multi-modules-testapp/app/src/main/AndroidManifest.xml
+++ b/appfunctions/integration-tests/multi-modules-testapp/app/src/main/AndroidManifest.xml
@@ -14,5 +14,7 @@
   limitations under the License.
   -->
 <manifest xmlns:android="http://schemas.android.com/apk/res/android">
-
+    <queries>
+        <package android:name="com.google.android.app.notes" />
+    </queries>
 </manifest>
\ No newline at end of file
diff --git a/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/IcingOptionsConfig.java b/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/IcingOptionsConfig.java
index 1949ec5c..a4a2779 100644
--- a/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/IcingOptionsConfig.java
+++ b/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/IcingOptionsConfig.java
@@ -364,6 +364,8 @@
                 .setEmbeddingIndexNumShards(
                         Flags.enableShardedEmbeddingStorage()
                                 ? Math.max(1, getEmbeddingIndexNumShards()) : 1)
+                .setEnableSchemaTypeIdOptimization(
+                        Flags.enableSchemaTypeIdOptimization())
                 .build();
     }
 }
diff --git a/appsearch/appsearch/src/androidTest/java/androidx/appsearch/flags/FlagsTest.java b/appsearch/appsearch/src/androidTest/java/androidx/appsearch/flags/FlagsTest.java
index f7d14eed..5e5296d 100644
--- a/appsearch/appsearch/src/androidTest/java/androidx/appsearch/flags/FlagsTest.java
+++ b/appsearch/appsearch/src/androidTest/java/androidx/appsearch/flags/FlagsTest.java
@@ -341,4 +341,10 @@
         assertThat(Flags.FLAG_ENABLE_SHARDED_EMBEDDING_STORAGE)
                 .isEqualTo("com.android.appsearch.flags.enable_sharded_embedding_storage");
     }
+
+    @Test
+    public void testFlagValue_enableSchemaTypeIdOptimization() {
+        assertThat(Flags.FLAG_ENABLE_SCHEMA_TYPE_ID_OPTIMIZATION).isEqualTo(
+                "com.android.appsearch.flags.enable_schema_type_id_optimization");
+    }
 }
diff --git a/appsearch/appsearch/src/main/java/androidx/appsearch/flags/Flags.java b/appsearch/appsearch/src/main/java/androidx/appsearch/flags/Flags.java
index 40c4301..342aa59 100644
--- a/appsearch/appsearch/src/main/java/androidx/appsearch/flags/Flags.java
+++ b/appsearch/appsearch/src/main/java/androidx/appsearch/flags/Flags.java
@@ -333,6 +333,13 @@
     public static final String FLAG_ENABLE_DIRECTLY_WRITE_COMMIT_REMOVE_BLOB_RESPONSE =
             FLAG_PREFIX + "directly_write_commit_remove_blob_response";
 
+    /**
+     * Whether to enable schema-type id optimization for setSchema. When enabled, the type-ids of
+     * existing types will be preserved when possible.
+     */
+    public static final String FLAG_ENABLE_SCHEMA_TYPE_ID_OPTIMIZATION =
+            FLAG_PREFIX + "enable_schema_type_id_optimization";
+
     // Whether the features should be enabled.
     //
     // In Jetpack, those should always return true.
@@ -734,4 +741,14 @@
     public static boolean enableDirectlyWriteCommitRemoveBlobResponse() {
         return true;
     }
+
+    /**
+     * Whether to enable schema-type id optimization for setSchema. When enabled, the type-ids of
+     * existing types will be preserved when possible, and there will be no schema-type id
+     * reassignment for adding new types.
+     */
+    public static boolean enableSchemaTypeIdOptimization() {
+        // TODO(b/434218554): Enable this once the feature is rolled out to Nextfood in platform.
+        return false;
+    }
 }
diff --git a/browser/browser/src/main/java/androidx/browser/trusted/TrustedWebActivityServiceConnectionPool.java b/browser/browser/src/main/java/androidx/browser/trusted/TrustedWebActivityServiceConnectionPool.java
index 3215b2b..b242a0e 100644
--- a/browser/browser/src/main/java/androidx/browser/trusted/TrustedWebActivityServiceConnectionPool.java
+++ b/browser/browser/src/main/java/androidx/browser/trusted/TrustedWebActivityServiceConnectionPool.java
@@ -215,8 +215,16 @@
         Intent scopeResolutionIntent = new Intent();
         scopeResolutionIntent.setData(scope);
         scopeResolutionIntent.setAction(Intent.ACTION_VIEW);
+
+        // According to the documentation, the flag we want to use below is MATCH_DEFAULT_ONLY.
+        // This would match all the browsers installed on the user's system whose intent handler
+        // contains the category Intent.CATEGORY_DEFAULT. However, >= Android M the behavior of
+        // the PackageManager changed to only return the default browser unless the MATCH_ALL is
+        // passed (this is specific to querying browsers - if you query for any other type of
+        // package, MATCH_DEFAULT_ONLY will work as documented). This flag did not exist on Android
+        // versions before M, so we only use it in that case.
         List<ResolveInfo> candidateActivities = appContext.getPackageManager()
-                .queryIntentActivities(scopeResolutionIntent, PackageManager.MATCH_DEFAULT_ONLY);
+                .queryIntentActivities(scopeResolutionIntent, PackageManager.MATCH_ALL);
 
         // Choose the first of the installed packages that is verified.
         String resolvedPackage = null;
diff --git a/buildSrc/lint/lint.xml b/buildSrc/lint/lint.xml
index 7dda684..ff7df05 100644
--- a/buildSrc/lint/lint.xml
+++ b/buildSrc/lint/lint.xml
@@ -37,7 +37,7 @@
         <ignore path="**/src/androidTest/**" />
         <!-- Required for Kotlin multi-platform tests. -->
         <ignore path="**/src/androidInstrumentedTest/**" />
-        <ignore path="**/src/androidUnitTest/**" />
+        <ignore path="**/src/androidHostTest/**" />
     </issue>
     <!-- Disable all lint checks on transformed classes by default. b/283812176 -->
     <issue id="all">
diff --git a/buildSrc/private/src/main/kotlin/androidx/build/AndroidXImplPlugin.kt b/buildSrc/private/src/main/kotlin/androidx/build/AndroidXImplPlugin.kt
index eb6baa8..bc19a31 100644
--- a/buildSrc/private/src/main/kotlin/androidx/build/AndroidXImplPlugin.kt
+++ b/buildSrc/private/src/main/kotlin/androidx/build/AndroidXImplPlugin.kt
@@ -1123,11 +1123,7 @@
                 it.animationsDisabled = true
             }
 
-        @Suppress("UnstableApiUsage") // usage of withHostTestBuilder
-        withHostTestBuilder {
-            @Suppress("DEPRECATION")
-            defaultSourceSetName = "androidUnitTest"
-        }
+        withHostTestBuilder {} // enable Android host tests
 
         @Suppress("UnstableApiUsage") // usage of withDeviceTestBuilder
         withDeviceTestBuilder {
diff --git a/buildSrc/private/src/main/kotlin/androidx/build/ListTaskOutputsTask.kt b/buildSrc/private/src/main/kotlin/androidx/build/ListTaskOutputsTask.kt
index 02c3573..93b533d 100644
--- a/buildSrc/private/src/main/kotlin/androidx/build/ListTaskOutputsTask.kt
+++ b/buildSrc/private/src/main/kotlin/androidx/build/ListTaskOutputsTask.kt
@@ -16,14 +16,15 @@
 
 package androidx.build
 
-import java.io.File
 import org.gradle.api.DefaultTask
 import org.gradle.api.GradleException
-import org.gradle.api.Project
 import org.gradle.api.Task
 import org.gradle.api.file.RegularFileProperty
+import org.gradle.api.provider.ListProperty
+import org.gradle.api.provider.Property
 import org.gradle.api.tasks.CacheableTask
 import org.gradle.api.tasks.Input
+import org.gradle.api.tasks.Nested
 import org.gradle.api.tasks.OutputFile
 import org.gradle.api.tasks.TaskAction
 
@@ -32,33 +33,81 @@
 abstract class ListTaskOutputsTask : DefaultTask() {
     @OutputFile val outputFile: RegularFileProperty = project.objects.fileProperty()
     @Input val removePrefixes: MutableList<String> = mutableListOf()
-    @Input val tasks: MutableList<Task> = mutableListOf()
-
-    @get:Input val outputText by lazy { computeOutputText() }
+    @get:Nested abstract val producers: ListProperty<TaskOutputProducer>
 
     init {
         group = "Help"
-        // compute the output text when the taskgraph is ready so that the output text can be
-        // saved in the configuration cache and not generate a configuration cache violation
-        project.gradle.taskGraph.whenReady { outputText }
+        project.gradle.taskGraph.whenReady {
+            val taskOutputProducerList = mutableListOf<TaskOutputProducer>()
+            project.allprojects { otherProject ->
+                otherProject.tasks.forEach { task ->
+                    project.objects.newInstance(TaskOutputProducer::class.java).apply {
+                        taskPath.set(task.path)
+                        taskClass.set(task::class.qualifiedName ?: task::class.java.name)
+                        validate.set(shouldValidateTaskOutput(task))
+                        val fileElements = task.outputs.files.elements
+                        outputPaths.set(
+                            fileElements.map { set ->
+                                set.map { it.asFile.invariantSeparatorsPath }
+                            }
+                        )
+                        taskOutputProducerList.add(this)
+                    }
+                }
+            }
+            producers.set(taskOutputProducerList)
+        }
     }
 
     fun removePrefix(prefix: String) {
         removePrefixes.add("$prefix/")
     }
 
-    // Given a map from output file to Task, formats into a String
-    private fun formatTasks(tasksByOutput: Map<File, Task>): String {
+    @TaskAction
+    fun exec() {
+        val outputText = computeOutputText(producers.get())
+        val outputFile = outputFile.get()
+        outputFile.asFile.writeText(outputText)
+    }
+
+    private fun computeOutputText(producers: List<TaskOutputProducer>): String {
+        val tasksByOutput: MutableMap<String, TaskOutputProducer> = hashMapOf()
+        for (producer in producers) {
+            for (path in producer.outputPaths.get()) {
+                val existing = tasksByOutput[path]
+                if (existing != null) {
+                    if (existing.validate.get() && producer.validate.get()) {
+                        throw GradleException(
+                            "Output file $path was declared as an output of multiple tasks: " +
+                                "${producer.taskPath.get()} and ${existing.taskPath.get()}"
+                        )
+                    }
+                    if (existing.taskPath.get() > producer.taskPath.get()) continue
+                }
+                tasksByOutput[path] = producer
+            }
+        }
+        return formatTasks(tasksByOutput, removePrefixes)
+    }
+
+    // Given a map from output file path to Task, formats into a String
+    private fun formatTasks(
+        tasksByOutput: MutableMap<String, TaskOutputProducer>,
+        removePrefixes: List<String>,
+    ): String {
         val messages: MutableList<String> = mutableListOf()
-        for ((output, task) in tasksByOutput) {
-            var filePath = output.path
+        for ((path, task) in tasksByOutput) {
+            var filePath = path
             for (prefix in removePrefixes) {
                 filePath = filePath.removePrefix(prefix)
             }
 
             messages.add(
                 formatInColumns(
-                    listOf(filePath, " - " + task.path + " (" + task::class.qualifiedName + ")")
+                    listOf(
+                        filePath,
+                        " - " + task.taskPath.get() + " (" + task.taskClass.get() + ")",
+                    )
                 )
             )
         }
@@ -85,21 +134,10 @@
         }
         return components.joinToString("")
     }
-
-    fun computeOutputText(): String {
-        val tasksByOutput = project.rootProject.findAllTasksByOutput()
-        return formatTasks(tasksByOutput)
-    }
-
-    @TaskAction
-    fun exec() {
-        val outputFile = outputFile.get()
-        outputFile.asFile.writeText(outputText)
-    }
 }
 
 // TODO(149103692): remove all elements of this set
-val taskNamesKnownToDuplicateOutputs =
+private val taskNamesKnownToDuplicateOutputs =
     setOf(
         // Instead of adding new elements to this set, prefer to disable unused tasks when possible
 
@@ -180,38 +218,22 @@
     return !taskNamesKnownToDuplicateOutputs.contains(task.name)
 }
 
-// For this project and all subprojects, collects all tasks and creates a map keyed by their output
-// files
-fun Project.findAllTasksByOutput(): Map<File, Task> {
-    // find list of all tasks
-    val allTasks = mutableListOf<Task>()
-    project.allprojects { otherProject ->
-        otherProject.tasks.forEach { task -> allTasks.add(task) }
-    }
+/** Nested input describing each projects tasks and its outputs */
+abstract class TaskOutputProducer {
 
-    // group tasks by their outputs
-    val tasksByOutput: MutableMap<File, Task> = hashMapOf()
-    for (otherTask in allTasks) {
-        for (otherTaskOutput in otherTask.outputs.files.files) {
-            val existingTask = tasksByOutput[otherTaskOutput]
-            if (existingTask != null) {
-                if (shouldValidateTaskOutput(existingTask) && shouldValidateTaskOutput(otherTask)) {
-                    throw GradleException(
-                        "Output file " +
-                            otherTaskOutput +
-                            " was declared as an output of " +
-                            "multiple tasks: " +
-                            otherTask +
-                            " and " +
-                            existingTask
-                    )
-                }
-                // if there is an exempt conflict, keep the alphabetically earlier task to ensure
-                // consistency
-                if (existingTask.path > otherTask.path) continue
-            }
-            tasksByOutput[otherTaskOutput] = otherTask
-        }
-    }
-    return tasksByOutput
+    @get:Input abstract val taskPath: Property<String>
+
+    @get:Input abstract val taskClass: Property<String>
+
+    @get:Input abstract val validate: Property<Boolean>
+
+    /**
+     * A collection of output paths from various tasks.
+     *
+     * This property intentionally avoids using a [org.gradle.api.file.FileCollection] to prevent
+     * creating a direct task dependency between the producer tasks and the [ListTaskOutputsTask].
+     * By storing the paths as strings, we can inspect the output locations without coupling the
+     * tasks in the execution graph.
+     */
+    @get:Input abstract val outputPaths: ListProperty<String>
 }
diff --git a/buildSrc/private/src/main/kotlin/androidx/build/VerifyDependencyVersionsTask.kt b/buildSrc/private/src/main/kotlin/androidx/build/VerifyDependencyVersionsTask.kt
index 89fc3c1..ca48fd9 100644
--- a/buildSrc/private/src/main/kotlin/androidx/build/VerifyDependencyVersionsTask.kt
+++ b/buildSrc/private/src/main/kotlin/androidx/build/VerifyDependencyVersionsTask.kt
@@ -183,7 +183,6 @@
     if (name.startsWith("androidInstrumentedTest")) return false
     if (name.startsWith("androidReleaseUnitTest")) return false
     if (name.startsWith("androidHostTest")) return false
-    if (name.startsWith("androidUnitTest")) return false
     if (name.startsWith("debug")) return false
     if (name.startsWith("androidDebug")) return false
     if (name.startsWith("releaseAndroidTest")) return false
diff --git a/buildSrc/public/src/main/kotlin/androidx/build/RobolectricHelper.kt b/buildSrc/public/src/main/kotlin/androidx/build/RobolectricHelper.kt
index b0c34c5..6635a1d 100644
--- a/buildSrc/public/src/main/kotlin/androidx/build/RobolectricHelper.kt
+++ b/buildSrc/public/src/main/kotlin/androidx/build/RobolectricHelper.kt
@@ -72,7 +72,7 @@
                             hostTest.configureTestTask { configureJvmTestTask(project, it) }
                         }
                     }
-                project.configurations.named("androidUnitTestImplementation").configure {
+                project.configurations.named("androidHostTestImplementation").configure {
                     configuration ->
                     configuration.dependencies.add(project.getLibraryByName("robolectric"))
                 }
diff --git a/busytown/androidx_multiplatform_mac_arm64.sh b/busytown/androidx_multiplatform_mac_arm64.sh
index e17cbb0..8e0e648 100755
--- a/busytown/androidx_multiplatform_mac_arm64.sh
+++ b/busytown/androidx_multiplatform_mac_arm64.sh
@@ -6,6 +6,6 @@
 
 export USE_ANDROIDX_REMOTE_BUILD_CACHE=gcp
 
-sharedArgs="--no-configuration-cache -Pandroidx.lowMemory $*"
+sharedArgs="-Pandroidx.lowMemory $*"
 
 impl/build.sh buildOnServer createAllArchives listTaskOutputs checkExternalLicenses "$sharedArgs"
\ No newline at end of file
diff --git a/busytown/androidx_with_metalava.sh b/busytown/androidx_with_metalava.sh
index fa03981..98623e8 100755
--- a/busytown/androidx_with_metalava.sh
+++ b/busytown/androidx_with_metalava.sh
@@ -4,7 +4,7 @@
 
 # Use this flag to temporarily disable `checkApi`
 # while landing Metalava w/ breaking API changes
-METALAVA_INTEGRATION_ENFORCED=true
+METALAVA_INTEGRATION_ENFORCED=false
 
 # The default targets to build if no arguments
 # are provided on the command line.
diff --git a/compose/animation/animation-core/build.gradle b/compose/animation/animation-core/build.gradle
index 49b6a18..f8190ed 100644
--- a/compose/animation/animation-core/build.gradle
+++ b/compose/animation/animation-core/build.gradle
@@ -110,7 +110,7 @@
             }
         }
 
-        androidUnitTest {
+        androidHostTest {
             dependsOn(commonTest)
             dependencies {
                 implementation(libs.testRules)
diff --git a/compose/animation/animation-core/src/androidUnitTest/kotlin/androidx/compose/animation/core/EasingTest.android.kt b/compose/animation/animation-core/src/androidHostTest/kotlin/androidx/compose/animation/core/EasingTest.android.kt
similarity index 100%
rename from compose/animation/animation-core/src/androidUnitTest/kotlin/androidx/compose/animation/core/EasingTest.android.kt
rename to compose/animation/animation-core/src/androidHostTest/kotlin/androidx/compose/animation/core/EasingTest.android.kt
diff --git a/compose/animation/animation-core/src/androidUnitTest/kotlin/androidx/compose/animation/core/SpringEstimationTest.kt b/compose/animation/animation-core/src/androidHostTest/kotlin/androidx/compose/animation/core/SpringEstimationTest.kt
similarity index 100%
rename from compose/animation/animation-core/src/androidUnitTest/kotlin/androidx/compose/animation/core/SpringEstimationTest.kt
rename to compose/animation/animation-core/src/androidHostTest/kotlin/androidx/compose/animation/core/SpringEstimationTest.kt
diff --git a/compose/animation/animation-graphics/build.gradle b/compose/animation/animation-graphics/build.gradle
index 4acd30b..c7f2932 100644
--- a/compose/animation/animation-graphics/build.gradle
+++ b/compose/animation/animation-graphics/build.gradle
@@ -104,7 +104,7 @@
             }
         }
 
-        androidUnitTest {
+        androidHostTest {
             dependsOn(commonTest)
             dependencies {
                 implementation(libs.testRules)
diff --git a/compose/animation/animation/build.gradle b/compose/animation/animation/build.gradle
index 8ab1780..f2f7340 100644
--- a/compose/animation/animation/build.gradle
+++ b/compose/animation/animation/build.gradle
@@ -106,7 +106,7 @@
             }
         }
 
-        androidUnitTest {
+        androidHostTest {
             dependsOn(commonTest)
             dependencies {
                 implementation(libs.testRules)
diff --git a/compose/animation/animation/src/androidUnitTest/kotlin/androidx/compose/animation/AndroidFlingSplineTest.kt b/compose/animation/animation/src/androidHostTest/kotlin/androidx/compose/animation/AndroidFlingSplineTest.kt
similarity index 100%
rename from compose/animation/animation/src/androidUnitTest/kotlin/androidx/compose/animation/AndroidFlingSplineTest.kt
rename to compose/animation/animation/src/androidHostTest/kotlin/androidx/compose/animation/AndroidFlingSplineTest.kt
diff --git a/compose/animation/animation/src/androidUnitTest/kotlin/androidx/compose/animation/ConverterTest.kt b/compose/animation/animation/src/androidHostTest/kotlin/androidx/compose/animation/ConverterTest.kt
similarity index 100%
rename from compose/animation/animation/src/androidUnitTest/kotlin/androidx/compose/animation/ConverterTest.kt
rename to compose/animation/animation/src/androidHostTest/kotlin/androidx/compose/animation/ConverterTest.kt
diff --git a/compose/foundation/foundation-layout/build.gradle b/compose/foundation/foundation-layout/build.gradle
index 2aa8e39..66b3194 100644
--- a/compose/foundation/foundation-layout/build.gradle
+++ b/compose/foundation/foundation-layout/build.gradle
@@ -105,7 +105,7 @@
             }
         }
 
-        androidUnitTest {
+        androidHostTest {
             dependsOn(commonTest)
             dependencies {
                 implementation(libs.testRules)
diff --git a/compose/foundation/foundation-layout/src/androidUnitTest/kotlin/androidx/compose/foundation/layout/WindowInsetsTest.kt b/compose/foundation/foundation-layout/src/androidHostTest/kotlin/androidx/compose/foundation/layout/WindowInsetsTest.kt
similarity index 100%
rename from compose/foundation/foundation-layout/src/androidUnitTest/kotlin/androidx/compose/foundation/layout/WindowInsetsTest.kt
rename to compose/foundation/foundation-layout/src/androidHostTest/kotlin/androidx/compose/foundation/layout/WindowInsetsTest.kt
diff --git a/compose/foundation/foundation/build.gradle b/compose/foundation/foundation/build.gradle
index 6b8d116..83131b9 100644
--- a/compose/foundation/foundation/build.gradle
+++ b/compose/foundation/foundation/build.gradle
@@ -122,7 +122,7 @@
             }
         }
 
-        androidUnitTest {
+        androidHostTest {
             dependsOn(commonTest)
             dependencies {
                 implementation(libs.testRules)
diff --git a/compose/foundation/foundation/lint-baseline.xml b/compose/foundation/foundation/lint-baseline.xml
index d0305ba..c834539 100644
--- a/compose/foundation/foundation/lint-baseline.xml
+++ b/compose/foundation/foundation/lint-baseline.xml
@@ -7,7 +7,7 @@
         errorLine1="            assertThat(texts.isEmpty())"
         errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="src/androidUnitTest/kotlin/androidx/compose/foundation/text/input/TextFieldStateTest.kt"/>
+            file="src/androidHostTest/kotlin/androidx/compose/foundation/text/input/TextFieldStateTest.kt"/>
     </issue>
 
     <issue
diff --git a/compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/MutatorMutexTest.kt b/compose/foundation/foundation/src/androidHostTest/kotlin/androidx/compose/foundation/MutatorMutexTest.kt
similarity index 100%
rename from compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/MutatorMutexTest.kt
rename to compose/foundation/foundation/src/androidHostTest/kotlin/androidx/compose/foundation/MutatorMutexTest.kt
diff --git a/compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/contextmenu/ContextMenuPopupPositionProviderTest.kt b/compose/foundation/foundation/src/androidHostTest/kotlin/androidx/compose/foundation/contextmenu/ContextMenuPopupPositionProviderTest.kt
similarity index 100%
rename from compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/contextmenu/ContextMenuPopupPositionProviderTest.kt
rename to compose/foundation/foundation/src/androidHostTest/kotlin/androidx/compose/foundation/contextmenu/ContextMenuPopupPositionProviderTest.kt
diff --git a/compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/contextmenu/ContextMenuStateTest.kt b/compose/foundation/foundation/src/androidHostTest/kotlin/androidx/compose/foundation/contextmenu/ContextMenuStateTest.kt
similarity index 100%
rename from compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/contextmenu/ContextMenuStateTest.kt
rename to compose/foundation/foundation/src/androidHostTest/kotlin/androidx/compose/foundation/contextmenu/ContextMenuStateTest.kt
diff --git a/compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/gestures/BringIntoViewRequestPriorityQueueTest.kt b/compose/foundation/foundation/src/androidHostTest/kotlin/androidx/compose/foundation/gestures/BringIntoViewRequestPriorityQueueTest.kt
similarity index 100%
rename from compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/gestures/BringIntoViewRequestPriorityQueueTest.kt
rename to compose/foundation/foundation/src/androidHostTest/kotlin/androidx/compose/foundation/gestures/BringIntoViewRequestPriorityQueueTest.kt
diff --git a/compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/gestures/DraggableAnchorsTest.kt b/compose/foundation/foundation/src/androidHostTest/kotlin/androidx/compose/foundation/gestures/DraggableAnchorsTest.kt
similarity index 100%
rename from compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/gestures/DraggableAnchorsTest.kt
rename to compose/foundation/foundation/src/androidHostTest/kotlin/androidx/compose/foundation/gestures/DraggableAnchorsTest.kt
diff --git a/compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/gestures/UpdatableAnimationStateTest.kt b/compose/foundation/foundation/src/androidHostTest/kotlin/androidx/compose/foundation/gestures/UpdatableAnimationStateTest.kt
similarity index 100%
rename from compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/gestures/UpdatableAnimationStateTest.kt
rename to compose/foundation/foundation/src/androidHostTest/kotlin/androidx/compose/foundation/gestures/UpdatableAnimationStateTest.kt
diff --git a/compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/lazy/MutableIntervalListTest.kt b/compose/foundation/foundation/src/androidHostTest/kotlin/androidx/compose/foundation/lazy/MutableIntervalListTest.kt
similarity index 100%
rename from compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/lazy/MutableIntervalListTest.kt
rename to compose/foundation/foundation/src/androidHostTest/kotlin/androidx/compose/foundation/lazy/MutableIntervalListTest.kt
diff --git a/compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/shape/ShapeInterpolationTests.kt b/compose/foundation/foundation/src/androidHostTest/kotlin/androidx/compose/foundation/shape/ShapeInterpolationTests.kt
similarity index 100%
rename from compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/shape/ShapeInterpolationTests.kt
rename to compose/foundation/foundation/src/androidHostTest/kotlin/androidx/compose/foundation/shape/ShapeInterpolationTests.kt
diff --git a/compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/text/KeyboardOptionsTest.kt b/compose/foundation/foundation/src/androidHostTest/kotlin/androidx/compose/foundation/text/KeyboardOptionsTest.kt
similarity index 100%
rename from compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/text/KeyboardOptionsTest.kt
rename to compose/foundation/foundation/src/androidHostTest/kotlin/androidx/compose/foundation/text/KeyboardOptionsTest.kt
diff --git a/compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/text/LegacyTextFieldStateTest.kt b/compose/foundation/foundation/src/androidHostTest/kotlin/androidx/compose/foundation/text/LegacyTextFieldStateTest.kt
similarity index 100%
rename from compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/text/LegacyTextFieldStateTest.kt
rename to compose/foundation/foundation/src/androidHostTest/kotlin/androidx/compose/foundation/text/LegacyTextFieldStateTest.kt
diff --git a/compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/text/LinkStateInteractionSourceObserverTest.kt b/compose/foundation/foundation/src/androidHostTest/kotlin/androidx/compose/foundation/text/LinkStateInteractionSourceObserverTest.kt
similarity index 100%
rename from compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/text/LinkStateInteractionSourceObserverTest.kt
rename to compose/foundation/foundation/src/androidHostTest/kotlin/androidx/compose/foundation/text/LinkStateInteractionSourceObserverTest.kt
diff --git a/compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/text/OWNERS b/compose/foundation/foundation/src/androidHostTest/kotlin/androidx/compose/foundation/text/OWNERS
similarity index 100%
rename from compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/text/OWNERS
rename to compose/foundation/foundation/src/androidHostTest/kotlin/androidx/compose/foundation/text/OWNERS
diff --git a/compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/text/TextAutoSizeTest.kt b/compose/foundation/foundation/src/androidHostTest/kotlin/androidx/compose/foundation/text/TextAutoSizeTest.kt
similarity index 100%
rename from compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/text/TextAutoSizeTest.kt
rename to compose/foundation/foundation/src/androidHostTest/kotlin/androidx/compose/foundation/text/TextAutoSizeTest.kt
diff --git a/compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/text/TextDelegateTest.kt b/compose/foundation/foundation/src/androidHostTest/kotlin/androidx/compose/foundation/text/TextDelegateTest.kt
similarity index 100%
rename from compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/text/TextDelegateTest.kt
rename to compose/foundation/foundation/src/androidHostTest/kotlin/androidx/compose/foundation/text/TextDelegateTest.kt
diff --git a/compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/text/TextFieldBringIntoViewTest.kt b/compose/foundation/foundation/src/androidHostTest/kotlin/androidx/compose/foundation/text/TextFieldBringIntoViewTest.kt
similarity index 100%
rename from compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/text/TextFieldBringIntoViewTest.kt
rename to compose/foundation/foundation/src/androidHostTest/kotlin/androidx/compose/foundation/text/TextFieldBringIntoViewTest.kt
diff --git a/compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/text/TextFieldDelegateTest.kt b/compose/foundation/foundation/src/androidHostTest/kotlin/androidx/compose/foundation/text/TextFieldDelegateTest.kt
similarity index 100%
rename from compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/text/TextFieldDelegateTest.kt
rename to compose/foundation/foundation/src/androidHostTest/kotlin/androidx/compose/foundation/text/TextFieldDelegateTest.kt
diff --git a/compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/text/TextFieldScrollerPositionTest.kt b/compose/foundation/foundation/src/androidHostTest/kotlin/androidx/compose/foundation/text/TextFieldScrollerPositionTest.kt
similarity index 100%
rename from compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/text/TextFieldScrollerPositionTest.kt
rename to compose/foundation/foundation/src/androidHostTest/kotlin/androidx/compose/foundation/text/TextFieldScrollerPositionTest.kt
diff --git a/compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/text/TextLayoutHelperTest.kt b/compose/foundation/foundation/src/androidHostTest/kotlin/androidx/compose/foundation/text/TextLayoutHelperTest.kt
similarity index 100%
rename from compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/text/TextLayoutHelperTest.kt
rename to compose/foundation/foundation/src/androidHostTest/kotlin/androidx/compose/foundation/text/TextLayoutHelperTest.kt
diff --git a/compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/text/UndoManagerTest.kt b/compose/foundation/foundation/src/androidHostTest/kotlin/androidx/compose/foundation/text/UndoManagerTest.kt
similarity index 100%
rename from compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/text/UndoManagerTest.kt
rename to compose/foundation/foundation/src/androidHostTest/kotlin/androidx/compose/foundation/text/UndoManagerTest.kt
diff --git a/compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/text/ValidatingOffsetMappingKtTest.kt b/compose/foundation/foundation/src/androidHostTest/kotlin/androidx/compose/foundation/text/ValidatingOffsetMappingKtTest.kt
similarity index 100%
rename from compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/text/ValidatingOffsetMappingKtTest.kt
rename to compose/foundation/foundation/src/androidHostTest/kotlin/androidx/compose/foundation/text/ValidatingOffsetMappingKtTest.kt
diff --git a/compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/text/ValidatingOffsetMappingTest.kt b/compose/foundation/foundation/src/androidHostTest/kotlin/androidx/compose/foundation/text/ValidatingOffsetMappingTest.kt
similarity index 100%
rename from compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/text/ValidatingOffsetMappingTest.kt
rename to compose/foundation/foundation/src/androidHostTest/kotlin/androidx/compose/foundation/text/ValidatingOffsetMappingTest.kt
diff --git a/compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/text/contextmenu/builder/TextContextMenuBuilderScopeTest.kt b/compose/foundation/foundation/src/androidHostTest/kotlin/androidx/compose/foundation/text/contextmenu/builder/TextContextMenuBuilderScopeTest.kt
similarity index 100%
rename from compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/text/contextmenu/builder/TextContextMenuBuilderScopeTest.kt
rename to compose/foundation/foundation/src/androidHostTest/kotlin/androidx/compose/foundation/text/contextmenu/builder/TextContextMenuBuilderScopeTest.kt
diff --git a/compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/text/contextmenu/test/ContextMenuFlagFlipperRunner.kt b/compose/foundation/foundation/src/androidHostTest/kotlin/androidx/compose/foundation/text/contextmenu/test/ContextMenuFlagFlipperRunner.kt
similarity index 100%
rename from compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/text/contextmenu/test/ContextMenuFlagFlipperRunner.kt
rename to compose/foundation/foundation/src/androidHostTest/kotlin/androidx/compose/foundation/text/contextmenu/test/ContextMenuFlagFlipperRunner.kt
diff --git a/compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/text/contextmenu/test/ContextMenuFlagFlipperRunnerTest.kt b/compose/foundation/foundation/src/androidHostTest/kotlin/androidx/compose/foundation/text/contextmenu/test/ContextMenuFlagFlipperRunnerTest.kt
similarity index 100%
rename from compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/text/contextmenu/test/ContextMenuFlagFlipperRunnerTest.kt
rename to compose/foundation/foundation/src/androidHostTest/kotlin/androidx/compose/foundation/text/contextmenu/test/ContextMenuFlagFlipperRunnerTest.kt
diff --git a/compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/text/contextmenu/test/TextContextMenuTestUtils.kt b/compose/foundation/foundation/src/androidHostTest/kotlin/androidx/compose/foundation/text/contextmenu/test/TextContextMenuTestUtils.kt
similarity index 100%
rename from compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/text/contextmenu/test/TextContextMenuTestUtils.kt
rename to compose/foundation/foundation/src/androidHostTest/kotlin/androidx/compose/foundation/text/contextmenu/test/TextContextMenuTestUtils.kt
diff --git a/compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/text/input/AllCapsTransformationTest.kt b/compose/foundation/foundation/src/androidHostTest/kotlin/androidx/compose/foundation/text/input/AllCapsTransformationTest.kt
similarity index 100%
rename from compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/text/input/AllCapsTransformationTest.kt
rename to compose/foundation/foundation/src/androidHostTest/kotlin/androidx/compose/foundation/text/input/AllCapsTransformationTest.kt
diff --git a/compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/text/input/InputTransformationTest.kt b/compose/foundation/foundation/src/androidHostTest/kotlin/androidx/compose/foundation/text/input/InputTransformationTest.kt
similarity index 100%
rename from compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/text/input/InputTransformationTest.kt
rename to compose/foundation/foundation/src/androidHostTest/kotlin/androidx/compose/foundation/text/input/InputTransformationTest.kt
diff --git a/compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/text/input/TextFieldBufferTest.kt b/compose/foundation/foundation/src/androidHostTest/kotlin/androidx/compose/foundation/text/input/TextFieldBufferTest.kt
similarity index 100%
rename from compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/text/input/TextFieldBufferTest.kt
rename to compose/foundation/foundation/src/androidHostTest/kotlin/androidx/compose/foundation/text/input/TextFieldBufferTest.kt
diff --git a/compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/text/input/TextFieldCharSequenceTest.kt b/compose/foundation/foundation/src/androidHostTest/kotlin/androidx/compose/foundation/text/input/TextFieldCharSequenceTest.kt
similarity index 100%
rename from compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/text/input/TextFieldCharSequenceTest.kt
rename to compose/foundation/foundation/src/androidHostTest/kotlin/androidx/compose/foundation/text/input/TextFieldCharSequenceTest.kt
diff --git a/compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/text/input/TextFieldStateSaverTest.kt b/compose/foundation/foundation/src/androidHostTest/kotlin/androidx/compose/foundation/text/input/TextFieldStateSaverTest.kt
similarity index 100%
rename from compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/text/input/TextFieldStateSaverTest.kt
rename to compose/foundation/foundation/src/androidHostTest/kotlin/androidx/compose/foundation/text/input/TextFieldStateSaverTest.kt
diff --git a/compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/text/input/TextFieldStateTest.kt b/compose/foundation/foundation/src/androidHostTest/kotlin/androidx/compose/foundation/text/input/TextFieldStateTest.kt
similarity index 100%
rename from compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/text/input/TextFieldStateTest.kt
rename to compose/foundation/foundation/src/androidHostTest/kotlin/androidx/compose/foundation/text/input/TextFieldStateTest.kt
diff --git a/compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/text/input/internal/ChangeTrackerTest.kt b/compose/foundation/foundation/src/androidHostTest/kotlin/androidx/compose/foundation/text/input/internal/ChangeTrackerTest.kt
similarity index 100%
rename from compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/text/input/internal/ChangeTrackerTest.kt
rename to compose/foundation/foundation/src/androidHostTest/kotlin/androidx/compose/foundation/text/input/internal/ChangeTrackerTest.kt
diff --git a/compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/text/input/internal/CodepointTransformationTest.kt b/compose/foundation/foundation/src/androidHostTest/kotlin/androidx/compose/foundation/text/input/internal/CodepointTransformationTest.kt
similarity index 100%
rename from compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/text/input/internal/CodepointTransformationTest.kt
rename to compose/foundation/foundation/src/androidHostTest/kotlin/androidx/compose/foundation/text/input/internal/CodepointTransformationTest.kt
diff --git a/compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/text/input/internal/CommitTextCommandTest.kt b/compose/foundation/foundation/src/androidHostTest/kotlin/androidx/compose/foundation/text/input/internal/CommitTextCommandTest.kt
similarity index 100%
rename from compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/text/input/internal/CommitTextCommandTest.kt
rename to compose/foundation/foundation/src/androidHostTest/kotlin/androidx/compose/foundation/text/input/internal/CommitTextCommandTest.kt
diff --git a/compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/text/input/internal/CursorAnimationDurationTest.kt b/compose/foundation/foundation/src/androidHostTest/kotlin/androidx/compose/foundation/text/input/internal/CursorAnimationDurationTest.kt
similarity index 100%
rename from compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/text/input/internal/CursorAnimationDurationTest.kt
rename to compose/foundation/foundation/src/androidHostTest/kotlin/androidx/compose/foundation/text/input/internal/CursorAnimationDurationTest.kt
diff --git a/compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/text/input/internal/CursorAnimationStateTest.kt b/compose/foundation/foundation/src/androidHostTest/kotlin/androidx/compose/foundation/text/input/internal/CursorAnimationStateTest.kt
similarity index 100%
rename from compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/text/input/internal/CursorAnimationStateTest.kt
rename to compose/foundation/foundation/src/androidHostTest/kotlin/androidx/compose/foundation/text/input/internal/CursorAnimationStateTest.kt
diff --git a/compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/text/input/internal/DeleteSurroundingTextCommandTest.kt b/compose/foundation/foundation/src/androidHostTest/kotlin/androidx/compose/foundation/text/input/internal/DeleteSurroundingTextCommandTest.kt
similarity index 100%
rename from compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/text/input/internal/DeleteSurroundingTextCommandTest.kt
rename to compose/foundation/foundation/src/androidHostTest/kotlin/androidx/compose/foundation/text/input/internal/DeleteSurroundingTextCommandTest.kt
diff --git a/compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/text/input/internal/DeleteSurroundingTextInCodePointsCommandTest.kt b/compose/foundation/foundation/src/androidHostTest/kotlin/androidx/compose/foundation/text/input/internal/DeleteSurroundingTextInCodePointsCommandTest.kt
similarity index 100%
rename from compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/text/input/internal/DeleteSurroundingTextInCodePointsCommandTest.kt
rename to compose/foundation/foundation/src/androidHostTest/kotlin/androidx/compose/foundation/text/input/internal/DeleteSurroundingTextInCodePointsCommandTest.kt
diff --git a/compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/text/input/internal/FinishComposingTextCommandTest.kt b/compose/foundation/foundation/src/androidHostTest/kotlin/androidx/compose/foundation/text/input/internal/FinishComposingTextCommandTest.kt
similarity index 100%
rename from compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/text/input/internal/FinishComposingTextCommandTest.kt
rename to compose/foundation/foundation/src/androidHostTest/kotlin/androidx/compose/foundation/text/input/internal/FinishComposingTextCommandTest.kt
diff --git a/compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/text/input/internal/GapBufferTest.kt b/compose/foundation/foundation/src/androidHostTest/kotlin/androidx/compose/foundation/text/input/internal/GapBufferTest.kt
similarity index 100%
rename from compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/text/input/internal/GapBufferTest.kt
rename to compose/foundation/foundation/src/androidHostTest/kotlin/androidx/compose/foundation/text/input/internal/GapBufferTest.kt
diff --git a/compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/text/input/internal/ImeEditCommandTest.kt b/compose/foundation/foundation/src/androidHostTest/kotlin/androidx/compose/foundation/text/input/internal/ImeEditCommandTest.kt
similarity index 100%
rename from compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/text/input/internal/ImeEditCommandTest.kt
rename to compose/foundation/foundation/src/androidHostTest/kotlin/androidx/compose/foundation/text/input/internal/ImeEditCommandTest.kt
diff --git a/compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/text/input/internal/MathUtilsTest.kt b/compose/foundation/foundation/src/androidHostTest/kotlin/androidx/compose/foundation/text/input/internal/MathUtilsTest.kt
similarity index 100%
rename from compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/text/input/internal/MathUtilsTest.kt
rename to compose/foundation/foundation/src/androidHostTest/kotlin/androidx/compose/foundation/text/input/internal/MathUtilsTest.kt
diff --git a/compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/text/input/internal/OffsetMappingCalculatorTest.kt b/compose/foundation/foundation/src/androidHostTest/kotlin/androidx/compose/foundation/text/input/internal/OffsetMappingCalculatorTest.kt
similarity index 100%
rename from compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/text/input/internal/OffsetMappingCalculatorTest.kt
rename to compose/foundation/foundation/src/androidHostTest/kotlin/androidx/compose/foundation/text/input/internal/OffsetMappingCalculatorTest.kt
diff --git a/compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/text/input/internal/SetComposingRegionCommandTest.kt b/compose/foundation/foundation/src/androidHostTest/kotlin/androidx/compose/foundation/text/input/internal/SetComposingRegionCommandTest.kt
similarity index 100%
rename from compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/text/input/internal/SetComposingRegionCommandTest.kt
rename to compose/foundation/foundation/src/androidHostTest/kotlin/androidx/compose/foundation/text/input/internal/SetComposingRegionCommandTest.kt
diff --git a/compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/text/input/internal/SetComposingTextCommandTest.kt b/compose/foundation/foundation/src/androidHostTest/kotlin/androidx/compose/foundation/text/input/internal/SetComposingTextCommandTest.kt
similarity index 100%
rename from compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/text/input/internal/SetComposingTextCommandTest.kt
rename to compose/foundation/foundation/src/androidHostTest/kotlin/androidx/compose/foundation/text/input/internal/SetComposingTextCommandTest.kt
diff --git a/compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/text/input/internal/SetSelectionCommandTest.kt b/compose/foundation/foundation/src/androidHostTest/kotlin/androidx/compose/foundation/text/input/internal/SetSelectionCommandTest.kt
similarity index 100%
rename from compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/text/input/internal/SetSelectionCommandTest.kt
rename to compose/foundation/foundation/src/androidHostTest/kotlin/androidx/compose/foundation/text/input/internal/SetSelectionCommandTest.kt
diff --git a/compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/text/input/internal/TextFieldBufferDeleteFromImeRangeTest.kt b/compose/foundation/foundation/src/androidHostTest/kotlin/androidx/compose/foundation/text/input/internal/TextFieldBufferDeleteFromImeRangeTest.kt
similarity index 100%
rename from compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/text/input/internal/TextFieldBufferDeleteFromImeRangeTest.kt
rename to compose/foundation/foundation/src/androidHostTest/kotlin/androidx/compose/foundation/text/input/internal/TextFieldBufferDeleteFromImeRangeTest.kt
diff --git a/compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/text/input/internal/TextFieldBufferUseFromImeTest.kt b/compose/foundation/foundation/src/androidHostTest/kotlin/androidx/compose/foundation/text/input/internal/TextFieldBufferUseFromImeTest.kt
similarity index 100%
rename from compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/text/input/internal/TextFieldBufferUseFromImeTest.kt
rename to compose/foundation/foundation/src/androidHostTest/kotlin/androidx/compose/foundation/text/input/internal/TextFieldBufferUseFromImeTest.kt
diff --git a/compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/text/input/internal/TextFieldStateInternalBufferTest.kt b/compose/foundation/foundation/src/androidHostTest/kotlin/androidx/compose/foundation/text/input/internal/TextFieldStateInternalBufferTest.kt
similarity index 100%
rename from compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/text/input/internal/TextFieldStateInternalBufferTest.kt
rename to compose/foundation/foundation/src/androidHostTest/kotlin/androidx/compose/foundation/text/input/internal/TextFieldStateInternalBufferTest.kt
diff --git a/compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/text/input/internal/ToCharArrayTest.kt b/compose/foundation/foundation/src/androidHostTest/kotlin/androidx/compose/foundation/text/input/internal/ToCharArrayTest.kt
similarity index 100%
rename from compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/text/input/internal/ToCharArrayTest.kt
rename to compose/foundation/foundation/src/androidHostTest/kotlin/androidx/compose/foundation/text/input/internal/ToCharArrayTest.kt
diff --git a/compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/text/input/internal/TransformedTextFieldStateTest.kt b/compose/foundation/foundation/src/androidHostTest/kotlin/androidx/compose/foundation/text/input/internal/TransformedTextFieldStateTest.kt
similarity index 100%
rename from compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/text/input/internal/TransformedTextFieldStateTest.kt
rename to compose/foundation/foundation/src/androidHostTest/kotlin/androidx/compose/foundation/text/input/internal/TransformedTextFieldStateTest.kt
diff --git a/compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/text/input/internal/TransformedTextSelectionMovementTest.kt b/compose/foundation/foundation/src/androidHostTest/kotlin/androidx/compose/foundation/text/input/internal/TransformedTextSelectionMovementTest.kt
similarity index 100%
rename from compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/text/input/internal/TransformedTextSelectionMovementTest.kt
rename to compose/foundation/foundation/src/androidHostTest/kotlin/androidx/compose/foundation/text/input/internal/TransformedTextSelectionMovementTest.kt
diff --git a/compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/text/input/internal/matchers/TextFieldBufferSubject.kt b/compose/foundation/foundation/src/androidHostTest/kotlin/androidx/compose/foundation/text/input/internal/matchers/TextFieldBufferSubject.kt
similarity index 100%
rename from compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/text/input/internal/matchers/TextFieldBufferSubject.kt
rename to compose/foundation/foundation/src/androidHostTest/kotlin/androidx/compose/foundation/text/input/internal/matchers/TextFieldBufferSubject.kt
diff --git a/compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/text/input/internal/undo/TextUndoTest.kt b/compose/foundation/foundation/src/androidHostTest/kotlin/androidx/compose/foundation/text/input/internal/undo/TextUndoTest.kt
similarity index 100%
rename from compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/text/input/internal/undo/TextUndoTest.kt
rename to compose/foundation/foundation/src/androidHostTest/kotlin/androidx/compose/foundation/text/input/internal/undo/TextUndoTest.kt
diff --git a/compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/text/input/internal/undo/UndoManagerSaverTest.kt b/compose/foundation/foundation/src/androidHostTest/kotlin/androidx/compose/foundation/text/input/internal/undo/UndoManagerSaverTest.kt
similarity index 100%
rename from compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/text/input/internal/undo/UndoManagerSaverTest.kt
rename to compose/foundation/foundation/src/androidHostTest/kotlin/androidx/compose/foundation/text/input/internal/undo/UndoManagerSaverTest.kt
diff --git a/compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/text/input/internal/undo/UndoManagerTest.kt b/compose/foundation/foundation/src/androidHostTest/kotlin/androidx/compose/foundation/text/input/internal/undo/UndoManagerTest.kt
similarity index 100%
rename from compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/text/input/internal/undo/UndoManagerTest.kt
rename to compose/foundation/foundation/src/androidHostTest/kotlin/androidx/compose/foundation/text/input/internal/undo/UndoManagerTest.kt
diff --git a/compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/text/selection/InlineAnswer.kt b/compose/foundation/foundation/src/androidHostTest/kotlin/androidx/compose/foundation/text/selection/InlineAnswer.kt
similarity index 100%
rename from compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/text/selection/InlineAnswer.kt
rename to compose/foundation/foundation/src/androidHostTest/kotlin/androidx/compose/foundation/text/selection/InlineAnswer.kt
diff --git a/compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/text/selection/MockCoordinates.kt b/compose/foundation/foundation/src/androidHostTest/kotlin/androidx/compose/foundation/text/selection/MockCoordinates.kt
similarity index 100%
rename from compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/text/selection/MockCoordinates.kt
rename to compose/foundation/foundation/src/androidHostTest/kotlin/androidx/compose/foundation/text/selection/MockCoordinates.kt
diff --git a/compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/text/selection/SelectableInfoTest.kt b/compose/foundation/foundation/src/androidHostTest/kotlin/androidx/compose/foundation/text/selection/SelectableInfoTest.kt
similarity index 100%
rename from compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/text/selection/SelectableInfoTest.kt
rename to compose/foundation/foundation/src/androidHostTest/kotlin/androidx/compose/foundation/text/selection/SelectableInfoTest.kt
diff --git a/compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/text/selection/SelectionAdjustmentTest.kt b/compose/foundation/foundation/src/androidHostTest/kotlin/androidx/compose/foundation/text/selection/SelectionAdjustmentTest.kt
similarity index 100%
rename from compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/text/selection/SelectionAdjustmentTest.kt
rename to compose/foundation/foundation/src/androidHostTest/kotlin/androidx/compose/foundation/text/selection/SelectionAdjustmentTest.kt
diff --git a/compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/text/selection/SelectionFakes.kt b/compose/foundation/foundation/src/androidHostTest/kotlin/androidx/compose/foundation/text/selection/SelectionFakes.kt
similarity index 100%
rename from compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/text/selection/SelectionFakes.kt
rename to compose/foundation/foundation/src/androidHostTest/kotlin/androidx/compose/foundation/text/selection/SelectionFakes.kt
diff --git a/compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/text/selection/SelectionLayoutStartSlot2DTest.kt b/compose/foundation/foundation/src/androidHostTest/kotlin/androidx/compose/foundation/text/selection/SelectionLayoutStartSlot2DTest.kt
similarity index 100%
rename from compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/text/selection/SelectionLayoutStartSlot2DTest.kt
rename to compose/foundation/foundation/src/androidHostTest/kotlin/androidx/compose/foundation/text/selection/SelectionLayoutStartSlot2DTest.kt
diff --git a/compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/text/selection/SelectionLayoutTest.kt b/compose/foundation/foundation/src/androidHostTest/kotlin/androidx/compose/foundation/text/selection/SelectionLayoutTest.kt
similarity index 100%
rename from compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/text/selection/SelectionLayoutTest.kt
rename to compose/foundation/foundation/src/androidHostTest/kotlin/androidx/compose/foundation/text/selection/SelectionLayoutTest.kt
diff --git a/compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/text/selection/SelectionManagerGetSelectedRegionRectTest.kt b/compose/foundation/foundation/src/androidHostTest/kotlin/androidx/compose/foundation/text/selection/SelectionManagerGetSelectedRegionRectTest.kt
similarity index 100%
rename from compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/text/selection/SelectionManagerGetSelectedRegionRectTest.kt
rename to compose/foundation/foundation/src/androidHostTest/kotlin/androidx/compose/foundation/text/selection/SelectionManagerGetSelectedRegionRectTest.kt
diff --git a/compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/text/selection/SelectionManagerTest.kt b/compose/foundation/foundation/src/androidHostTest/kotlin/androidx/compose/foundation/text/selection/SelectionManagerTest.kt
similarity index 100%
rename from compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/text/selection/SelectionManagerTest.kt
rename to compose/foundation/foundation/src/androidHostTest/kotlin/androidx/compose/foundation/text/selection/SelectionManagerTest.kt
diff --git a/compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/text/selection/SelectionModeTest.kt b/compose/foundation/foundation/src/androidHostTest/kotlin/androidx/compose/foundation/text/selection/SelectionModeTest.kt
similarity index 100%
rename from compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/text/selection/SelectionModeTest.kt
rename to compose/foundation/foundation/src/androidHostTest/kotlin/androidx/compose/foundation/text/selection/SelectionModeTest.kt
diff --git a/compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/text/selection/SelectionRegistrarImplTest.kt b/compose/foundation/foundation/src/androidHostTest/kotlin/androidx/compose/foundation/text/selection/SelectionRegistrarImplTest.kt
similarity index 100%
rename from compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/text/selection/SelectionRegistrarImplTest.kt
rename to compose/foundation/foundation/src/androidHostTest/kotlin/androidx/compose/foundation/text/selection/SelectionRegistrarImplTest.kt
diff --git a/compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/text/selection/SelectionTest.kt b/compose/foundation/foundation/src/androidHostTest/kotlin/androidx/compose/foundation/text/selection/SelectionTest.kt
similarity index 100%
rename from compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/text/selection/SelectionTest.kt
rename to compose/foundation/foundation/src/androidHostTest/kotlin/androidx/compose/foundation/text/selection/SelectionTest.kt
diff --git a/compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/text/selection/StringHelpersTest.kt b/compose/foundation/foundation/src/androidHostTest/kotlin/androidx/compose/foundation/text/selection/StringHelpersTest.kt
similarity index 100%
rename from compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/text/selection/StringHelpersTest.kt
rename to compose/foundation/foundation/src/androidHostTest/kotlin/androidx/compose/foundation/text/selection/StringHelpersTest.kt
diff --git a/compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/text/selection/TextFieldSelectionManagerTest.kt b/compose/foundation/foundation/src/androidHostTest/kotlin/androidx/compose/foundation/text/selection/TextFieldSelectionManagerTest.kt
similarity index 100%
rename from compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/text/selection/TextFieldSelectionManagerTest.kt
rename to compose/foundation/foundation/src/androidHostTest/kotlin/androidx/compose/foundation/text/selection/TextFieldSelectionManagerTest.kt
diff --git a/compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/text2/OWNERS b/compose/foundation/foundation/src/androidHostTest/kotlin/androidx/compose/foundation/text2/OWNERS
similarity index 100%
rename from compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/text2/OWNERS
rename to compose/foundation/foundation/src/androidHostTest/kotlin/androidx/compose/foundation/text2/OWNERS
diff --git a/compose/foundation/foundation/src/androidUnitTest/resources/mockito-extensions/org.mockito.plugins.MockMaker b/compose/foundation/foundation/src/androidHostTest/resources/mockito-extensions/org.mockito.plugins.MockMaker
similarity index 100%
rename from compose/foundation/foundation/src/androidUnitTest/resources/mockito-extensions/org.mockito.plugins.MockMaker
rename to compose/foundation/foundation/src/androidHostTest/resources/mockito-extensions/org.mockito.plugins.MockMaker
diff --git a/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/text/contextmenu/test/ContextMenuFlagFlipperRunner.kt b/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/text/contextmenu/test/ContextMenuFlagFlipperRunner.kt
index 070b69a..c32df2b 100644
--- a/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/text/contextmenu/test/ContextMenuFlagFlipperRunner.kt
+++ b/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/text/contextmenu/test/ContextMenuFlagFlipperRunner.kt
@@ -33,7 +33,7 @@
 import org.junit.runners.model.Statement
 
 // KEEP THIS FILE UP TO DATE WITH
-// compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/text/contextmenu/test/ContextMenuFlagFlipperRunner.kt
+// compose/foundation/foundation/src/androidHostTest/kotlin/androidx/compose/foundation/text/contextmenu/test/ContextMenuFlagFlipperRunner.kt
 
 /**
  * Annotation that tells junit to **NOT** run the test or test class with
diff --git a/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/text/contextmenu/test/ContextMenuFlagFlipperRunnerTest.kt b/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/text/contextmenu/test/ContextMenuFlagFlipperRunnerTest.kt
index b0463b3..b0a8afc 100644
--- a/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/text/contextmenu/test/ContextMenuFlagFlipperRunnerTest.kt
+++ b/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/text/contextmenu/test/ContextMenuFlagFlipperRunnerTest.kt
@@ -29,7 +29,7 @@
 import org.junit.runner.notification.RunListener
 
 // KEEP THIS FILE UP TO DATE WITH
-// compose/foundation/foundation/src/androidUnitTest/kotlin/androidx/compose/foundation/text/contextmenu/test/ContextMenuFlagFlipperRunnerTest.kt
+// compose/foundation/foundation/src/androidHostTest/kotlin/androidx/compose/foundation/text/contextmenu/test/ContextMenuFlagFlipperRunnerTest.kt
 
 @RunWith(ContextMenuFlagFlipperRunner::class)
 class ContextMenuFlagFlipperRunnerTest {
diff --git a/compose/material/material-ripple/build.gradle b/compose/material/material-ripple/build.gradle
index a80b6a8..b76b925 100644
--- a/compose/material/material-ripple/build.gradle
+++ b/compose/material/material-ripple/build.gradle
@@ -94,7 +94,7 @@
             }
         }
 
-        androidUnitTest {
+        androidHostTest {
             dependsOn(commonTest)
             dependencies {
                 implementation(libs.testRules)
diff --git a/compose/material/material-ripple/src/androidUnitTest/kotlin/androidx/compose/material/ripple/RippleAnimationTest.kt b/compose/material/material-ripple/src/androidHostTest/kotlin/androidx/compose/material/ripple/RippleAnimationTest.kt
similarity index 100%
rename from compose/material/material-ripple/src/androidUnitTest/kotlin/androidx/compose/material/ripple/RippleAnimationTest.kt
rename to compose/material/material-ripple/src/androidHostTest/kotlin/androidx/compose/material/ripple/RippleAnimationTest.kt
diff --git a/compose/material/material/build.gradle b/compose/material/material/build.gradle
index 7fde981..3833928 100644
--- a/compose/material/material/build.gradle
+++ b/compose/material/material/build.gradle
@@ -117,7 +117,7 @@
             }
         }
 
-        androidUnitTest {
+        androidHostTest {
             dependsOn(commonTest)
             dependencies {
                 implementation(libs.testRules)
diff --git a/compose/material/material/src/androidUnitTest/bottom_app_bar_rounded_edges.png b/compose/material/material/src/androidHostTest/bottom_app_bar_rounded_edges.png
similarity index 100%
rename from compose/material/material/src/androidUnitTest/bottom_app_bar_rounded_edges.png
rename to compose/material/material/src/androidHostTest/bottom_app_bar_rounded_edges.png
Binary files differ
diff --git a/compose/material/material/src/androidUnitTest/bottom_app_bar_rounded_edges_graph.py b/compose/material/material/src/androidHostTest/bottom_app_bar_rounded_edges_graph.py
similarity index 100%
rename from compose/material/material/src/androidUnitTest/bottom_app_bar_rounded_edges_graph.py
rename to compose/material/material/src/androidHostTest/bottom_app_bar_rounded_edges_graph.py
diff --git a/compose/material/material/src/androidUnitTest/kotlin/androidx/compose/material/BottomAppBarRoundedEdgesTest.kt b/compose/material/material/src/androidHostTest/kotlin/androidx/compose/material/BottomAppBarRoundedEdgesTest.kt
similarity index 100%
rename from compose/material/material/src/androidUnitTest/kotlin/androidx/compose/material/BottomAppBarRoundedEdgesTest.kt
rename to compose/material/material/src/androidHostTest/kotlin/androidx/compose/material/BottomAppBarRoundedEdgesTest.kt
diff --git a/compose/material/material/src/androidUnitTest/kotlin/androidx/compose/material/DraggableAnchorsTest.kt b/compose/material/material/src/androidHostTest/kotlin/androidx/compose/material/DraggableAnchorsTest.kt
similarity index 100%
rename from compose/material/material/src/androidUnitTest/kotlin/androidx/compose/material/DraggableAnchorsTest.kt
rename to compose/material/material/src/androidHostTest/kotlin/androidx/compose/material/DraggableAnchorsTest.kt
diff --git a/compose/material/material/src/androidUnitTest/kotlin/androidx/compose/material/InternalMutatorMutexTest.kt b/compose/material/material/src/androidHostTest/kotlin/androidx/compose/material/InternalMutatorMutexTest.kt
similarity index 100%
rename from compose/material/material/src/androidUnitTest/kotlin/androidx/compose/material/InternalMutatorMutexTest.kt
rename to compose/material/material/src/androidHostTest/kotlin/androidx/compose/material/InternalMutatorMutexTest.kt
diff --git a/compose/material/material/src/androidUnitTest/kotlin/androidx/compose/material/TextSelectionBackgroundColorTest.kt b/compose/material/material/src/androidHostTest/kotlin/androidx/compose/material/TextSelectionBackgroundColorTest.kt
similarity index 100%
rename from compose/material/material/src/androidUnitTest/kotlin/androidx/compose/material/TextSelectionBackgroundColorTest.kt
rename to compose/material/material/src/androidHostTest/kotlin/androidx/compose/material/TextSelectionBackgroundColorTest.kt
diff --git a/compose/material/material/src/androidUnitTest/resources/mockito-extensions/org.mockito.plugins.MockMaker b/compose/material/material/src/androidHostTest/resources/mockito-extensions/org.mockito.plugins.MockMaker
similarity index 100%
rename from compose/material/material/src/androidUnitTest/resources/mockito-extensions/org.mockito.plugins.MockMaker
rename to compose/material/material/src/androidHostTest/resources/mockito-extensions/org.mockito.plugins.MockMaker
diff --git a/compose/material3/adaptive/adaptive-layout/build.gradle b/compose/material3/adaptive/adaptive-layout/build.gradle
index e6c29ad..b5606c1 100644
--- a/compose/material3/adaptive/adaptive-layout/build.gradle
+++ b/compose/material3/adaptive/adaptive-layout/build.gradle
@@ -103,7 +103,7 @@
             }
         }
 
-        androidUnitTest {
+        androidHostTest {
             dependsOn(commonTest)
             dependencies {
                 implementation(libs.junit)
diff --git a/compose/material3/adaptive/adaptive-layout/src/androidUnitTest/kotlin/androidx/compose/material3/adaptive/layout/DelayedSpringSpecTest.kt b/compose/material3/adaptive/adaptive-layout/src/androidHostTest/kotlin/androidx/compose/material3/adaptive/layout/DelayedSpringSpecTest.kt
similarity index 100%
rename from compose/material3/adaptive/adaptive-layout/src/androidUnitTest/kotlin/androidx/compose/material3/adaptive/layout/DelayedSpringSpecTest.kt
rename to compose/material3/adaptive/adaptive-layout/src/androidHostTest/kotlin/androidx/compose/material3/adaptive/layout/DelayedSpringSpecTest.kt
diff --git a/compose/material3/adaptive/adaptive-layout/src/androidUnitTest/kotlin/androidx/compose/material3/adaptive/layout/PaneExpansionStateTest.kt b/compose/material3/adaptive/adaptive-layout/src/androidHostTest/kotlin/androidx/compose/material3/adaptive/layout/PaneExpansionStateTest.kt
similarity index 100%
rename from compose/material3/adaptive/adaptive-layout/src/androidUnitTest/kotlin/androidx/compose/material3/adaptive/layout/PaneExpansionStateTest.kt
rename to compose/material3/adaptive/adaptive-layout/src/androidHostTest/kotlin/androidx/compose/material3/adaptive/layout/PaneExpansionStateTest.kt
diff --git a/compose/material3/adaptive/adaptive-layout/src/androidUnitTest/kotlin/androidx/compose/material3/adaptive/layout/PaneMarginsTest.kt b/compose/material3/adaptive/adaptive-layout/src/androidHostTest/kotlin/androidx/compose/material3/adaptive/layout/PaneMarginsTest.kt
similarity index 100%
rename from compose/material3/adaptive/adaptive-layout/src/androidUnitTest/kotlin/androidx/compose/material3/adaptive/layout/PaneMarginsTest.kt
rename to compose/material3/adaptive/adaptive-layout/src/androidHostTest/kotlin/androidx/compose/material3/adaptive/layout/PaneMarginsTest.kt
diff --git a/compose/material3/adaptive/adaptive-layout/src/androidUnitTest/kotlin/androidx/compose/material3/adaptive/layout/PaneMotionTest.kt b/compose/material3/adaptive/adaptive-layout/src/androidHostTest/kotlin/androidx/compose/material3/adaptive/layout/PaneMotionTest.kt
similarity index 100%
rename from compose/material3/adaptive/adaptive-layout/src/androidUnitTest/kotlin/androidx/compose/material3/adaptive/layout/PaneMotionTest.kt
rename to compose/material3/adaptive/adaptive-layout/src/androidHostTest/kotlin/androidx/compose/material3/adaptive/layout/PaneMotionTest.kt
diff --git a/compose/material3/adaptive/adaptive-layout/src/androidUnitTest/kotlin/androidx/compose/material3/adaptive/layout/PaneScaffoldDirectiveTest.kt b/compose/material3/adaptive/adaptive-layout/src/androidHostTest/kotlin/androidx/compose/material3/adaptive/layout/PaneScaffoldDirectiveTest.kt
similarity index 100%
rename from compose/material3/adaptive/adaptive-layout/src/androidUnitTest/kotlin/androidx/compose/material3/adaptive/layout/PaneScaffoldDirectiveTest.kt
rename to compose/material3/adaptive/adaptive-layout/src/androidHostTest/kotlin/androidx/compose/material3/adaptive/layout/PaneScaffoldDirectiveTest.kt
diff --git a/compose/material3/adaptive/adaptive-layout/src/androidUnitTest/kotlin/androidx/compose/material3/adaptive/layout/ThreePaneScaffoldValueTest.kt b/compose/material3/adaptive/adaptive-layout/src/androidHostTest/kotlin/androidx/compose/material3/adaptive/layout/ThreePaneScaffoldValueTest.kt
similarity index 100%
rename from compose/material3/adaptive/adaptive-layout/src/androidUnitTest/kotlin/androidx/compose/material3/adaptive/layout/ThreePaneScaffoldValueTest.kt
rename to compose/material3/adaptive/adaptive-layout/src/androidHostTest/kotlin/androidx/compose/material3/adaptive/layout/ThreePaneScaffoldValueTest.kt
diff --git a/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-af/strings.xml b/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-af/strings.xml
index 3081ff8..9dffb99 100644
--- a/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-af/strings.xml
+++ b/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-af/strings.xml
@@ -17,12 +17,9 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <!-- no translation found for m3_adaptive_default_pane_title_primary (4435202124665670898) -->
-    <skip />
-    <!-- no translation found for m3_adaptive_default_pane_title_secondary (5571153069654173825) -->
-    <skip />
-    <!-- no translation found for m3_adaptive_default_pane_title_tertiary (4618411484428250300) -->
-    <skip />
+    <string name="m3_adaptive_default_pane_title_primary" msgid="4435202124665670898">"Primêre paneel"</string>
+    <string name="m3_adaptive_default_pane_title_secondary" msgid="5571153069654173825">"Sekondêre paneel"</string>
+    <string name="m3_adaptive_default_pane_title_tertiary" msgid="4618411484428250300">"Tersiêre paneel"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_content_description" msgid="9058489142432490820">"Sleephandvatsel van paneeluitbreiding"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_state_description" msgid="3470811934112444098">"Huidige paneelverdeling, %s"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_action_description" msgid="9031621431415014327">"Verander paneelverdeling na %s"</string>
diff --git a/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-am/strings.xml b/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-am/strings.xml
index c73083c..e04175c 100644
--- a/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-am/strings.xml
+++ b/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-am/strings.xml
@@ -17,12 +17,9 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <!-- no translation found for m3_adaptive_default_pane_title_primary (4435202124665670898) -->
-    <skip />
-    <!-- no translation found for m3_adaptive_default_pane_title_secondary (5571153069654173825) -->
-    <skip />
-    <!-- no translation found for m3_adaptive_default_pane_title_tertiary (4618411484428250300) -->
-    <skip />
+    <string name="m3_adaptive_default_pane_title_primary" msgid="4435202124665670898">"ዋና ፔን"</string>
+    <string name="m3_adaptive_default_pane_title_secondary" msgid="5571153069654173825">"ሁለተኛ ፔን"</string>
+    <string name="m3_adaptive_default_pane_title_tertiary" msgid="4618411484428250300">"ሦስተኛ ፔን"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_content_description" msgid="9058489142432490820">"የፔን መዘርጋት መያዣ ይጎትቱ"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_state_description" msgid="3470811934112444098">"የአሁን ፔን መከፋፈል፣ %s"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_action_description" msgid="9031621431415014327">"ፔን መከፋፈልን ወደ %s ይለውጡ"</string>
diff --git a/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-ar/strings.xml b/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-ar/strings.xml
index 0ae1ec5..84c5dc6 100644
--- a/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-ar/strings.xml
+++ b/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-ar/strings.xml
@@ -17,12 +17,9 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <!-- no translation found for m3_adaptive_default_pane_title_primary (4435202124665670898) -->
-    <skip />
-    <!-- no translation found for m3_adaptive_default_pane_title_secondary (5571153069654173825) -->
-    <skip />
-    <!-- no translation found for m3_adaptive_default_pane_title_tertiary (4618411484428250300) -->
-    <skip />
+    <string name="m3_adaptive_default_pane_title_primary" msgid="4435202124665670898">"اللوحة الأساسية"</string>
+    <string name="m3_adaptive_default_pane_title_secondary" msgid="5571153069654173825">"اللوحة الثانوية"</string>
+    <string name="m3_adaptive_default_pane_title_tertiary" msgid="4618411484428250300">"اللوحة التكميلية"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_content_description" msgid="9058489142432490820">"مقبض السحب لتوسيع اللوحة"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_state_description" msgid="3470811934112444098">"‏حالة تقسيم اللوحة الحالية: %s"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_action_description" msgid="9031621431415014327">"‏تغيير نسبة تقسيم اللوحة إلى %s"</string>
diff --git a/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-as/strings.xml b/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-as/strings.xml
index de29bab..70caeae 100644
--- a/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-as/strings.xml
+++ b/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-as/strings.xml
@@ -17,12 +17,9 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <!-- no translation found for m3_adaptive_default_pane_title_primary (4435202124665670898) -->
-    <skip />
-    <!-- no translation found for m3_adaptive_default_pane_title_secondary (5571153069654173825) -->
-    <skip />
-    <!-- no translation found for m3_adaptive_default_pane_title_tertiary (4618411484428250300) -->
-    <skip />
+    <string name="m3_adaptive_default_pane_title_primary" msgid="4435202124665670898">"প্ৰাথমিক পে’ন"</string>
+    <string name="m3_adaptive_default_pane_title_secondary" msgid="5571153069654173825">"গৌণ পে’ন"</string>
+    <string name="m3_adaptive_default_pane_title_tertiary" msgid="4618411484428250300">"তৃতীয় স্তৰৰ পে’ন"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_content_description" msgid="9058489142432490820">"পে’ন সম্প্ৰসাৰণ কৰিবলৈ টনা হেণ্ডেল"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_state_description" msgid="3470811934112444098">"বৰ্তমানৰ পে’নৰ বিভাজন, %s"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_action_description" msgid="9031621431415014327">"পে’নৰ বিভাজন %sলৈ সলনি কৰক"</string>
diff --git a/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-az/strings.xml b/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-az/strings.xml
index c380e2a..b11d810 100644
--- a/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-az/strings.xml
+++ b/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-az/strings.xml
@@ -17,12 +17,9 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <!-- no translation found for m3_adaptive_default_pane_title_primary (4435202124665670898) -->
-    <skip />
-    <!-- no translation found for m3_adaptive_default_pane_title_secondary (5571153069654173825) -->
-    <skip />
-    <!-- no translation found for m3_adaptive_default_pane_title_tertiary (4618411484428250300) -->
-    <skip />
+    <string name="m3_adaptive_default_pane_title_primary" msgid="4435202124665670898">"Əsas panel"</string>
+    <string name="m3_adaptive_default_pane_title_secondary" msgid="5571153069654173825">"İkinci dərəcəli panel"</string>
+    <string name="m3_adaptive_default_pane_title_tertiary" msgid="4618411484428250300">"Üçüncü dərəcəli panel"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_content_description" msgid="9058489142432490820">"Panelin genişləndirilməsi üçün sürükləmə tutacağı"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_state_description" msgid="3470811934112444098">"Cari panel bölünməsi, %s"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_action_description" msgid="9031621431415014327">"Panel bölgüsünü %s olaraq dəyişin"</string>
diff --git a/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-b+sr+Latn/strings.xml b/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-b+sr+Latn/strings.xml
index adb8b19..58579bb 100644
--- a/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-b+sr+Latn/strings.xml
+++ b/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-b+sr+Latn/strings.xml
@@ -17,12 +17,9 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <!-- no translation found for m3_adaptive_default_pane_title_primary (4435202124665670898) -->
-    <skip />
-    <!-- no translation found for m3_adaptive_default_pane_title_secondary (5571153069654173825) -->
-    <skip />
-    <!-- no translation found for m3_adaptive_default_pane_title_tertiary (4618411484428250300) -->
-    <skip />
+    <string name="m3_adaptive_default_pane_title_primary" msgid="4435202124665670898">"Primarno okno"</string>
+    <string name="m3_adaptive_default_pane_title_secondary" msgid="5571153069654173825">"Sekundarno okno"</string>
+    <string name="m3_adaptive_default_pane_title_tertiary" msgid="4618411484428250300">"Tercijarno okno"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_content_description" msgid="9058489142432490820">"Marker za prevlačenje kojim se proširuje okno"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_state_description" msgid="3470811934112444098">"Trenutno podeljeno okno, %s"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_action_description" msgid="9031621431415014327">"Promenite podeljeno okno na: %s"</string>
diff --git a/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-be/strings.xml b/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-be/strings.xml
index b6a6110..081eb86 100644
--- a/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-be/strings.xml
+++ b/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-be/strings.xml
@@ -17,12 +17,9 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <!-- no translation found for m3_adaptive_default_pane_title_primary (4435202124665670898) -->
-    <skip />
-    <!-- no translation found for m3_adaptive_default_pane_title_secondary (5571153069654173825) -->
-    <skip />
-    <!-- no translation found for m3_adaptive_default_pane_title_tertiary (4618411484428250300) -->
-    <skip />
+    <string name="m3_adaptive_default_pane_title_primary" msgid="4435202124665670898">"Асноўная панэль"</string>
+    <string name="m3_adaptive_default_pane_title_secondary" msgid="5571153069654173825">"Панэль другога ўзроўню"</string>
+    <string name="m3_adaptive_default_pane_title_tertiary" msgid="4618411484428250300">"Панэль трэцяга ўзроўню"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_content_description" msgid="9058489142432490820">"Маркер перацягвання для разгортвання панэлі"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_state_description" msgid="3470811934112444098">"Бягучае раздзяленне панэлі, %s"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_action_description" msgid="9031621431415014327">"Змяніць раздзяленне панэлі на %s"</string>
diff --git a/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-bg/strings.xml b/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-bg/strings.xml
index 6f520a36..7f2812b 100644
--- a/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-bg/strings.xml
+++ b/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-bg/strings.xml
@@ -17,12 +17,9 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <!-- no translation found for m3_adaptive_default_pane_title_primary (4435202124665670898) -->
-    <skip />
-    <!-- no translation found for m3_adaptive_default_pane_title_secondary (5571153069654173825) -->
-    <skip />
-    <!-- no translation found for m3_adaptive_default_pane_title_tertiary (4618411484428250300) -->
-    <skip />
+    <string name="m3_adaptive_default_pane_title_primary" msgid="4435202124665670898">"Основен панел"</string>
+    <string name="m3_adaptive_default_pane_title_secondary" msgid="5571153069654173825">"Вторичен панел"</string>
+    <string name="m3_adaptive_default_pane_title_tertiary" msgid="4618411484428250300">"Третичен панел"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_content_description" msgid="9058489142432490820">"Манипулатор за преместване с плъзгане за разширяване на панела"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_state_description" msgid="3470811934112444098">"Текущо разделяне на панела – %s"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_action_description" msgid="9031621431415014327">"Промяна на разделянето на панела на %s"</string>
diff --git a/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-bn/strings.xml b/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-bn/strings.xml
index a4de865..d0a798b 100644
--- a/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-bn/strings.xml
+++ b/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-bn/strings.xml
@@ -17,12 +17,9 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <!-- no translation found for m3_adaptive_default_pane_title_primary (4435202124665670898) -->
-    <skip />
-    <!-- no translation found for m3_adaptive_default_pane_title_secondary (5571153069654173825) -->
-    <skip />
-    <!-- no translation found for m3_adaptive_default_pane_title_tertiary (4618411484428250300) -->
-    <skip />
+    <string name="m3_adaptive_default_pane_title_primary" msgid="4435202124665670898">"প্রাথমিক প্যানেল"</string>
+    <string name="m3_adaptive_default_pane_title_secondary" msgid="5571153069654173825">"সেকেন্ডারি প্যানেল"</string>
+    <string name="m3_adaptive_default_pane_title_tertiary" msgid="4618411484428250300">"টার্শিয়ারি প্যানেল"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_content_description" msgid="9058489142432490820">"প্যানেল বড় করার টেনে আনার হ্যান্ডেল"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_state_description" msgid="3470811934112444098">"প্যানেল স্প্লিটের বর্তমান স্ট্যাটাস %s"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_action_description" msgid="9031621431415014327">"প্যানেল স্প্লিট %s-এ পরিবর্তন করুন"</string>
diff --git a/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-bs/strings.xml b/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-bs/strings.xml
index c6ec7ba..a3280d3 100644
--- a/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-bs/strings.xml
+++ b/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-bs/strings.xml
@@ -17,12 +17,9 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <!-- no translation found for m3_adaptive_default_pane_title_primary (4435202124665670898) -->
-    <skip />
-    <!-- no translation found for m3_adaptive_default_pane_title_secondary (5571153069654173825) -->
-    <skip />
-    <!-- no translation found for m3_adaptive_default_pane_title_tertiary (4618411484428250300) -->
-    <skip />
+    <string name="m3_adaptive_default_pane_title_primary" msgid="4435202124665670898">"Primarno okno"</string>
+    <string name="m3_adaptive_default_pane_title_secondary" msgid="5571153069654173825">"Sekundarno okno"</string>
+    <string name="m3_adaptive_default_pane_title_tertiary" msgid="4618411484428250300">"Tercijarno okno"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_content_description" msgid="9058489142432490820">"Ručica za prevlačenje radi proširenja okna"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_state_description" msgid="3470811934112444098">"Trenutna podjela okna, %s"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_action_description" msgid="9031621431415014327">"Promjena podijeljenog okna na %s"</string>
diff --git a/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-ca/strings.xml b/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-ca/strings.xml
index 5481c33..1a833e6 100644
--- a/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-ca/strings.xml
+++ b/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-ca/strings.xml
@@ -17,12 +17,9 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <!-- no translation found for m3_adaptive_default_pane_title_primary (4435202124665670898) -->
-    <skip />
-    <!-- no translation found for m3_adaptive_default_pane_title_secondary (5571153069654173825) -->
-    <skip />
-    <!-- no translation found for m3_adaptive_default_pane_title_tertiary (4618411484428250300) -->
-    <skip />
+    <string name="m3_adaptive_default_pane_title_primary" msgid="4435202124665670898">"Subfinestra principal"</string>
+    <string name="m3_adaptive_default_pane_title_secondary" msgid="5571153069654173825">"Subfinestra secundària"</string>
+    <string name="m3_adaptive_default_pane_title_tertiary" msgid="4618411484428250300">"Subfinestra terciària"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_content_description" msgid="9058489142432490820">"Ansa per arrossegar l\'expansió de la subfinestra"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_state_description" msgid="3470811934112444098">"Divisió de la subfinestra actual, %s"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_action_description" msgid="9031621431415014327">"Canvia la divisió de la subfinestra a %s"</string>
diff --git a/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-cs/strings.xml b/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-cs/strings.xml
index ef1531b..59a745a 100644
--- a/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-cs/strings.xml
+++ b/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-cs/strings.xml
@@ -17,12 +17,9 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <!-- no translation found for m3_adaptive_default_pane_title_primary (4435202124665670898) -->
-    <skip />
-    <!-- no translation found for m3_adaptive_default_pane_title_secondary (5571153069654173825) -->
-    <skip />
-    <!-- no translation found for m3_adaptive_default_pane_title_tertiary (4618411484428250300) -->
-    <skip />
+    <string name="m3_adaptive_default_pane_title_primary" msgid="4435202124665670898">"Primární panel"</string>
+    <string name="m3_adaptive_default_pane_title_secondary" msgid="5571153069654173825">"Sekundární panel"</string>
+    <string name="m3_adaptive_default_pane_title_tertiary" msgid="4618411484428250300">"Terciární panel"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_content_description" msgid="9058489142432490820">"Úchyt pro přetažení a rozbalení panelu"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_state_description" msgid="3470811934112444098">"Aktuální rozdělení panelu, %s"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_action_description" msgid="9031621431415014327">"Změnit rozdělení panelu na %s"</string>
diff --git a/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-da/strings.xml b/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-da/strings.xml
index 7861aa0..3da0c9f 100644
--- a/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-da/strings.xml
+++ b/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-da/strings.xml
@@ -17,12 +17,9 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <!-- no translation found for m3_adaptive_default_pane_title_primary (4435202124665670898) -->
-    <skip />
-    <!-- no translation found for m3_adaptive_default_pane_title_secondary (5571153069654173825) -->
-    <skip />
-    <!-- no translation found for m3_adaptive_default_pane_title_tertiary (4618411484428250300) -->
-    <skip />
+    <string name="m3_adaptive_default_pane_title_primary" msgid="4435202124665670898">"Primær rude"</string>
+    <string name="m3_adaptive_default_pane_title_secondary" msgid="5571153069654173825">"Sekundær rude"</string>
+    <string name="m3_adaptive_default_pane_title_tertiary" msgid="4618411484428250300">"Tertiær rude"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_content_description" msgid="9058489142432490820">"Håndtag til udvidelse af rude"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_state_description" msgid="3470811934112444098">"Aktuel rudeopdeling, %s"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_action_description" msgid="9031621431415014327">"Skift rudeopdeling til %s"</string>
diff --git a/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-de/strings.xml b/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-de/strings.xml
index 34a320e..89c6432 100644
--- a/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-de/strings.xml
+++ b/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-de/strings.xml
@@ -17,12 +17,9 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <!-- no translation found for m3_adaptive_default_pane_title_primary (4435202124665670898) -->
-    <skip />
-    <!-- no translation found for m3_adaptive_default_pane_title_secondary (5571153069654173825) -->
-    <skip />
-    <!-- no translation found for m3_adaptive_default_pane_title_tertiary (4618411484428250300) -->
-    <skip />
+    <string name="m3_adaptive_default_pane_title_primary" msgid="4435202124665670898">"Primärer Bereich"</string>
+    <string name="m3_adaptive_default_pane_title_secondary" msgid="5571153069654173825">"Sekundärer Bereich"</string>
+    <string name="m3_adaptive_default_pane_title_tertiary" msgid="4618411484428250300">"Tertiärer Bereich"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_content_description" msgid="9058489142432490820">"Ziehpunkt zum Maximieren des Bereichs"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_state_description" msgid="3470811934112444098">"Aktueller Bereich geteilt, %s"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_action_description" msgid="9031621431415014327">"„Fenster teilen“ in %s ändern"</string>
diff --git a/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-el/strings.xml b/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-el/strings.xml
index 342361f..091ed04 100644
--- a/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-el/strings.xml
+++ b/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-el/strings.xml
@@ -17,12 +17,9 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <!-- no translation found for m3_adaptive_default_pane_title_primary (4435202124665670898) -->
-    <skip />
-    <!-- no translation found for m3_adaptive_default_pane_title_secondary (5571153069654173825) -->
-    <skip />
-    <!-- no translation found for m3_adaptive_default_pane_title_tertiary (4618411484428250300) -->
-    <skip />
+    <string name="m3_adaptive_default_pane_title_primary" msgid="4435202124665670898">"Κύριο πλαίσιο"</string>
+    <string name="m3_adaptive_default_pane_title_secondary" msgid="5571153069654173825">"Δευτερεύον πλαίσιο"</string>
+    <string name="m3_adaptive_default_pane_title_tertiary" msgid="4618411484428250300">"Τριτεύον πλαίσιο"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_content_description" msgid="9058489142432490820">"Λαβή μεταφοράς επέκτασης πλαισίου"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_state_description" msgid="3470811934112444098">"Τρέχων επιμερισμός πλαισίου, %s"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_action_description" msgid="9031621431415014327">"Αλλαγή επιμερισμού πλαισίου σε %s"</string>
diff --git a/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-en-rAU/strings.xml b/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-en-rAU/strings.xml
index a427d2c..3e0939b 100644
--- a/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-en-rAU/strings.xml
+++ b/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-en-rAU/strings.xml
@@ -17,12 +17,9 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <!-- no translation found for m3_adaptive_default_pane_title_primary (4435202124665670898) -->
-    <skip />
-    <!-- no translation found for m3_adaptive_default_pane_title_secondary (5571153069654173825) -->
-    <skip />
-    <!-- no translation found for m3_adaptive_default_pane_title_tertiary (4618411484428250300) -->
-    <skip />
+    <string name="m3_adaptive_default_pane_title_primary" msgid="4435202124665670898">"Primary pane"</string>
+    <string name="m3_adaptive_default_pane_title_secondary" msgid="5571153069654173825">"Secondary pane"</string>
+    <string name="m3_adaptive_default_pane_title_tertiary" msgid="4618411484428250300">"Tertiary pane"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_content_description" msgid="9058489142432490820">"Pane expansion drag handle"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_state_description" msgid="3470811934112444098">"Current pane split, %s"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_action_description" msgid="9031621431415014327">"Change pane split to %s"</string>
diff --git a/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-en-rGB/strings.xml b/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-en-rGB/strings.xml
index a427d2c..3e0939b 100644
--- a/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-en-rGB/strings.xml
+++ b/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-en-rGB/strings.xml
@@ -17,12 +17,9 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <!-- no translation found for m3_adaptive_default_pane_title_primary (4435202124665670898) -->
-    <skip />
-    <!-- no translation found for m3_adaptive_default_pane_title_secondary (5571153069654173825) -->
-    <skip />
-    <!-- no translation found for m3_adaptive_default_pane_title_tertiary (4618411484428250300) -->
-    <skip />
+    <string name="m3_adaptive_default_pane_title_primary" msgid="4435202124665670898">"Primary pane"</string>
+    <string name="m3_adaptive_default_pane_title_secondary" msgid="5571153069654173825">"Secondary pane"</string>
+    <string name="m3_adaptive_default_pane_title_tertiary" msgid="4618411484428250300">"Tertiary pane"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_content_description" msgid="9058489142432490820">"Pane expansion drag handle"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_state_description" msgid="3470811934112444098">"Current pane split, %s"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_action_description" msgid="9031621431415014327">"Change pane split to %s"</string>
diff --git a/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-en-rIN/strings.xml b/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-en-rIN/strings.xml
index a427d2c..3e0939b 100644
--- a/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-en-rIN/strings.xml
+++ b/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-en-rIN/strings.xml
@@ -17,12 +17,9 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <!-- no translation found for m3_adaptive_default_pane_title_primary (4435202124665670898) -->
-    <skip />
-    <!-- no translation found for m3_adaptive_default_pane_title_secondary (5571153069654173825) -->
-    <skip />
-    <!-- no translation found for m3_adaptive_default_pane_title_tertiary (4618411484428250300) -->
-    <skip />
+    <string name="m3_adaptive_default_pane_title_primary" msgid="4435202124665670898">"Primary pane"</string>
+    <string name="m3_adaptive_default_pane_title_secondary" msgid="5571153069654173825">"Secondary pane"</string>
+    <string name="m3_adaptive_default_pane_title_tertiary" msgid="4618411484428250300">"Tertiary pane"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_content_description" msgid="9058489142432490820">"Pane expansion drag handle"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_state_description" msgid="3470811934112444098">"Current pane split, %s"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_action_description" msgid="9031621431415014327">"Change pane split to %s"</string>
diff --git a/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-es-rUS/strings.xml b/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-es-rUS/strings.xml
index a9ac137..71f40c6 100644
--- a/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-es-rUS/strings.xml
+++ b/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-es-rUS/strings.xml
@@ -17,12 +17,9 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <!-- no translation found for m3_adaptive_default_pane_title_primary (4435202124665670898) -->
-    <skip />
-    <!-- no translation found for m3_adaptive_default_pane_title_secondary (5571153069654173825) -->
-    <skip />
-    <!-- no translation found for m3_adaptive_default_pane_title_tertiary (4618411484428250300) -->
-    <skip />
+    <string name="m3_adaptive_default_pane_title_primary" msgid="4435202124665670898">"Panel principal"</string>
+    <string name="m3_adaptive_default_pane_title_secondary" msgid="5571153069654173825">"Panel secundario"</string>
+    <string name="m3_adaptive_default_pane_title_tertiary" msgid="4618411484428250300">"Panel terciario"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_content_description" msgid="9058489142432490820">"Controlador de arrastre para expandir el panel"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_state_description" msgid="3470811934112444098">"División actual del panel, %s"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_action_description" msgid="9031621431415014327">"Cambiar la división del panel a %s"</string>
diff --git a/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-es/strings.xml b/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-es/strings.xml
index 9cbd449..44b6668 100644
--- a/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-es/strings.xml
+++ b/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-es/strings.xml
@@ -17,12 +17,9 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <!-- no translation found for m3_adaptive_default_pane_title_primary (4435202124665670898) -->
-    <skip />
-    <!-- no translation found for m3_adaptive_default_pane_title_secondary (5571153069654173825) -->
-    <skip />
-    <!-- no translation found for m3_adaptive_default_pane_title_tertiary (4618411484428250300) -->
-    <skip />
+    <string name="m3_adaptive_default_pane_title_primary" msgid="4435202124665670898">"Panel principal"</string>
+    <string name="m3_adaptive_default_pane_title_secondary" msgid="5571153069654173825">"Panel secundario"</string>
+    <string name="m3_adaptive_default_pane_title_tertiary" msgid="4618411484428250300">"Panel terciario"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_content_description" msgid="9058489142432490820">"Controlador de arrastre para expandir el panel"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_state_description" msgid="3470811934112444098">"División de panel actual, %s"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_action_description" msgid="9031621431415014327">"Cambiar división de panel a %s"</string>
diff --git a/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-et/strings.xml b/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-et/strings.xml
index 02850fc..eb59f00 100644
--- a/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-et/strings.xml
+++ b/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-et/strings.xml
@@ -17,12 +17,9 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <!-- no translation found for m3_adaptive_default_pane_title_primary (4435202124665670898) -->
-    <skip />
-    <!-- no translation found for m3_adaptive_default_pane_title_secondary (5571153069654173825) -->
-    <skip />
-    <!-- no translation found for m3_adaptive_default_pane_title_tertiary (4618411484428250300) -->
-    <skip />
+    <string name="m3_adaptive_default_pane_title_primary" msgid="4435202124665670898">"Põhipaan"</string>
+    <string name="m3_adaptive_default_pane_title_secondary" msgid="5571153069654173825">"Teisene paan"</string>
+    <string name="m3_adaptive_default_pane_title_tertiary" msgid="4618411484428250300">"Kolmas paan"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_content_description" msgid="9058489142432490820">"Paani laiendamise lohistamispide"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_state_description" msgid="3470811934112444098">"Praegune paani jaotus, %s"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_action_description" msgid="9031621431415014327">"Muutke jaotatud paan väärtusele %s"</string>
diff --git a/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-eu/strings.xml b/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-eu/strings.xml
index 5b14ac7..11856a3 100644
--- a/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-eu/strings.xml
+++ b/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-eu/strings.xml
@@ -17,12 +17,9 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <!-- no translation found for m3_adaptive_default_pane_title_primary (4435202124665670898) -->
-    <skip />
-    <!-- no translation found for m3_adaptive_default_pane_title_secondary (5571153069654173825) -->
-    <skip />
-    <!-- no translation found for m3_adaptive_default_pane_title_tertiary (4618411484428250300) -->
-    <skip />
+    <string name="m3_adaptive_default_pane_title_primary" msgid="4435202124665670898">"Panel nagusia"</string>
+    <string name="m3_adaptive_default_pane_title_secondary" msgid="5571153069654173825">"Bigarren mailako panela"</string>
+    <string name="m3_adaptive_default_pane_title_tertiary" msgid="4618411484428250300">"Hirugarren mailako panela"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_content_description" msgid="9058489142432490820">"Panelaren zabalera arrastatzeko kontrol-puntua"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_state_description" msgid="3470811934112444098">"Oraingo panela zatituta dago, %s"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_action_description" msgid="9031621431415014327">"Aldatu panelaren zatiketa eta ezarri %s"</string>
diff --git a/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-fa/strings.xml b/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-fa/strings.xml
index f88ed80..dd18f0e 100644
--- a/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-fa/strings.xml
+++ b/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-fa/strings.xml
@@ -17,12 +17,9 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <!-- no translation found for m3_adaptive_default_pane_title_primary (4435202124665670898) -->
-    <skip />
-    <!-- no translation found for m3_adaptive_default_pane_title_secondary (5571153069654173825) -->
-    <skip />
-    <!-- no translation found for m3_adaptive_default_pane_title_tertiary (4618411484428250300) -->
-    <skip />
+    <string name="m3_adaptive_default_pane_title_primary" msgid="4435202124665670898">"قاب اصلی"</string>
+    <string name="m3_adaptive_default_pane_title_secondary" msgid="5571153069654173825">"قاب دوم"</string>
+    <string name="m3_adaptive_default_pane_title_tertiary" msgid="4618411484428250300">"قاب سوم"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_content_description" msgid="9058489142432490820">"دستگیره کشاندن برای از هم بازکردن اندازه قاب"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_state_description" msgid="3470811934112444098">"‏حالت فعلی تقسیم قاب، %s"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_action_description" msgid="9031621431415014327">"‏تقسیم‌بندی قاب به %s تغییر کند"</string>
diff --git a/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-fi/strings.xml b/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-fi/strings.xml
index 8762e7a..059cad7 100644
--- a/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-fi/strings.xml
+++ b/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-fi/strings.xml
@@ -17,12 +17,9 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <!-- no translation found for m3_adaptive_default_pane_title_primary (4435202124665670898) -->
-    <skip />
-    <!-- no translation found for m3_adaptive_default_pane_title_secondary (5571153069654173825) -->
-    <skip />
-    <!-- no translation found for m3_adaptive_default_pane_title_tertiary (4618411484428250300) -->
-    <skip />
+    <string name="m3_adaptive_default_pane_title_primary" msgid="4435202124665670898">"Ensisijainen ruutu"</string>
+    <string name="m3_adaptive_default_pane_title_secondary" msgid="5571153069654173825">"Toissijainen ruutu"</string>
+    <string name="m3_adaptive_default_pane_title_tertiary" msgid="4618411484428250300">"Kolmas ruutu"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_content_description" msgid="9058489142432490820">"Ruudun laajennusvetokahva"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_state_description" msgid="3470811934112444098">"Nykyinen ruudun jako, %s"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_action_description" msgid="9031621431415014327">"Muuta ruudun jaoksi %s"</string>
diff --git a/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-fr-rCA/strings.xml b/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-fr-rCA/strings.xml
index d5eb3b7..5ceb5d5 100644
--- a/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-fr-rCA/strings.xml
+++ b/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-fr-rCA/strings.xml
@@ -17,12 +17,9 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <!-- no translation found for m3_adaptive_default_pane_title_primary (4435202124665670898) -->
-    <skip />
-    <!-- no translation found for m3_adaptive_default_pane_title_secondary (5571153069654173825) -->
-    <skip />
-    <!-- no translation found for m3_adaptive_default_pane_title_tertiary (4618411484428250300) -->
-    <skip />
+    <string name="m3_adaptive_default_pane_title_primary" msgid="4435202124665670898">"Volet principal"</string>
+    <string name="m3_adaptive_default_pane_title_secondary" msgid="5571153069654173825">"Volet secondaire"</string>
+    <string name="m3_adaptive_default_pane_title_tertiary" msgid="4618411484428250300">"Volet tertiaire"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_content_description" msgid="9058489142432490820">"Poignée de déplacement d\'extension du volet"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_state_description" msgid="3470811934112444098">"Volet actuel divisé, %s"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_action_description" msgid="9031621431415014327">"Modifiez la division du volet à %s"</string>
diff --git a/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-fr/strings.xml b/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-fr/strings.xml
index 7a95805..16ae8f9 100644
--- a/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-fr/strings.xml
+++ b/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-fr/strings.xml
@@ -17,12 +17,9 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <!-- no translation found for m3_adaptive_default_pane_title_primary (4435202124665670898) -->
-    <skip />
-    <!-- no translation found for m3_adaptive_default_pane_title_secondary (5571153069654173825) -->
-    <skip />
-    <!-- no translation found for m3_adaptive_default_pane_title_tertiary (4618411484428250300) -->
-    <skip />
+    <string name="m3_adaptive_default_pane_title_primary" msgid="4435202124665670898">"Volet principal"</string>
+    <string name="m3_adaptive_default_pane_title_secondary" msgid="5571153069654173825">"Volet secondaire"</string>
+    <string name="m3_adaptive_default_pane_title_tertiary" msgid="4618411484428250300">"Volet tertiaire"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_content_description" msgid="9058489142432490820">"Poignée de déplacement pour développer les volets"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_state_description" msgid="3470811934112444098">"Répartition actuelle des volets, %s"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_action_description" msgid="9031621431415014327">"Passer la répartition des volets sur %s"</string>
diff --git a/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-gl/strings.xml b/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-gl/strings.xml
index 490dfb4..48eb550 100644
--- a/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-gl/strings.xml
+++ b/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-gl/strings.xml
@@ -17,12 +17,9 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <!-- no translation found for m3_adaptive_default_pane_title_primary (4435202124665670898) -->
-    <skip />
-    <!-- no translation found for m3_adaptive_default_pane_title_secondary (5571153069654173825) -->
-    <skip />
-    <!-- no translation found for m3_adaptive_default_pane_title_tertiary (4618411484428250300) -->
-    <skip />
+    <string name="m3_adaptive_default_pane_title_primary" msgid="4435202124665670898">"Panel principal"</string>
+    <string name="m3_adaptive_default_pane_title_secondary" msgid="5571153069654173825">"Panel secundario"</string>
+    <string name="m3_adaptive_default_pane_title_tertiary" msgid="4618411484428250300">"Panel terciario"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_content_description" msgid="9058489142432490820">"Controlador de arrastre para despregar o panel"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_state_description" msgid="3470811934112444098">"División actual do panel, %s"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_action_description" msgid="9031621431415014327">"Cambia o panel dividido a %s"</string>
diff --git a/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-gu/strings.xml b/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-gu/strings.xml
index 34d4558..63e7408 100644
--- a/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-gu/strings.xml
+++ b/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-gu/strings.xml
@@ -17,12 +17,9 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <!-- no translation found for m3_adaptive_default_pane_title_primary (4435202124665670898) -->
-    <skip />
-    <!-- no translation found for m3_adaptive_default_pane_title_secondary (5571153069654173825) -->
-    <skip />
-    <!-- no translation found for m3_adaptive_default_pane_title_tertiary (4618411484428250300) -->
-    <skip />
+    <string name="m3_adaptive_default_pane_title_primary" msgid="4435202124665670898">"પ્રાથમિક વિભાગ"</string>
+    <string name="m3_adaptive_default_pane_title_secondary" msgid="5571153069654173825">"ગૌણ વિભાગ"</string>
+    <string name="m3_adaptive_default_pane_title_tertiary" msgid="4618411484428250300">"તૃતીય વિભાગ"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_content_description" msgid="9058489142432490820">"વિભાગ વિસ્તરણ માટે ઑબ્જેક્ટ ખેંચવાનું હૅન્ડલ"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_state_description" msgid="3470811934112444098">"વર્તમાન વિભાગ વિભાજન, %s"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_action_description" msgid="9031621431415014327">"વિભાગ વિભાજનને %s પર બદલો"</string>
diff --git a/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-hi/strings.xml b/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-hi/strings.xml
index 84d8ed3..168de78 100644
--- a/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-hi/strings.xml
+++ b/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-hi/strings.xml
@@ -17,12 +17,9 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <!-- no translation found for m3_adaptive_default_pane_title_primary (4435202124665670898) -->
-    <skip />
-    <!-- no translation found for m3_adaptive_default_pane_title_secondary (5571153069654173825) -->
-    <skip />
-    <!-- no translation found for m3_adaptive_default_pane_title_tertiary (4618411484428250300) -->
-    <skip />
+    <string name="m3_adaptive_default_pane_title_primary" msgid="4435202124665670898">"प्राइमरी पैनल"</string>
+    <string name="m3_adaptive_default_pane_title_secondary" msgid="5571153069654173825">"सेकंडरी पैनल"</string>
+    <string name="m3_adaptive_default_pane_title_tertiary" msgid="4618411484428250300">"टर्शरी पैनल"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_content_description" msgid="9058489142432490820">"पैनल को बड़ा करने के लिए, खींचकर छोड़ने वाला हैंडल"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_state_description" msgid="3470811934112444098">"पैनल स्प्लिट की मौजूदा स्थिति, %s"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_action_description" msgid="9031621431415014327">"पैनल स्प्लिट को %s में बदलें"</string>
diff --git a/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-hr/strings.xml b/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-hr/strings.xml
index a8abd25..96a7559 100644
--- a/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-hr/strings.xml
+++ b/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-hr/strings.xml
@@ -17,12 +17,9 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <!-- no translation found for m3_adaptive_default_pane_title_primary (4435202124665670898) -->
-    <skip />
-    <!-- no translation found for m3_adaptive_default_pane_title_secondary (5571153069654173825) -->
-    <skip />
-    <!-- no translation found for m3_adaptive_default_pane_title_tertiary (4618411484428250300) -->
-    <skip />
+    <string name="m3_adaptive_default_pane_title_primary" msgid="4435202124665670898">"Primarno okno"</string>
+    <string name="m3_adaptive_default_pane_title_secondary" msgid="5571153069654173825">"Sekundarno okno"</string>
+    <string name="m3_adaptive_default_pane_title_tertiary" msgid="4618411484428250300">"Tercijarno okno"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_content_description" msgid="9058489142432490820">"Marker za povlačenje proširenja okna"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_state_description" msgid="3470811934112444098">"Trenutačna podjela okna, %s"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_action_description" msgid="9031621431415014327">"Promijeni podjelu okna u: %s"</string>
diff --git a/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-hu/strings.xml b/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-hu/strings.xml
index ec6522b..ba48f17 100644
--- a/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-hu/strings.xml
+++ b/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-hu/strings.xml
@@ -17,12 +17,9 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <!-- no translation found for m3_adaptive_default_pane_title_primary (4435202124665670898) -->
-    <skip />
-    <!-- no translation found for m3_adaptive_default_pane_title_secondary (5571153069654173825) -->
-    <skip />
-    <!-- no translation found for m3_adaptive_default_pane_title_tertiary (4618411484428250300) -->
-    <skip />
+    <string name="m3_adaptive_default_pane_title_primary" msgid="4435202124665670898">"Elsődleges panel"</string>
+    <string name="m3_adaptive_default_pane_title_secondary" msgid="5571153069654173825">"Másodlagos panel"</string>
+    <string name="m3_adaptive_default_pane_title_tertiary" msgid="4618411484428250300">"Harmadlagos panel"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_content_description" msgid="9058489142432490820">"Panel kibontásának fogópontja"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_state_description" msgid="3470811934112444098">"Jelenlegi panelfelosztás, %s"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_action_description" msgid="9031621431415014327">"Panelfelosztás módosítása a következőre: %s"</string>
diff --git a/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-hy/strings.xml b/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-hy/strings.xml
index 02d9949..d01842c 100644
--- a/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-hy/strings.xml
+++ b/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-hy/strings.xml
@@ -17,12 +17,9 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <!-- no translation found for m3_adaptive_default_pane_title_primary (4435202124665670898) -->
-    <skip />
-    <!-- no translation found for m3_adaptive_default_pane_title_secondary (5571153069654173825) -->
-    <skip />
-    <!-- no translation found for m3_adaptive_default_pane_title_tertiary (4618411484428250300) -->
-    <skip />
+    <string name="m3_adaptive_default_pane_title_primary" msgid="4435202124665670898">"Հիմնական փեղկ"</string>
+    <string name="m3_adaptive_default_pane_title_secondary" msgid="5571153069654173825">"Օժանդակ փեղկ"</string>
+    <string name="m3_adaptive_default_pane_title_tertiary" msgid="4618411484428250300">"Լրացուցիչ փեղկ"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_content_description" msgid="9058489142432490820">"Փեղկի ծավալման տեղափոխման նշիչ"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_state_description" msgid="3470811934112444098">"Փեղկերի բաժանման հարաբերակցությունը, %s"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_action_description" msgid="9031621431415014327">"Փեղկի բաժանումը դարձնել %s"</string>
diff --git a/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-in/strings.xml b/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-in/strings.xml
index d7a88c4..b4a0209 100644
--- a/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-in/strings.xml
+++ b/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-in/strings.xml
@@ -17,12 +17,9 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <!-- no translation found for m3_adaptive_default_pane_title_primary (4435202124665670898) -->
-    <skip />
-    <!-- no translation found for m3_adaptive_default_pane_title_secondary (5571153069654173825) -->
-    <skip />
-    <!-- no translation found for m3_adaptive_default_pane_title_tertiary (4618411484428250300) -->
-    <skip />
+    <string name="m3_adaptive_default_pane_title_primary" msgid="4435202124665670898">"Panel utama"</string>
+    <string name="m3_adaptive_default_pane_title_secondary" msgid="5571153069654173825">"Panel sekunder"</string>
+    <string name="m3_adaptive_default_pane_title_tertiary" msgid="4618411484428250300">"Panel tersier"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_content_description" msgid="9058489142432490820">"Handel geser perluasan panel"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_state_description" msgid="3470811934112444098">"Luas panel ganda saat ini, %s"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_action_description" msgid="9031621431415014327">"Ubah luas panel ganda menjadi %s"</string>
diff --git a/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-is/strings.xml b/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-is/strings.xml
index 049b3a8..dcd4b7a 100644
--- a/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-is/strings.xml
+++ b/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-is/strings.xml
@@ -17,12 +17,9 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <!-- no translation found for m3_adaptive_default_pane_title_primary (4435202124665670898) -->
-    <skip />
-    <!-- no translation found for m3_adaptive_default_pane_title_secondary (5571153069654173825) -->
-    <skip />
-    <!-- no translation found for m3_adaptive_default_pane_title_tertiary (4618411484428250300) -->
-    <skip />
+    <string name="m3_adaptive_default_pane_title_primary" msgid="4435202124665670898">"Fyrsti gluggi"</string>
+    <string name="m3_adaptive_default_pane_title_secondary" msgid="5571153069654173825">"Annar gluggi"</string>
+    <string name="m3_adaptive_default_pane_title_tertiary" msgid="4618411484428250300">"Þriðji gluggi"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_content_description" msgid="9058489142432490820">"Dragkló gluggastækkunar"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_state_description" msgid="3470811934112444098">"Núverandi skiptur gluggi, %s"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_action_description" msgid="9031621431415014327">"Breyta gluggaskiptingu í %s"</string>
diff --git a/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-it/strings.xml b/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-it/strings.xml
index 924a735..4d1ecb3 100644
--- a/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-it/strings.xml
+++ b/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-it/strings.xml
@@ -17,12 +17,9 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <!-- no translation found for m3_adaptive_default_pane_title_primary (4435202124665670898) -->
-    <skip />
-    <!-- no translation found for m3_adaptive_default_pane_title_secondary (5571153069654173825) -->
-    <skip />
-    <!-- no translation found for m3_adaptive_default_pane_title_tertiary (4618411484428250300) -->
-    <skip />
+    <string name="m3_adaptive_default_pane_title_primary" msgid="4435202124665670898">"Riquadro principale"</string>
+    <string name="m3_adaptive_default_pane_title_secondary" msgid="5571153069654173825">"Riquadro secondario"</string>
+    <string name="m3_adaptive_default_pane_title_tertiary" msgid="4618411484428250300">"Riquadro terziario"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_content_description" msgid="9058489142432490820">"Punto di trascinamento per l\'espansione del riquadro"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_state_description" msgid="3470811934112444098">"Divisione del riquadro attuale, %s"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_action_description" msgid="9031621431415014327">"Modifica la divisione del riquadro in %s"</string>
diff --git a/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-iw/strings.xml b/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-iw/strings.xml
index 0ed2e6e..0f4a860 100644
--- a/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-iw/strings.xml
+++ b/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-iw/strings.xml
@@ -17,12 +17,9 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <!-- no translation found for m3_adaptive_default_pane_title_primary (4435202124665670898) -->
-    <skip />
-    <!-- no translation found for m3_adaptive_default_pane_title_secondary (5571153069654173825) -->
-    <skip />
-    <!-- no translation found for m3_adaptive_default_pane_title_tertiary (4618411484428250300) -->
-    <skip />
+    <string name="m3_adaptive_default_pane_title_primary" msgid="4435202124665670898">"החלונית הראשית"</string>
+    <string name="m3_adaptive_default_pane_title_secondary" msgid="5571153069654173825">"החלונית המשנית"</string>
+    <string name="m3_adaptive_default_pane_title_tertiary" msgid="4618411484428250300">"החלונית השלישית"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_content_description" msgid="9058489142432490820">"נקודת אחיזה לגרירה להרחבת החלונית"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_state_description" msgid="3470811934112444098">"‏פיצול החלונית הנוכחי, %s"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_action_description" msgid="9031621431415014327">"‏שינוי של פיצול החלונית ל-%s"</string>
diff --git a/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-ja/strings.xml b/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-ja/strings.xml
index ffa1541..ed42569 100644
--- a/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-ja/strings.xml
+++ b/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-ja/strings.xml
@@ -17,12 +17,9 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <!-- no translation found for m3_adaptive_default_pane_title_primary (4435202124665670898) -->
-    <skip />
-    <!-- no translation found for m3_adaptive_default_pane_title_secondary (5571153069654173825) -->
-    <skip />
-    <!-- no translation found for m3_adaptive_default_pane_title_tertiary (4618411484428250300) -->
-    <skip />
+    <string name="m3_adaptive_default_pane_title_primary" msgid="4435202124665670898">"プライマリ ペイン"</string>
+    <string name="m3_adaptive_default_pane_title_secondary" msgid="5571153069654173825">"セカンダリ ペイン"</string>
+    <string name="m3_adaptive_default_pane_title_tertiary" msgid="4618411484428250300">"ターシャリ ペイン"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_content_description" msgid="9058489142432490820">"ペインの展開のドラッグ ハンドル"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_state_description" msgid="3470811934112444098">"現在のペイン分割、%s"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_action_description" msgid="9031621431415014327">"ペインの分割を %s に変更"</string>
diff --git a/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-ka/strings.xml b/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-ka/strings.xml
index df7cb62..f8be6ee 100644
--- a/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-ka/strings.xml
+++ b/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-ka/strings.xml
@@ -17,12 +17,9 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <!-- no translation found for m3_adaptive_default_pane_title_primary (4435202124665670898) -->
-    <skip />
-    <!-- no translation found for m3_adaptive_default_pane_title_secondary (5571153069654173825) -->
-    <skip />
-    <!-- no translation found for m3_adaptive_default_pane_title_tertiary (4618411484428250300) -->
-    <skip />
+    <string name="m3_adaptive_default_pane_title_primary" msgid="4435202124665670898">"ძირითადი არე"</string>
+    <string name="m3_adaptive_default_pane_title_secondary" msgid="5571153069654173825">"მეორეული არე"</string>
+    <string name="m3_adaptive_default_pane_title_tertiary" msgid="4618411484428250300">"მესამეული არე"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_content_description" msgid="9058489142432490820">"არეს გაფართოების სახელური ჩავლებისთვის"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_state_description" msgid="3470811934112444098">"მიმდინარე არის გაყოფა, %s"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_action_description" msgid="9031621431415014327">"არეს გაყოფის შეცვლა %s-ით"</string>
diff --git a/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-kk/strings.xml b/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-kk/strings.xml
index 43b8bb4..f9356c3 100644
--- a/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-kk/strings.xml
+++ b/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-kk/strings.xml
@@ -17,12 +17,9 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <!-- no translation found for m3_adaptive_default_pane_title_primary (4435202124665670898) -->
-    <skip />
-    <!-- no translation found for m3_adaptive_default_pane_title_secondary (5571153069654173825) -->
-    <skip />
-    <!-- no translation found for m3_adaptive_default_pane_title_tertiary (4618411484428250300) -->
-    <skip />
+    <string name="m3_adaptive_default_pane_title_primary" msgid="4435202124665670898">"Негізгі панель"</string>
+    <string name="m3_adaptive_default_pane_title_secondary" msgid="5571153069654173825">"Қосалқы панель"</string>
+    <string name="m3_adaptive_default_pane_title_tertiary" msgid="4618411484428250300">"Үшінші панель"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_content_description" msgid="9058489142432490820">"Панельді жаюға арналған сүйрейтін тетік"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_state_description" msgid="3470811934112444098">"Қазіргі панельді бөлу деңгейі, %s"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_action_description" msgid="9031621431415014327">"Панельді бөлу деңгейін %s етіп өзгерту"</string>
diff --git a/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-km/strings.xml b/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-km/strings.xml
index 3cb1345..dda067a 100644
--- a/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-km/strings.xml
+++ b/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-km/strings.xml
@@ -17,12 +17,9 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <!-- no translation found for m3_adaptive_default_pane_title_primary (4435202124665670898) -->
-    <skip />
-    <!-- no translation found for m3_adaptive_default_pane_title_secondary (5571153069654173825) -->
-    <skip />
-    <!-- no translation found for m3_adaptive_default_pane_title_tertiary (4618411484428250300) -->
-    <skip />
+    <string name="m3_adaptive_default_pane_title_primary" msgid="4435202124665670898">"ផ្ទាំងចម្បង"</string>
+    <string name="m3_adaptive_default_pane_title_secondary" msgid="5571153069654173825">"ផ្ទាំងទីពីរ"</string>
+    <string name="m3_adaptive_default_pane_title_tertiary" msgid="4618411484428250300">"ផ្ទាំងទីបី"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_content_description" msgid="9058489142432490820">"ដង​អូស​ពង្រីកផ្ទាំង"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_state_description" msgid="3470811934112444098">"ការបំបែកផ្ទាំងបច្ចុប្បន្ន %s"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_action_description" msgid="9031621431415014327">"ប្ដូរការបំបែកផ្ទាំងទៅ %s"</string>
diff --git a/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-kn/strings.xml b/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-kn/strings.xml
index f8e3c83..194cc72 100644
--- a/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-kn/strings.xml
+++ b/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-kn/strings.xml
@@ -17,12 +17,9 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <!-- no translation found for m3_adaptive_default_pane_title_primary (4435202124665670898) -->
-    <skip />
-    <!-- no translation found for m3_adaptive_default_pane_title_secondary (5571153069654173825) -->
-    <skip />
-    <!-- no translation found for m3_adaptive_default_pane_title_tertiary (4618411484428250300) -->
-    <skip />
+    <string name="m3_adaptive_default_pane_title_primary" msgid="4435202124665670898">"ಪ್ರಾಥಮಿಕ ಪೇನ್"</string>
+    <string name="m3_adaptive_default_pane_title_secondary" msgid="5571153069654173825">"ದ್ವಿತೀಯ ಪೇನ್"</string>
+    <string name="m3_adaptive_default_pane_title_tertiary" msgid="4618411484428250300">"ತೃತೀಯ ಪೇನ್"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_content_description" msgid="9058489142432490820">"ಪೇನ್ ಅನ್ನು ವಿಸ್ತೃತಗೊಳಿಸುವುದಕ್ಕೆ ನೆರವಾಗುವ ಡ್ರ್ಯಾಗ್ ಹ್ಯಾಂಡಲ್"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_state_description" msgid="3470811934112444098">"ಪ್ರಸ್ತುತ ಪೇನ್ ವಿಭಜನೆ, %s"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_action_description" msgid="9031621431415014327">"ಪೇನ್ ವಿಭಜನೆಯನ್ನು %s ಗೆ ಬದಲಾಯಿಸಿ"</string>
diff --git a/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-ko/strings.xml b/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-ko/strings.xml
index dec3d54..4c21299 100644
--- a/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-ko/strings.xml
+++ b/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-ko/strings.xml
@@ -17,12 +17,9 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <!-- no translation found for m3_adaptive_default_pane_title_primary (4435202124665670898) -->
-    <skip />
-    <!-- no translation found for m3_adaptive_default_pane_title_secondary (5571153069654173825) -->
-    <skip />
-    <!-- no translation found for m3_adaptive_default_pane_title_tertiary (4618411484428250300) -->
-    <skip />
+    <string name="m3_adaptive_default_pane_title_primary" msgid="4435202124665670898">"기본 창"</string>
+    <string name="m3_adaptive_default_pane_title_secondary" msgid="5571153069654173825">"보조 창"</string>
+    <string name="m3_adaptive_default_pane_title_tertiary" msgid="4618411484428250300">"세 번째 창"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_content_description" msgid="9058489142432490820">"창 확장 드래그 핸들"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_state_description" msgid="3470811934112444098">"현재 창 분할, %s"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_action_description" msgid="9031621431415014327">"창 분할을 %s(으)로 변경"</string>
diff --git a/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-ky/strings.xml b/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-ky/strings.xml
index 2756cef..3664b09 100644
--- a/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-ky/strings.xml
+++ b/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-ky/strings.xml
@@ -17,12 +17,9 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <!-- no translation found for m3_adaptive_default_pane_title_primary (4435202124665670898) -->
-    <skip />
-    <!-- no translation found for m3_adaptive_default_pane_title_secondary (5571153069654173825) -->
-    <skip />
-    <!-- no translation found for m3_adaptive_default_pane_title_tertiary (4618411484428250300) -->
-    <skip />
+    <string name="m3_adaptive_default_pane_title_primary" msgid="4435202124665670898">"Негизги такта"</string>
+    <string name="m3_adaptive_default_pane_title_secondary" msgid="5571153069654173825">"Көмөкчү такта"</string>
+    <string name="m3_adaptive_default_pane_title_tertiary" msgid="4618411484428250300">"Кошумча такта"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_content_description" msgid="9058489142432490820">"Тактаны кеңейтүү үчүн сүйрөө маркери"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_state_description" msgid="3470811934112444098">"Учурдагы тактанын бөлүнүшү, %s"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_action_description" msgid="9031621431415014327">"Тактанын бөлүнүшүн %s деп өзгөртүү"</string>
diff --git a/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-lo/strings.xml b/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-lo/strings.xml
index 6d0707e..44efcb7 100644
--- a/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-lo/strings.xml
+++ b/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-lo/strings.xml
@@ -17,12 +17,9 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <!-- no translation found for m3_adaptive_default_pane_title_primary (4435202124665670898) -->
-    <skip />
-    <!-- no translation found for m3_adaptive_default_pane_title_secondary (5571153069654173825) -->
-    <skip />
-    <!-- no translation found for m3_adaptive_default_pane_title_tertiary (4618411484428250300) -->
-    <skip />
+    <string name="m3_adaptive_default_pane_title_primary" msgid="4435202124665670898">"ແຖບຫຼັກ"</string>
+    <string name="m3_adaptive_default_pane_title_secondary" msgid="5571153069654173825">"ແຖບສຳຮອງ"</string>
+    <string name="m3_adaptive_default_pane_title_tertiary" msgid="4618411484428250300">"ແຖບລຳດັບທີ 3"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_content_description" msgid="9058489142432490820">"ບ່ອນຈັບລາກເພື່ອຂະຫຍາຍແຖບ"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_state_description" msgid="3470811934112444098">"ການແບ່ງແຖບປັດຈຸບັນ, %s"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_action_description" msgid="9031621431415014327">"ປ່ຽນການແບ່ງແຖບເປັນ %s"</string>
diff --git a/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-lt/strings.xml b/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-lt/strings.xml
index 5730b9b..caf424d 100644
--- a/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-lt/strings.xml
+++ b/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-lt/strings.xml
@@ -17,12 +17,9 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <!-- no translation found for m3_adaptive_default_pane_title_primary (4435202124665670898) -->
-    <skip />
-    <!-- no translation found for m3_adaptive_default_pane_title_secondary (5571153069654173825) -->
-    <skip />
-    <!-- no translation found for m3_adaptive_default_pane_title_tertiary (4618411484428250300) -->
-    <skip />
+    <string name="m3_adaptive_default_pane_title_primary" msgid="4435202124665670898">"Pagrindinė sritis"</string>
+    <string name="m3_adaptive_default_pane_title_secondary" msgid="5571153069654173825">"Antrinė sritis"</string>
+    <string name="m3_adaptive_default_pane_title_tertiary" msgid="4618411484428250300">"Tretinė sritis"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_content_description" msgid="9058489142432490820">"Srities išplėtimo vilkimo rankenėlė"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_state_description" msgid="3470811934112444098">"Dabartinis srities skaidymas, %s"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_action_description" msgid="9031621431415014327">"Keisti srities skaidymą į %s"</string>
diff --git a/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-lv/strings.xml b/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-lv/strings.xml
index a0f6eb7b..b9bd2d7 100644
--- a/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-lv/strings.xml
+++ b/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-lv/strings.xml
@@ -17,12 +17,9 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <!-- no translation found for m3_adaptive_default_pane_title_primary (4435202124665670898) -->
-    <skip />
-    <!-- no translation found for m3_adaptive_default_pane_title_secondary (5571153069654173825) -->
-    <skip />
-    <!-- no translation found for m3_adaptive_default_pane_title_tertiary (4618411484428250300) -->
-    <skip />
+    <string name="m3_adaptive_default_pane_title_primary" msgid="4435202124665670898">"Primārā rūts"</string>
+    <string name="m3_adaptive_default_pane_title_secondary" msgid="5571153069654173825">"Sekundārā rūts"</string>
+    <string name="m3_adaptive_default_pane_title_tertiary" msgid="4618411484428250300">"Terciārā rūts"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_content_description" msgid="9058489142432490820">"Rūts izvēršanas vilkšanas turis"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_state_description" msgid="3470811934112444098">"Pašreizējais rūts sadalījums, %s"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_action_description" msgid="9031621431415014327">"Mainīt rūts sadalījumu uz šādu: %s"</string>
diff --git a/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-mk/strings.xml b/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-mk/strings.xml
index fb70612..e9c3e12 100644
--- a/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-mk/strings.xml
+++ b/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-mk/strings.xml
@@ -17,12 +17,9 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <!-- no translation found for m3_adaptive_default_pane_title_primary (4435202124665670898) -->
-    <skip />
-    <!-- no translation found for m3_adaptive_default_pane_title_secondary (5571153069654173825) -->
-    <skip />
-    <!-- no translation found for m3_adaptive_default_pane_title_tertiary (4618411484428250300) -->
-    <skip />
+    <string name="m3_adaptive_default_pane_title_primary" msgid="4435202124665670898">"Примарно окно"</string>
+    <string name="m3_adaptive_default_pane_title_secondary" msgid="5571153069654173825">"Секундарно окно"</string>
+    <string name="m3_adaptive_default_pane_title_tertiary" msgid="4618411484428250300">"Терцијарно окно"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_content_description" msgid="9058489142432490820">"Рачка за влечење за проширување на окното"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_state_description" msgid="3470811934112444098">"Тековно поделено окно, %s"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_action_description" msgid="9031621431415014327">"Променете го поделеното окно на %s"</string>
diff --git a/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-ml/strings.xml b/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-ml/strings.xml
index f1948f7..402cb88 100644
--- a/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-ml/strings.xml
+++ b/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-ml/strings.xml
@@ -17,12 +17,9 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <!-- no translation found for m3_adaptive_default_pane_title_primary (4435202124665670898) -->
-    <skip />
-    <!-- no translation found for m3_adaptive_default_pane_title_secondary (5571153069654173825) -->
-    <skip />
-    <!-- no translation found for m3_adaptive_default_pane_title_tertiary (4618411484428250300) -->
-    <skip />
+    <string name="m3_adaptive_default_pane_title_primary" msgid="4435202124665670898">"പ്രൈമറി പെയിൻ"</string>
+    <string name="m3_adaptive_default_pane_title_secondary" msgid="5571153069654173825">"സെക്കൻഡറി പെയിൻ"</string>
+    <string name="m3_adaptive_default_pane_title_tertiary" msgid="4618411484428250300">"ടെർഷ്യറി പെയിൻ"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_content_description" msgid="9058489142432490820">"പെയിൻ വികസിപ്പിക്കാനായി വലിച്ചിടുന്നതിനുള്ള ഹാൻഡിൽ"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_state_description" msgid="3470811934112444098">"നിലവിലെ പെയിൻ വിഭജനം, %s"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_action_description" msgid="9031621431415014327">"പെയിൻ വിഭജനം %s ആയി മാറ്റുക"</string>
diff --git a/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-mn/strings.xml b/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-mn/strings.xml
index 96c1053..d10bcbe 100644
--- a/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-mn/strings.xml
+++ b/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-mn/strings.xml
@@ -17,12 +17,9 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <!-- no translation found for m3_adaptive_default_pane_title_primary (4435202124665670898) -->
-    <skip />
-    <!-- no translation found for m3_adaptive_default_pane_title_secondary (5571153069654173825) -->
-    <skip />
-    <!-- no translation found for m3_adaptive_default_pane_title_tertiary (4618411484428250300) -->
-    <skip />
+    <string name="m3_adaptive_default_pane_title_primary" msgid="4435202124665670898">"Үндсэн хэсэг"</string>
+    <string name="m3_adaptive_default_pane_title_secondary" msgid="5571153069654173825">"Хоёрдогч хэсэг"</string>
+    <string name="m3_adaptive_default_pane_title_tertiary" msgid="4618411484428250300">"Гуравдагч хэсэг"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_content_description" msgid="9058489142432490820">"Хэсгийн өргөтгөлийг чирэх бариул"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_state_description" msgid="3470811934112444098">"Одоогийн хэсгийн хуваалт, %s"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_action_description" msgid="9031621431415014327">"Хэсгийн хуваалтыг %s болгож өөрчлөх"</string>
diff --git a/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-mr/strings.xml b/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-mr/strings.xml
index 4b24e0f..63b0c18 100644
--- a/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-mr/strings.xml
+++ b/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-mr/strings.xml
@@ -17,12 +17,9 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <!-- no translation found for m3_adaptive_default_pane_title_primary (4435202124665670898) -->
-    <skip />
-    <!-- no translation found for m3_adaptive_default_pane_title_secondary (5571153069654173825) -->
-    <skip />
-    <!-- no translation found for m3_adaptive_default_pane_title_tertiary (4618411484428250300) -->
-    <skip />
+    <string name="m3_adaptive_default_pane_title_primary" msgid="4435202124665670898">"प्राथमिक पेन"</string>
+    <string name="m3_adaptive_default_pane_title_secondary" msgid="5571153069654173825">"दुय्यम पेन"</string>
+    <string name="m3_adaptive_default_pane_title_tertiary" msgid="4618411484428250300">"तिसरे पेन"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_content_description" msgid="9058489142432490820">"पेन विस्तार ड्रॅग हँडल"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_state_description" msgid="3470811934112444098">"सद्य पेन स्प्लिट, %s"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_action_description" msgid="9031621431415014327">"स्प्लिट पेन %s वर बदला"</string>
diff --git a/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-ms/strings.xml b/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-ms/strings.xml
index ef280af..28dc610 100644
--- a/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-ms/strings.xml
+++ b/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-ms/strings.xml
@@ -17,12 +17,9 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <!-- no translation found for m3_adaptive_default_pane_title_primary (4435202124665670898) -->
-    <skip />
-    <!-- no translation found for m3_adaptive_default_pane_title_secondary (5571153069654173825) -->
-    <skip />
-    <!-- no translation found for m3_adaptive_default_pane_title_tertiary (4618411484428250300) -->
-    <skip />
+    <string name="m3_adaptive_default_pane_title_primary" msgid="4435202124665670898">"Anak tetingkap utama"</string>
+    <string name="m3_adaptive_default_pane_title_secondary" msgid="5571153069654173825">"Anak tetingkap kedua"</string>
+    <string name="m3_adaptive_default_pane_title_tertiary" msgid="4618411484428250300">"Anak tetingkap ketiga"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_content_description" msgid="9058489142432490820">"Pemegang seret pengembangan anak tetingkap"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_state_description" msgid="3470811934112444098">"Pemisahan anak tetingkap semasa, %s"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_action_description" msgid="9031621431415014327">"Tukar anak tetingkap terpisah kepada %s"</string>
diff --git a/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-my/strings.xml b/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-my/strings.xml
index cafd198..02f06f3 100644
--- a/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-my/strings.xml
+++ b/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-my/strings.xml
@@ -17,12 +17,9 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <!-- no translation found for m3_adaptive_default_pane_title_primary (4435202124665670898) -->
-    <skip />
-    <!-- no translation found for m3_adaptive_default_pane_title_secondary (5571153069654173825) -->
-    <skip />
-    <!-- no translation found for m3_adaptive_default_pane_title_tertiary (4618411484428250300) -->
-    <skip />
+    <string name="m3_adaptive_default_pane_title_primary" msgid="4435202124665670898">"အဓိကအကန့်"</string>
+    <string name="m3_adaptive_default_pane_title_secondary" msgid="5571153069654173825">"ဒုတိယအကန့်"</string>
+    <string name="m3_adaptive_default_pane_title_tertiary" msgid="4618411484428250300">"တတိယအကန့်"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_content_description" msgid="9058489142432490820">"အကန့်တိုးချဲ့မှု ဖိဆွဲအထိန်း"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_state_description" msgid="3470811934112444098">"လက်ရှိအကန့်အခွဲ၊ %s"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_action_description" msgid="9031621431415014327">"အကန့်အခွဲကို %s သို့ ပြောင်းနိုင်သည်"</string>
diff --git a/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-nb/strings.xml b/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-nb/strings.xml
index 9e017fd..f01ec7d 100644
--- a/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-nb/strings.xml
+++ b/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-nb/strings.xml
@@ -17,12 +17,9 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <!-- no translation found for m3_adaptive_default_pane_title_primary (4435202124665670898) -->
-    <skip />
-    <!-- no translation found for m3_adaptive_default_pane_title_secondary (5571153069654173825) -->
-    <skip />
-    <!-- no translation found for m3_adaptive_default_pane_title_tertiary (4618411484428250300) -->
-    <skip />
+    <string name="m3_adaptive_default_pane_title_primary" msgid="4435202124665670898">"Primært felt"</string>
+    <string name="m3_adaptive_default_pane_title_secondary" msgid="5571153069654173825">"Sekundært felt"</string>
+    <string name="m3_adaptive_default_pane_title_tertiary" msgid="4618411484428250300">"Tertiært panel"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_content_description" msgid="9058489142432490820">"Håndtak for utvidelse av feltet"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_state_description" msgid="3470811934112444098">"Gjeldende feltdeling, %s"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_action_description" msgid="9031621431415014327">"Endre feltdelingen til %s"</string>
diff --git a/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-ne/strings.xml b/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-ne/strings.xml
index 237f5e8..8d46a34 100644
--- a/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-ne/strings.xml
+++ b/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-ne/strings.xml
@@ -17,12 +17,9 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <!-- no translation found for m3_adaptive_default_pane_title_primary (4435202124665670898) -->
-    <skip />
-    <!-- no translation found for m3_adaptive_default_pane_title_secondary (5571153069654173825) -->
-    <skip />
-    <!-- no translation found for m3_adaptive_default_pane_title_tertiary (4618411484428250300) -->
-    <skip />
+    <string name="m3_adaptive_default_pane_title_primary" msgid="4435202124665670898">"मुख्य सामग्री भएको पेन"</string>
+    <string name="m3_adaptive_default_pane_title_secondary" msgid="5571153069654173825">"सहायक सामग्री भएको पेन"</string>
+    <string name="m3_adaptive_default_pane_title_tertiary" msgid="4618411484428250300">"अतिरिक्त सामग्री भएको पेन"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_content_description" msgid="9058489142432490820">"पेन एक्स्पान्सनको ड्र्याग ह्यान्डल"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_state_description" msgid="3470811934112444098">"पेन स्प्लिटको हालको स्थिति, %s"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_action_description" msgid="9031621431415014327">"पेन स्प्लिट परिवर्तन गरी %s बनाउनुहोस्"</string>
diff --git a/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-nl/strings.xml b/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-nl/strings.xml
index a4a9036..414aca6 100644
--- a/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-nl/strings.xml
+++ b/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-nl/strings.xml
@@ -17,12 +17,9 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <!-- no translation found for m3_adaptive_default_pane_title_primary (4435202124665670898) -->
-    <skip />
-    <!-- no translation found for m3_adaptive_default_pane_title_secondary (5571153069654173825) -->
-    <skip />
-    <!-- no translation found for m3_adaptive_default_pane_title_tertiary (4618411484428250300) -->
-    <skip />
+    <string name="m3_adaptive_default_pane_title_primary" msgid="4435202124665670898">"Primair deelvenster"</string>
+    <string name="m3_adaptive_default_pane_title_secondary" msgid="5571153069654173825">"Secundair deelvenster"</string>
+    <string name="m3_adaptive_default_pane_title_tertiary" msgid="4618411484428250300">"Tertiair deelvenster"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_content_description" msgid="9058489142432490820">"Handgreep voor slepen om deelvenster uit te breiden"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_state_description" msgid="3470811934112444098">"Huidige deelvenstersplitsing, %s"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_action_description" msgid="9031621431415014327">"Deelvenstersplitsing wijzigen in %s"</string>
diff --git a/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-pl/strings.xml b/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-pl/strings.xml
index ffb3d69..5139667 100644
--- a/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-pl/strings.xml
+++ b/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-pl/strings.xml
@@ -17,12 +17,9 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <!-- no translation found for m3_adaptive_default_pane_title_primary (4435202124665670898) -->
-    <skip />
-    <!-- no translation found for m3_adaptive_default_pane_title_secondary (5571153069654173825) -->
-    <skip />
-    <!-- no translation found for m3_adaptive_default_pane_title_tertiary (4618411484428250300) -->
-    <skip />
+    <string name="m3_adaptive_default_pane_title_primary" msgid="4435202124665670898">"Panel główny"</string>
+    <string name="m3_adaptive_default_pane_title_secondary" msgid="5571153069654173825">"Panel dodatkowy"</string>
+    <string name="m3_adaptive_default_pane_title_tertiary" msgid="4618411484428250300">"Panel trzeciorzędny"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_content_description" msgid="9058489142432490820">"Uchwyt do przeciągania panelu"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_state_description" msgid="3470811934112444098">"Bieżący podział panelu: %s"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_action_description" msgid="9031621431415014327">"Zmień podział panelu na %s"</string>
diff --git a/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-pt-rBR/strings.xml b/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-pt-rBR/strings.xml
index 145e16c..925eca6 100644
--- a/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-pt-rBR/strings.xml
+++ b/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-pt-rBR/strings.xml
@@ -17,12 +17,9 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <!-- no translation found for m3_adaptive_default_pane_title_primary (4435202124665670898) -->
-    <skip />
-    <!-- no translation found for m3_adaptive_default_pane_title_secondary (5571153069654173825) -->
-    <skip />
-    <!-- no translation found for m3_adaptive_default_pane_title_tertiary (4618411484428250300) -->
-    <skip />
+    <string name="m3_adaptive_default_pane_title_primary" msgid="4435202124665670898">"Painel principal"</string>
+    <string name="m3_adaptive_default_pane_title_secondary" msgid="5571153069654173825">"Painel secundário"</string>
+    <string name="m3_adaptive_default_pane_title_tertiary" msgid="4618411484428250300">"Painel terciário"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_content_description" msgid="9058489142432490820">"Alça de arrastar para expandir o painel"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_state_description" msgid="3470811934112444098">"Divisão atual do painel, %s"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_action_description" msgid="9031621431415014327">"Mudar a divisão do painel para %s"</string>
diff --git a/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-pt-rPT/strings.xml b/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-pt-rPT/strings.xml
index 881477d..9716ddc 100644
--- a/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-pt-rPT/strings.xml
+++ b/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-pt-rPT/strings.xml
@@ -17,12 +17,9 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <!-- no translation found for m3_adaptive_default_pane_title_primary (4435202124665670898) -->
-    <skip />
-    <!-- no translation found for m3_adaptive_default_pane_title_secondary (5571153069654173825) -->
-    <skip />
-    <!-- no translation found for m3_adaptive_default_pane_title_tertiary (4618411484428250300) -->
-    <skip />
+    <string name="m3_adaptive_default_pane_title_primary" msgid="4435202124665670898">"Painel principal"</string>
+    <string name="m3_adaptive_default_pane_title_secondary" msgid="5571153069654173825">"Painel secundário"</string>
+    <string name="m3_adaptive_default_pane_title_tertiary" msgid="4618411484428250300">"Painel terciário"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_content_description" msgid="9058489142432490820">"Indicador para arrastar de expansão do painel"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_state_description" msgid="3470811934112444098">"Divisão do painel atual, %s"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_action_description" msgid="9031621431415014327">"Altere a divisão do painel para %s"</string>
diff --git a/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-pt/strings.xml b/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-pt/strings.xml
index 145e16c..925eca6 100644
--- a/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-pt/strings.xml
+++ b/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-pt/strings.xml
@@ -17,12 +17,9 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <!-- no translation found for m3_adaptive_default_pane_title_primary (4435202124665670898) -->
-    <skip />
-    <!-- no translation found for m3_adaptive_default_pane_title_secondary (5571153069654173825) -->
-    <skip />
-    <!-- no translation found for m3_adaptive_default_pane_title_tertiary (4618411484428250300) -->
-    <skip />
+    <string name="m3_adaptive_default_pane_title_primary" msgid="4435202124665670898">"Painel principal"</string>
+    <string name="m3_adaptive_default_pane_title_secondary" msgid="5571153069654173825">"Painel secundário"</string>
+    <string name="m3_adaptive_default_pane_title_tertiary" msgid="4618411484428250300">"Painel terciário"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_content_description" msgid="9058489142432490820">"Alça de arrastar para expandir o painel"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_state_description" msgid="3470811934112444098">"Divisão atual do painel, %s"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_action_description" msgid="9031621431415014327">"Mudar a divisão do painel para %s"</string>
diff --git a/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-ro/strings.xml b/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-ro/strings.xml
index 3bf817a..6c50203 100644
--- a/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-ro/strings.xml
+++ b/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-ro/strings.xml
@@ -17,12 +17,9 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <!-- no translation found for m3_adaptive_default_pane_title_primary (4435202124665670898) -->
-    <skip />
-    <!-- no translation found for m3_adaptive_default_pane_title_secondary (5571153069654173825) -->
-    <skip />
-    <!-- no translation found for m3_adaptive_default_pane_title_tertiary (4618411484428250300) -->
-    <skip />
+    <string name="m3_adaptive_default_pane_title_primary" msgid="4435202124665670898">"Panoul principal"</string>
+    <string name="m3_adaptive_default_pane_title_secondary" msgid="5571153069654173825">"Panoul secundar"</string>
+    <string name="m3_adaptive_default_pane_title_tertiary" msgid="4618411484428250300">"Panoul terțiar"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_content_description" msgid="9058489142432490820">"Ghidaj de tragere pentru extinderea panoului"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_state_description" msgid="3470811934112444098">"Împărțirea actuală a panoului, %s"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_action_description" msgid="9031621431415014327">"Modifică împărțirea panoului la %s"</string>
diff --git a/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-ru/strings.xml b/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-ru/strings.xml
index f31a55f..9f81635 100644
--- a/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-ru/strings.xml
+++ b/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-ru/strings.xml
@@ -17,12 +17,9 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <!-- no translation found for m3_adaptive_default_pane_title_primary (4435202124665670898) -->
-    <skip />
-    <!-- no translation found for m3_adaptive_default_pane_title_secondary (5571153069654173825) -->
-    <skip />
-    <!-- no translation found for m3_adaptive_default_pane_title_tertiary (4618411484428250300) -->
-    <skip />
+    <string name="m3_adaptive_default_pane_title_primary" msgid="4435202124665670898">"Основная панель"</string>
+    <string name="m3_adaptive_default_pane_title_secondary" msgid="5571153069654173825">"Вспомогательная панель"</string>
+    <string name="m3_adaptive_default_pane_title_tertiary" msgid="4618411484428250300">"Дополнительная панель"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_content_description" msgid="9058489142432490820">"Маркер перемещения для расширения панели"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_state_description" msgid="3470811934112444098">"Пропорция разделения панелей, %s"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_action_description" msgid="9031621431415014327">"Изменить пропорцию разделения панелей на %s"</string>
diff --git a/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-sk/strings.xml b/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-sk/strings.xml
index e0124c3..6af1f51 100644
--- a/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-sk/strings.xml
+++ b/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-sk/strings.xml
@@ -17,12 +17,9 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <!-- no translation found for m3_adaptive_default_pane_title_primary (4435202124665670898) -->
-    <skip />
-    <!-- no translation found for m3_adaptive_default_pane_title_secondary (5571153069654173825) -->
-    <skip />
-    <!-- no translation found for m3_adaptive_default_pane_title_tertiary (4618411484428250300) -->
-    <skip />
+    <string name="m3_adaptive_default_pane_title_primary" msgid="4435202124665670898">"Primárny panel"</string>
+    <string name="m3_adaptive_default_pane_title_secondary" msgid="5571153069654173825">"Sekundárny panel"</string>
+    <string name="m3_adaptive_default_pane_title_tertiary" msgid="4618411484428250300">"Terciárny panel"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_content_description" msgid="9058489142432490820">"Presúvadlo na rozšírenie panela"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_state_description" msgid="3470811934112444098">"Aktuálne rozdelenie panela, %s"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_action_description" msgid="9031621431415014327">"Zmeniť rozdelenie panela na %s"</string>
diff --git a/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-sl/strings.xml b/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-sl/strings.xml
index e5b4b96e..02e5501 100644
--- a/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-sl/strings.xml
+++ b/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-sl/strings.xml
@@ -17,12 +17,9 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <!-- no translation found for m3_adaptive_default_pane_title_primary (4435202124665670898) -->
-    <skip />
-    <!-- no translation found for m3_adaptive_default_pane_title_secondary (5571153069654173825) -->
-    <skip />
-    <!-- no translation found for m3_adaptive_default_pane_title_tertiary (4618411484428250300) -->
-    <skip />
+    <string name="m3_adaptive_default_pane_title_primary" msgid="4435202124665670898">"Primarno podokno"</string>
+    <string name="m3_adaptive_default_pane_title_secondary" msgid="5571153069654173825">"Sekundarno podokno"</string>
+    <string name="m3_adaptive_default_pane_title_tertiary" msgid="4618411484428250300">"Terciarno podokno"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_content_description" msgid="9058489142432490820">"Ročica za vlečenje za razširitev podokna"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_state_description" msgid="3470811934112444098">"Trenutna razdelitev podokna, %s"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_action_description" msgid="9031621431415014327">"Sprememba razdelitve podokna na %s"</string>
diff --git a/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-sq/strings.xml b/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-sq/strings.xml
index 0ba9a9e..7cdc684 100644
--- a/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-sq/strings.xml
+++ b/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-sq/strings.xml
@@ -17,12 +17,9 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <!-- no translation found for m3_adaptive_default_pane_title_primary (4435202124665670898) -->
-    <skip />
-    <!-- no translation found for m3_adaptive_default_pane_title_secondary (5571153069654173825) -->
-    <skip />
-    <!-- no translation found for m3_adaptive_default_pane_title_tertiary (4618411484428250300) -->
-    <skip />
+    <string name="m3_adaptive_default_pane_title_primary" msgid="4435202124665670898">"Paneli kryesor"</string>
+    <string name="m3_adaptive_default_pane_title_secondary" msgid="5571153069654173825">"Paneli dytësor"</string>
+    <string name="m3_adaptive_default_pane_title_tertiary" msgid="4618411484428250300">"Paneli tretësor"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_content_description" msgid="9058489142432490820">"Doreza e zvarritjes për zgjerimin e panelit"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_state_description" msgid="3470811934112444098">"Ndarja aktuale e panelit, %s"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_action_description" msgid="9031621431415014327">"Ndrysho ndarjen e panelit në %s"</string>
diff --git a/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-sr/strings.xml b/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-sr/strings.xml
index c0cdcea..ba43445 100644
--- a/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-sr/strings.xml
+++ b/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-sr/strings.xml
@@ -17,12 +17,9 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <!-- no translation found for m3_adaptive_default_pane_title_primary (4435202124665670898) -->
-    <skip />
-    <!-- no translation found for m3_adaptive_default_pane_title_secondary (5571153069654173825) -->
-    <skip />
-    <!-- no translation found for m3_adaptive_default_pane_title_tertiary (4618411484428250300) -->
-    <skip />
+    <string name="m3_adaptive_default_pane_title_primary" msgid="4435202124665670898">"Примарно окно"</string>
+    <string name="m3_adaptive_default_pane_title_secondary" msgid="5571153069654173825">"Секундарно окно"</string>
+    <string name="m3_adaptive_default_pane_title_tertiary" msgid="4618411484428250300">"Терцијарно окно"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_content_description" msgid="9058489142432490820">"Маркер за превлачење којим се проширује окно"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_state_description" msgid="3470811934112444098">"Тренутно подељено окно, %s"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_action_description" msgid="9031621431415014327">"Промените подељено окно на: %s"</string>
diff --git a/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-sv/strings.xml b/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-sv/strings.xml
index 96c81d5..363c3cb 100644
--- a/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-sv/strings.xml
+++ b/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-sv/strings.xml
@@ -17,12 +17,9 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <!-- no translation found for m3_adaptive_default_pane_title_primary (4435202124665670898) -->
-    <skip />
-    <!-- no translation found for m3_adaptive_default_pane_title_secondary (5571153069654173825) -->
-    <skip />
-    <!-- no translation found for m3_adaptive_default_pane_title_tertiary (4618411484428250300) -->
-    <skip />
+    <string name="m3_adaptive_default_pane_title_primary" msgid="4435202124665670898">"Primär ruta"</string>
+    <string name="m3_adaptive_default_pane_title_secondary" msgid="5571153069654173825">"Sekundär ruta"</string>
+    <string name="m3_adaptive_default_pane_title_tertiary" msgid="4618411484428250300">"Tertiär ruta"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_content_description" msgid="9058489142432490820">"Handtag för rutexpansion"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_state_description" msgid="3470811934112444098">"Nuvarande rutdelning, %s"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_action_description" msgid="9031621431415014327">"Ändra rutdelning till %s"</string>
diff --git a/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-sw/strings.xml b/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-sw/strings.xml
index 3a4e0f0..e0bbb08 100644
--- a/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-sw/strings.xml
+++ b/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-sw/strings.xml
@@ -17,12 +17,9 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <!-- no translation found for m3_adaptive_default_pane_title_primary (4435202124665670898) -->
-    <skip />
-    <!-- no translation found for m3_adaptive_default_pane_title_secondary (5571153069654173825) -->
-    <skip />
-    <!-- no translation found for m3_adaptive_default_pane_title_tertiary (4618411484428250300) -->
-    <skip />
+    <string name="m3_adaptive_default_pane_title_primary" msgid="4435202124665670898">"Kijisehemu msingi"</string>
+    <string name="m3_adaptive_default_pane_title_secondary" msgid="5571153069654173825">"Kijisehemu cha ziada"</string>
+    <string name="m3_adaptive_default_pane_title_tertiary" msgid="4618411484428250300">"Kijisehemu cha tatu"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_content_description" msgid="9058489142432490820">"Aikoni ya buruta ili kupanua kijisehemu"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_state_description" msgid="3470811934112444098">"Hali ya sasa ya kugawanya kijisehemu, %s"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_action_description" msgid="9031621431415014327">"Badilisha hali ya kugawanya kijisehemu iwe %s"</string>
diff --git a/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-ta/strings.xml b/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-ta/strings.xml
index ff06cad..2a245a3 100644
--- a/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-ta/strings.xml
+++ b/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-ta/strings.xml
@@ -17,12 +17,9 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <!-- no translation found for m3_adaptive_default_pane_title_primary (4435202124665670898) -->
-    <skip />
-    <!-- no translation found for m3_adaptive_default_pane_title_secondary (5571153069654173825) -->
-    <skip />
-    <!-- no translation found for m3_adaptive_default_pane_title_tertiary (4618411484428250300) -->
-    <skip />
+    <string name="m3_adaptive_default_pane_title_primary" msgid="4435202124665670898">"முதன்மைப் பெட்டி"</string>
+    <string name="m3_adaptive_default_pane_title_secondary" msgid="5571153069654173825">"இரண்டாம்நிலைப் பெட்டி"</string>
+    <string name="m3_adaptive_default_pane_title_tertiary" msgid="4618411484428250300">"மூன்றாம்நிலைப் பெட்டி"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_content_description" msgid="9058489142432490820">"பெட்டியை இழுத்து விரிவாக்குவதற்கான ஹேண்டில்"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_state_description" msgid="3470811934112444098">"தற்போதைய பாகம் பிரித்தல், %s"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_action_description" msgid="9031621431415014327">"பாகமாகப் பிரித்தலை %s மாற்றும்"</string>
diff --git a/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-te/strings.xml b/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-te/strings.xml
index bbe41a8..1820ac7 100644
--- a/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-te/strings.xml
+++ b/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-te/strings.xml
@@ -17,12 +17,9 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <!-- no translation found for m3_adaptive_default_pane_title_primary (4435202124665670898) -->
-    <skip />
-    <!-- no translation found for m3_adaptive_default_pane_title_secondary (5571153069654173825) -->
-    <skip />
-    <!-- no translation found for m3_adaptive_default_pane_title_tertiary (4618411484428250300) -->
-    <skip />
+    <string name="m3_adaptive_default_pane_title_primary" msgid="4435202124665670898">"ప్రధాన పేన్"</string>
+    <string name="m3_adaptive_default_pane_title_secondary" msgid="5571153069654173825">"ద్వితీయ పేన్"</string>
+    <string name="m3_adaptive_default_pane_title_tertiary" msgid="4618411484428250300">"తృతీయ పేన్"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_content_description" msgid="9058489142432490820">"పేన్‌ను విస్తరించడానికి లాగే హ్యాండిల్"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_state_description" msgid="3470811934112444098">"ప్రస్తుత పేన్ విభజన, %s"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_action_description" msgid="9031621431415014327">"పేన్ విభజనను %s‌కు మార్చండి"</string>
diff --git a/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-th/strings.xml b/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-th/strings.xml
index d6b6d19..4b10aee 100644
--- a/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-th/strings.xml
+++ b/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-th/strings.xml
@@ -17,12 +17,9 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <!-- no translation found for m3_adaptive_default_pane_title_primary (4435202124665670898) -->
-    <skip />
-    <!-- no translation found for m3_adaptive_default_pane_title_secondary (5571153069654173825) -->
-    <skip />
-    <!-- no translation found for m3_adaptive_default_pane_title_tertiary (4618411484428250300) -->
-    <skip />
+    <string name="m3_adaptive_default_pane_title_primary" msgid="4435202124665670898">"แผงหลัก"</string>
+    <string name="m3_adaptive_default_pane_title_secondary" msgid="5571153069654173825">"แผงรอง"</string>
+    <string name="m3_adaptive_default_pane_title_tertiary" msgid="4618411484428250300">"แผงลำดับที่ 3"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_content_description" msgid="9058489142432490820">"แฮนเดิลการลากเพื่อขยายแผง"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_state_description" msgid="3470811934112444098">"การแบ่งแผงปัจจุบัน %s"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_action_description" msgid="9031621431415014327">"เปลี่ยนการแบ่งแผงเป็น %s"</string>
diff --git a/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-tl/strings.xml b/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-tl/strings.xml
index 1be4e0c..62655fe 100644
--- a/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-tl/strings.xml
+++ b/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-tl/strings.xml
@@ -17,12 +17,9 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <!-- no translation found for m3_adaptive_default_pane_title_primary (4435202124665670898) -->
-    <skip />
-    <!-- no translation found for m3_adaptive_default_pane_title_secondary (5571153069654173825) -->
-    <skip />
-    <!-- no translation found for m3_adaptive_default_pane_title_tertiary (4618411484428250300) -->
-    <skip />
+    <string name="m3_adaptive_default_pane_title_primary" msgid="4435202124665670898">"Pangunahing pane"</string>
+    <string name="m3_adaptive_default_pane_title_secondary" msgid="5571153069654173825">"Pangalawang pane"</string>
+    <string name="m3_adaptive_default_pane_title_tertiary" msgid="4618411484428250300">"Pangatlong pane"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_content_description" msgid="9058489142432490820">"Handle sa pag-drag sa pagpapalawak ng pane"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_state_description" msgid="3470811934112444098">"Kasalukuyang hati ng pane, %s"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_action_description" msgid="9031621431415014327">"Gawing %s ang pane split"</string>
diff --git a/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-tr/strings.xml b/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-tr/strings.xml
index ec231d2..609767f 100644
--- a/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-tr/strings.xml
+++ b/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-tr/strings.xml
@@ -17,12 +17,9 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <!-- no translation found for m3_adaptive_default_pane_title_primary (4435202124665670898) -->
-    <skip />
-    <!-- no translation found for m3_adaptive_default_pane_title_secondary (5571153069654173825) -->
-    <skip />
-    <!-- no translation found for m3_adaptive_default_pane_title_tertiary (4618411484428250300) -->
-    <skip />
+    <string name="m3_adaptive_default_pane_title_primary" msgid="4435202124665670898">"Birincil bölme"</string>
+    <string name="m3_adaptive_default_pane_title_secondary" msgid="5571153069654173825">"İkincil bölme"</string>
+    <string name="m3_adaptive_default_pane_title_tertiary" msgid="4618411484428250300">"Üçüncül bölme"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_content_description" msgid="9058489142432490820">"Bölmeyi genişletmek için sürükleme tutamacı"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_state_description" msgid="3470811934112444098">"Mevcut bölme oranı, %s"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_action_description" msgid="9031621431415014327">"Bölme oranını %s olarak değiştirin"</string>
diff --git a/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-ur/strings.xml b/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-ur/strings.xml
index 3c83bd7..e22e9d6 100644
--- a/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-ur/strings.xml
+++ b/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-ur/strings.xml
@@ -17,12 +17,9 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <!-- no translation found for m3_adaptive_default_pane_title_primary (4435202124665670898) -->
-    <skip />
-    <!-- no translation found for m3_adaptive_default_pane_title_secondary (5571153069654173825) -->
-    <skip />
-    <!-- no translation found for m3_adaptive_default_pane_title_tertiary (4618411484428250300) -->
-    <skip />
+    <string name="m3_adaptive_default_pane_title_primary" msgid="4435202124665670898">"پرائمری پین"</string>
+    <string name="m3_adaptive_default_pane_title_secondary" msgid="5571153069654173825">"ثانوی پین"</string>
+    <string name="m3_adaptive_default_pane_title_tertiary" msgid="4618411484428250300">"تیسرے درجے کا پین"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_content_description" msgid="9058489142432490820">"پین کو پھیلانے کے لیے گھسیٹنے کا ہینڈل"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_state_description" msgid="3470811934112444098">"‏موجودہ پین اسپلٹ، ‎%s"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_action_description" msgid="9031621431415014327">"‏پین اسپلٹ کو ‎%s میں تبدیل کریں"</string>
diff --git a/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-vi/strings.xml b/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-vi/strings.xml
index 66f64ec..25b41b2 100644
--- a/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-vi/strings.xml
+++ b/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-vi/strings.xml
@@ -17,12 +17,9 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <!-- no translation found for m3_adaptive_default_pane_title_primary (4435202124665670898) -->
-    <skip />
-    <!-- no translation found for m3_adaptive_default_pane_title_secondary (5571153069654173825) -->
-    <skip />
-    <!-- no translation found for m3_adaptive_default_pane_title_tertiary (4618411484428250300) -->
-    <skip />
+    <string name="m3_adaptive_default_pane_title_primary" msgid="4435202124665670898">"Ngăn chính"</string>
+    <string name="m3_adaptive_default_pane_title_secondary" msgid="5571153069654173825">"Ngăn thứ hai"</string>
+    <string name="m3_adaptive_default_pane_title_tertiary" msgid="4618411484428250300">"Ngăn thứ ba"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_content_description" msgid="9058489142432490820">"Nút kéo mở rộng ngăn"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_state_description" msgid="3470811934112444098">"Trạng thái chia ngăn hiện tại, %s"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_action_description" msgid="9031621431415014327">"Thay đổi chế độ tách ngăn thành %s"</string>
diff --git a/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-zh-rCN/strings.xml b/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-zh-rCN/strings.xml
index c889a03..baf369a 100644
--- a/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-zh-rCN/strings.xml
+++ b/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-zh-rCN/strings.xml
@@ -17,12 +17,9 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <!-- no translation found for m3_adaptive_default_pane_title_primary (4435202124665670898) -->
-    <skip />
-    <!-- no translation found for m3_adaptive_default_pane_title_secondary (5571153069654173825) -->
-    <skip />
-    <!-- no translation found for m3_adaptive_default_pane_title_tertiary (4618411484428250300) -->
-    <skip />
+    <string name="m3_adaptive_default_pane_title_primary" msgid="4435202124665670898">"主要窗格"</string>
+    <string name="m3_adaptive_default_pane_title_secondary" msgid="5571153069654173825">"次要窗格"</string>
+    <string name="m3_adaptive_default_pane_title_tertiary" msgid="4618411484428250300">"第三窗格"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_content_description" msgid="9058489142432490820">"窗格展开拖动手柄"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_state_description" msgid="3470811934112444098">"当前窗格分割方式:%s"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_action_description" msgid="9031621431415014327">"将窗格分割更改为%s"</string>
diff --git a/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-zh-rHK/strings.xml b/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-zh-rHK/strings.xml
index e811fe2..7419ec3 100644
--- a/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-zh-rHK/strings.xml
+++ b/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-zh-rHK/strings.xml
@@ -17,12 +17,9 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <!-- no translation found for m3_adaptive_default_pane_title_primary (4435202124665670898) -->
-    <skip />
-    <!-- no translation found for m3_adaptive_default_pane_title_secondary (5571153069654173825) -->
-    <skip />
-    <!-- no translation found for m3_adaptive_default_pane_title_tertiary (4618411484428250300) -->
-    <skip />
+    <string name="m3_adaptive_default_pane_title_primary" msgid="4435202124665670898">"主要窗格"</string>
+    <string name="m3_adaptive_default_pane_title_secondary" msgid="5571153069654173825">"次要窗格"</string>
+    <string name="m3_adaptive_default_pane_title_tertiary" msgid="4618411484428250300">"第三窗格"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_content_description" msgid="9058489142432490820">"展開窗格拖曳控點"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_state_description" msgid="3470811934112444098">"目前的分割窗格,%s"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_action_description" msgid="9031621431415014327">"將分割窗格轉做 %s"</string>
diff --git a/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-zh-rTW/strings.xml b/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-zh-rTW/strings.xml
index a0d6f62..c0e6767 100644
--- a/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-zh-rTW/strings.xml
+++ b/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-zh-rTW/strings.xml
@@ -17,12 +17,9 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <!-- no translation found for m3_adaptive_default_pane_title_primary (4435202124665670898) -->
-    <skip />
-    <!-- no translation found for m3_adaptive_default_pane_title_secondary (5571153069654173825) -->
-    <skip />
-    <!-- no translation found for m3_adaptive_default_pane_title_tertiary (4618411484428250300) -->
-    <skip />
+    <string name="m3_adaptive_default_pane_title_primary" msgid="4435202124665670898">"主要窗格"</string>
+    <string name="m3_adaptive_default_pane_title_secondary" msgid="5571153069654173825">"次要窗格"</string>
+    <string name="m3_adaptive_default_pane_title_tertiary" msgid="4618411484428250300">"第三窗格"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_content_description" msgid="9058489142432490820">"窗格擴展拖曳控點"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_state_description" msgid="3470811934112444098">"目前窗格分割狀態:%s"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_action_description" msgid="9031621431415014327">"將窗格分割變更為「%s」"</string>
diff --git a/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-zu/strings.xml b/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-zu/strings.xml
index 30c07ae..c988046 100644
--- a/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-zu/strings.xml
+++ b/compose/material3/adaptive/adaptive-layout/src/androidMain/res/values-zu/strings.xml
@@ -17,12 +17,9 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <!-- no translation found for m3_adaptive_default_pane_title_primary (4435202124665670898) -->
-    <skip />
-    <!-- no translation found for m3_adaptive_default_pane_title_secondary (5571153069654173825) -->
-    <skip />
-    <!-- no translation found for m3_adaptive_default_pane_title_tertiary (4618411484428250300) -->
-    <skip />
+    <string name="m3_adaptive_default_pane_title_primary" msgid="4435202124665670898">"I-pane eyinhloko"</string>
+    <string name="m3_adaptive_default_pane_title_secondary" msgid="5571153069654173825">"I-pane yesibili"</string>
+    <string name="m3_adaptive_default_pane_title_tertiary" msgid="4618411484428250300">"I-pane yesithathu"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_content_description" msgid="9058489142432490820">"Isibambo sokuhudula isandiso sepane"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_state_description" msgid="3470811934112444098">"Ukuhlukaniswa kwepane yamanje, %s"</string>
     <string name="m3_adaptive_default_pane_expansion_drag_handle_action_description" msgid="9031621431415014327">"Shintsha ukuhlukana kwepane kube ku-%s"</string>
diff --git a/compose/material3/adaptive/adaptive-layout/src/commonMain/kotlin/androidx/compose/material3/adaptive/layout/ListDetailPaneScaffold.kt b/compose/material3/adaptive/adaptive-layout/src/commonMain/kotlin/androidx/compose/material3/adaptive/layout/ListDetailPaneScaffold.kt
index d13279a..d30f748 100644
--- a/compose/material3/adaptive/adaptive-layout/src/commonMain/kotlin/androidx/compose/material3/adaptive/layout/ListDetailPaneScaffold.kt
+++ b/compose/material3/adaptive/adaptive-layout/src/commonMain/kotlin/androidx/compose/material3/adaptive/layout/ListDetailPaneScaffold.kt
@@ -52,7 +52,7 @@
  *
  * The following code gives a sample of how to integrate with the Compose Navigation library:
  *
- * @sample androidx.compose.material3.adaptive.samples.NavigableListDetailPaneScaffoldSample
+ * @sample androidx.compose.material3.adaptive.samples.ListDetailWithNavigation2Sample
  * @param directive The top-level directives about how the scaffold should arrange its panes.
  * @param value The current adapted value of the scaffold, which indicates how each pane of the
  *   scaffold is adapted.
@@ -139,7 +139,7 @@
  *
  * The following code gives a sample of how to integrate with the Compose Navigation library:
  *
- * @sample androidx.compose.material3.adaptive.samples.NavigableListDetailPaneScaffoldSample
+ * @sample androidx.compose.material3.adaptive.samples.ListDetailWithNavigation2Sample
  * @param directive The top-level directives about how the scaffold should arrange its panes.
  * @param scaffoldState The current state of the scaffold, containing information about the adapted
  *   value of each pane of the scaffold and the transitions/animations in progress.
diff --git a/compose/material3/adaptive/adaptive-navigation/build.gradle b/compose/material3/adaptive/adaptive-navigation/build.gradle
index 12ad8c6..792bfa8 100644
--- a/compose/material3/adaptive/adaptive-navigation/build.gradle
+++ b/compose/material3/adaptive/adaptive-navigation/build.gradle
@@ -94,7 +94,7 @@
             }
         }
 
-        androidUnitTest {
+        androidHostTest {
             dependsOn(commonTest)
             dependencies {
                 implementation(libs.junit)
diff --git a/compose/material3/adaptive/adaptive-navigation/src/androidMain/kotlin/androidx/compose/material3/adaptive/navigation/AndroidThreePaneScaffold.android.kt b/compose/material3/adaptive/adaptive-navigation/src/androidMain/kotlin/androidx/compose/material3/adaptive/navigation/AndroidThreePaneScaffold.android.kt
index 4d8c3aa..d24558d 100644
--- a/compose/material3/adaptive/adaptive-navigation/src/androidMain/kotlin/androidx/compose/material3/adaptive/navigation/AndroidThreePaneScaffold.android.kt
+++ b/compose/material3/adaptive/adaptive-navigation/src/androidMain/kotlin/androidx/compose/material3/adaptive/navigation/AndroidThreePaneScaffold.android.kt
@@ -34,7 +34,7 @@
  *
  * Example usage, including integration with the Compose Navigation library:
  *
- * @sample androidx.compose.material3.adaptive.samples.NavigableListDetailPaneScaffoldSample
+ * @sample androidx.compose.material3.adaptive.samples.ListDetailWithNavigation2Sample
  * @param navigator The navigator instance to navigate through the scaffold.
  * @param listPane the list pane of the scaffold, which is supposed to hold a list of item summaries
  *   that can be selected from, for example, the inbox mail list of a mail app. See
diff --git a/compose/material3/adaptive/adaptive-navigation3/api/current.txt b/compose/material3/adaptive/adaptive-navigation3/api/current.txt
index 5110fa8..ce94ee0 100644
--- a/compose/material3/adaptive/adaptive-navigation3/api/current.txt
+++ b/compose/material3/adaptive/adaptive-navigation3/api/current.txt
@@ -4,8 +4,7 @@
   @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi public final class ListDetailSceneStrategy<T> implements androidx.navigation3.scene.SceneStrategy<T> {
     ctor @KotlinOnly public <T> ListDetailSceneStrategy(androidx.compose.material3.adaptive.navigation.BackNavigationBehavior backNavigationBehavior, androidx.compose.material3.adaptive.layout.PaneScaffoldDirective directive);
     ctor @BytecodeOnly public ListDetailSceneStrategy(String!, androidx.compose.material3.adaptive.layout.PaneScaffoldDirective!, kotlin.jvm.internal.DefaultConstructorMarker!);
-    method @BytecodeOnly @androidx.compose.runtime.Composable public androidx.navigation3.scene.Scene<T!>? calculateScene(java.util.List<? extends androidx.navigation3.runtime.NavEntry<T!>!>, kotlin.jvm.functions.Function0<kotlin.Unit!>, androidx.compose.runtime.Composer?, int);
-    method @KotlinOnly @androidx.compose.runtime.Composable public androidx.navigation3.scene.Scene<T>? calculateScene(java.util.List<androidx.navigation3.runtime.NavEntry<T>> entries, kotlin.jvm.functions.Function0<kotlin.Unit> onBack);
+    method public androidx.navigation3.scene.Scene<T>? calculateScene(androidx.navigation3.scene.SceneStrategyScope<T>, java.util.List<androidx.navigation3.runtime.NavEntry<T>> entries);
     method @BytecodeOnly public String getBackNavigationBehavior-pSECbL4();
     method @InaccessibleFromKotlin public androidx.compose.material3.adaptive.layout.PaneScaffoldDirective getDirective();
     property public androidx.compose.material3.adaptive.navigation.BackNavigationBehavior backNavigationBehavior;
@@ -29,8 +28,7 @@
   @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi public final class SupportingPaneSceneStrategy<T> implements androidx.navigation3.scene.SceneStrategy<T> {
     ctor @KotlinOnly public <T> SupportingPaneSceneStrategy(androidx.compose.material3.adaptive.navigation.BackNavigationBehavior backNavigationBehavior, androidx.compose.material3.adaptive.layout.PaneScaffoldDirective directive);
     ctor @BytecodeOnly public SupportingPaneSceneStrategy(String!, androidx.compose.material3.adaptive.layout.PaneScaffoldDirective!, kotlin.jvm.internal.DefaultConstructorMarker!);
-    method @BytecodeOnly @androidx.compose.runtime.Composable public androidx.navigation3.scene.Scene<T!>? calculateScene(java.util.List<? extends androidx.navigation3.runtime.NavEntry<T!>!>, kotlin.jvm.functions.Function0<kotlin.Unit!>, androidx.compose.runtime.Composer?, int);
-    method @KotlinOnly @androidx.compose.runtime.Composable public androidx.navigation3.scene.Scene<T>? calculateScene(java.util.List<androidx.navigation3.runtime.NavEntry<T>> entries, kotlin.jvm.functions.Function0<kotlin.Unit> onBack);
+    method public androidx.navigation3.scene.Scene<T>? calculateScene(androidx.navigation3.scene.SceneStrategyScope<T>, java.util.List<androidx.navigation3.runtime.NavEntry<T>> entries);
     method @BytecodeOnly public String getBackNavigationBehavior-pSECbL4();
     method @InaccessibleFromKotlin public androidx.compose.material3.adaptive.layout.PaneScaffoldDirective getDirective();
     property public androidx.compose.material3.adaptive.navigation.BackNavigationBehavior backNavigationBehavior;
diff --git a/compose/material3/adaptive/adaptive-navigation3/api/restricted_current.txt b/compose/material3/adaptive/adaptive-navigation3/api/restricted_current.txt
index 5110fa8..ce94ee0 100644
--- a/compose/material3/adaptive/adaptive-navigation3/api/restricted_current.txt
+++ b/compose/material3/adaptive/adaptive-navigation3/api/restricted_current.txt
@@ -4,8 +4,7 @@
   @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi public final class ListDetailSceneStrategy<T> implements androidx.navigation3.scene.SceneStrategy<T> {
     ctor @KotlinOnly public <T> ListDetailSceneStrategy(androidx.compose.material3.adaptive.navigation.BackNavigationBehavior backNavigationBehavior, androidx.compose.material3.adaptive.layout.PaneScaffoldDirective directive);
     ctor @BytecodeOnly public ListDetailSceneStrategy(String!, androidx.compose.material3.adaptive.layout.PaneScaffoldDirective!, kotlin.jvm.internal.DefaultConstructorMarker!);
-    method @BytecodeOnly @androidx.compose.runtime.Composable public androidx.navigation3.scene.Scene<T!>? calculateScene(java.util.List<? extends androidx.navigation3.runtime.NavEntry<T!>!>, kotlin.jvm.functions.Function0<kotlin.Unit!>, androidx.compose.runtime.Composer?, int);
-    method @KotlinOnly @androidx.compose.runtime.Composable public androidx.navigation3.scene.Scene<T>? calculateScene(java.util.List<androidx.navigation3.runtime.NavEntry<T>> entries, kotlin.jvm.functions.Function0<kotlin.Unit> onBack);
+    method public androidx.navigation3.scene.Scene<T>? calculateScene(androidx.navigation3.scene.SceneStrategyScope<T>, java.util.List<androidx.navigation3.runtime.NavEntry<T>> entries);
     method @BytecodeOnly public String getBackNavigationBehavior-pSECbL4();
     method @InaccessibleFromKotlin public androidx.compose.material3.adaptive.layout.PaneScaffoldDirective getDirective();
     property public androidx.compose.material3.adaptive.navigation.BackNavigationBehavior backNavigationBehavior;
@@ -29,8 +28,7 @@
   @SuppressCompatibility @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi public final class SupportingPaneSceneStrategy<T> implements androidx.navigation3.scene.SceneStrategy<T> {
     ctor @KotlinOnly public <T> SupportingPaneSceneStrategy(androidx.compose.material3.adaptive.navigation.BackNavigationBehavior backNavigationBehavior, androidx.compose.material3.adaptive.layout.PaneScaffoldDirective directive);
     ctor @BytecodeOnly public SupportingPaneSceneStrategy(String!, androidx.compose.material3.adaptive.layout.PaneScaffoldDirective!, kotlin.jvm.internal.DefaultConstructorMarker!);
-    method @BytecodeOnly @androidx.compose.runtime.Composable public androidx.navigation3.scene.Scene<T!>? calculateScene(java.util.List<? extends androidx.navigation3.runtime.NavEntry<T!>!>, kotlin.jvm.functions.Function0<kotlin.Unit!>, androidx.compose.runtime.Composer?, int);
-    method @KotlinOnly @androidx.compose.runtime.Composable public androidx.navigation3.scene.Scene<T>? calculateScene(java.util.List<androidx.navigation3.runtime.NavEntry<T>> entries, kotlin.jvm.functions.Function0<kotlin.Unit> onBack);
+    method public androidx.navigation3.scene.Scene<T>? calculateScene(androidx.navigation3.scene.SceneStrategyScope<T>, java.util.List<androidx.navigation3.runtime.NavEntry<T>> entries);
     method @BytecodeOnly public String getBackNavigationBehavior-pSECbL4();
     method @InaccessibleFromKotlin public androidx.compose.material3.adaptive.layout.PaneScaffoldDirective getDirective();
     property public androidx.compose.material3.adaptive.navigation.BackNavigationBehavior backNavigationBehavior;
diff --git a/compose/material3/adaptive/adaptive-navigation3/bcv/native/current.txt b/compose/material3/adaptive/adaptive-navigation3/bcv/native/current.txt
index e7878e3..cdc7ce0 100644
--- a/compose/material3/adaptive/adaptive-navigation3/bcv/native/current.txt
+++ b/compose/material3/adaptive/adaptive-navigation3/bcv/native/current.txt
@@ -14,7 +14,7 @@
     final val directive // androidx.compose.material3.adaptive.navigation3/ListDetailSceneStrategy.directive|{}directive[0]
         final fun <get-directive>(): androidx.compose.material3.adaptive.layout/PaneScaffoldDirective // androidx.compose.material3.adaptive.navigation3/ListDetailSceneStrategy.directive.<get-directive>|<get-directive>(){}[0]
 
-    final fun calculateScene(kotlin.collections/List<androidx.navigation3.runtime/NavEntry<#A>>, kotlin/Function0<kotlin/Unit>, androidx.compose.runtime/Composer?, kotlin/Int): androidx.navigation3.scene/Scene<#A>? // androidx.compose.material3.adaptive.navigation3/ListDetailSceneStrategy.calculateScene|calculateScene(kotlin.collections.List<androidx.navigation3.runtime.NavEntry<1:0>>;kotlin.Function0<kotlin.Unit>;androidx.compose.runtime.Composer?;kotlin.Int){}[0]
+    final fun (androidx.navigation3.scene/SceneStrategyScope<#A>).calculateScene(kotlin.collections/List<androidx.navigation3.runtime/NavEntry<#A>>): androidx.navigation3.scene/Scene<#A>? // androidx.compose.material3.adaptive.navigation3/ListDetailSceneStrategy.calculateScene|calculateScene@androidx.navigation3.scene.SceneStrategyScope<1:0>(kotlin.collections.List<androidx.navigation3.runtime.NavEntry<1:0>>){}[0]
 
     final object Companion { // androidx.compose.material3.adaptive.navigation3/ListDetailSceneStrategy.Companion|null[0]
         final fun detailPane(kotlin/Any = ...): kotlin.collections/Map<kotlin/String, kotlin/Any> // androidx.compose.material3.adaptive.navigation3/ListDetailSceneStrategy.Companion.detailPane|detailPane(kotlin.Any){}[0]
@@ -31,7 +31,7 @@
     final val directive // androidx.compose.material3.adaptive.navigation3/SupportingPaneSceneStrategy.directive|{}directive[0]
         final fun <get-directive>(): androidx.compose.material3.adaptive.layout/PaneScaffoldDirective // androidx.compose.material3.adaptive.navigation3/SupportingPaneSceneStrategy.directive.<get-directive>|<get-directive>(){}[0]
 
-    final fun calculateScene(kotlin.collections/List<androidx.navigation3.runtime/NavEntry<#A>>, kotlin/Function0<kotlin/Unit>, androidx.compose.runtime/Composer?, kotlin/Int): androidx.navigation3.scene/Scene<#A>? // androidx.compose.material3.adaptive.navigation3/SupportingPaneSceneStrategy.calculateScene|calculateScene(kotlin.collections.List<androidx.navigation3.runtime.NavEntry<1:0>>;kotlin.Function0<kotlin.Unit>;androidx.compose.runtime.Composer?;kotlin.Int){}[0]
+    final fun (androidx.navigation3.scene/SceneStrategyScope<#A>).calculateScene(kotlin.collections/List<androidx.navigation3.runtime/NavEntry<#A>>): androidx.navigation3.scene/Scene<#A>? // androidx.compose.material3.adaptive.navigation3/SupportingPaneSceneStrategy.calculateScene|calculateScene@androidx.navigation3.scene.SceneStrategyScope<1:0>(kotlin.collections.List<androidx.navigation3.runtime.NavEntry<1:0>>){}[0]
 
     final object Companion { // androidx.compose.material3.adaptive.navigation3/SupportingPaneSceneStrategy.Companion|null[0]
         final fun extraPane(kotlin/Any = ...): kotlin.collections/Map<kotlin/String, kotlin/Any> // androidx.compose.material3.adaptive.navigation3/SupportingPaneSceneStrategy.Companion.extraPane|extraPane(kotlin.Any){}[0]
diff --git a/compose/material3/adaptive/adaptive-navigation3/src/androidInstrumentedTest/kotlin/androidx/compose/material3/adaptive/navigation3/ListDetailSceneStrategyTest.kt b/compose/material3/adaptive/adaptive-navigation3/src/androidInstrumentedTest/kotlin/androidx/compose/material3/adaptive/navigation3/ListDetailSceneStrategyTest.kt
index c5845b7..143d086 100644
--- a/compose/material3/adaptive/adaptive-navigation3/src/androidInstrumentedTest/kotlin/androidx/compose/material3/adaptive/navigation3/ListDetailSceneStrategyTest.kt
+++ b/compose/material3/adaptive/adaptive-navigation3/src/androidInstrumentedTest/kotlin/androidx/compose/material3/adaptive/navigation3/ListDetailSceneStrategyTest.kt
@@ -31,6 +31,7 @@
 import androidx.compose.ui.test.onNodeWithText
 import androidx.navigation3.runtime.NavEntry
 import androidx.navigation3.scene.Scene
+import androidx.navigation3.scene.SceneStrategyScope
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.MediumTest
 import com.google.common.truth.Truth.assertThat
@@ -51,7 +52,7 @@
         composeRule.setContent {
             val strategy =
                 rememberListDetailSceneStrategy<TestKey>(directive = PaneScaffoldDirective.Default)
-            scene = strategy.calculateScene(listOf(nonListDetailEntry, listEntry, detailEntry)) {}
+            scene = strategy.calculateScene(listOf(nonListDetailEntry, listEntry, detailEntry))
         }
 
         composeRule.waitForIdle()
@@ -65,7 +66,7 @@
         composeRule.setContent {
             val strategy =
                 rememberListDetailSceneStrategy<TestKey>(directive = MockDualPaneScaffoldDirective)
-            scene = strategy.calculateScene(entries) {}
+            scene = strategy.calculateScene(entries)
         }
 
         composeRule.waitForIdle()
@@ -78,7 +79,7 @@
         composeRule.setContent {
             val strategy =
                 rememberListDetailSceneStrategy<TestKey>(directive = MockDualPaneScaffoldDirective)
-            scene = strategy.calculateScene(listOf(nonListDetailEntry, listEntry, detailEntry)) {}
+            scene = strategy.calculateScene(listOf(nonListDetailEntry, listEntry, detailEntry))
         }
 
         composeRule.waitForIdle()
@@ -91,7 +92,7 @@
         composeRule.setContent {
             val strategy =
                 rememberListDetailSceneStrategy<TestKey>(directive = MockDualPaneScaffoldDirective)
-            scene = strategy.calculateScene(listOf(listEntry, detailEntry, nonListDetailEntry)) {}
+            scene = strategy.calculateScene(listOf(listEntry, detailEntry, nonListDetailEntry))
         }
 
         composeRule.waitForIdle()
@@ -104,7 +105,7 @@
         composeRule.setContent {
             val strategy =
                 rememberListDetailSceneStrategy<TestKey>(directive = MockDualPaneScaffoldDirective)
-            scene = strategy.calculateScene(listOf(nonListDetailEntry, listEntry)) {}
+            scene = strategy.calculateScene(listOf(nonListDetailEntry, listEntry))
         }
 
         composeRule.waitForIdle()
@@ -117,7 +118,7 @@
         composeRule.setContent {
             val strategy =
                 rememberListDetailSceneStrategy<TestKey>(directive = MockDualPaneScaffoldDirective)
-            scene = strategy.calculateScene(listOf(nonListDetailEntry, detailEntry)) {}
+            scene = strategy.calculateScene(listOf(nonListDetailEntry, detailEntry))
         }
 
         composeRule.waitForIdle()
@@ -130,8 +131,7 @@
         composeRule.setContent {
             val strategy =
                 rememberListDetailSceneStrategy<TestKey>(directive = MockDualPaneScaffoldDirective)
-            scene =
-                strategy.calculateScene(listOf(listEntry, detailEntry, listEntry, detailEntry)) {}
+            scene = strategy.calculateScene(listOf(listEntry, detailEntry, listEntry, detailEntry))
         }
 
         composeRule.waitForIdle()
@@ -144,7 +144,7 @@
         composeRule.setContent {
             val strategy =
                 rememberListDetailSceneStrategy<TestKey>(directive = MockDualPaneScaffoldDirective)
-            scene = strategy.calculateScene(listOf(listEntry, nonListDetailEntry, detailEntry)) {}
+            scene = strategy.calculateScene(listOf(listEntry, nonListDetailEntry, detailEntry))
         }
 
         composeRule.waitForIdle()
@@ -160,7 +160,7 @@
             scene =
                 strategy.calculateScene(
                     listOf(listEntry, detailEntry, nonListDetailEntry, listEntry, detailEntry)
-                ) {}
+                )
         }
 
         composeRule.waitForIdle()
@@ -176,7 +176,7 @@
             scene =
                 strategy.calculateScene(
                     listOf(nonListDetailEntry, listEntry, detailEntry, detailEntry)
-                ) {}
+                )
         }
 
         composeRule.waitForIdle()
@@ -192,7 +192,7 @@
             scene =
                 strategy.calculateScene(
                     listOf(nonListDetailEntry, listEntry, listEntry, detailEntry)
-                ) {}
+                )
         }
 
         composeRule.waitForIdle()
@@ -211,7 +211,7 @@
         composeRule.setContent {
             val strategy =
                 rememberListDetailSceneStrategy<TestKey>(directive = MockDualPaneScaffoldDirective)
-            scene = strategy.calculateScene(listOf(listEntry1, listEntry2)) {}
+            scene = strategy.calculateScene(listOf(listEntry1, listEntry2))
         }
 
         composeRule.waitForIdle()
@@ -360,3 +360,8 @@
     NavEntry(DetailKey("1"), metadata = ListDetailSceneStrategy.detailPane()) {}
 
 private val nonListDetailEntry: NavEntry<TestKey> = NavEntry(HomeKey) {}
+
+private val EmptySceneStrategyScope = SceneStrategyScope<TestKey> {}
+
+private fun ListDetailSceneStrategy<TestKey>.calculateScene(entries: List<NavEntry<TestKey>>) =
+    with(this) { EmptySceneStrategyScope.calculateScene(entries) }
diff --git a/compose/material3/adaptive/adaptive-navigation3/src/androidInstrumentedTest/kotlin/androidx/compose/material3/adaptive/navigation3/SupportingPaneSceneStrategyTest.kt b/compose/material3/adaptive/adaptive-navigation3/src/androidInstrumentedTest/kotlin/androidx/compose/material3/adaptive/navigation3/SupportingPaneSceneStrategyTest.kt
index bde792e..0346118 100644
--- a/compose/material3/adaptive/adaptive-navigation3/src/androidInstrumentedTest/kotlin/androidx/compose/material3/adaptive/navigation3/SupportingPaneSceneStrategyTest.kt
+++ b/compose/material3/adaptive/adaptive-navigation3/src/androidInstrumentedTest/kotlin/androidx/compose/material3/adaptive/navigation3/SupportingPaneSceneStrategyTest.kt
@@ -40,6 +40,7 @@
 import androidx.navigation3.runtime.NavEntry
 import androidx.navigation3.runtime.entryProvider
 import androidx.navigation3.scene.Scene
+import androidx.navigation3.scene.SceneStrategyScope
 import androidx.navigation3.ui.NavDisplay
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.MediumTest
@@ -68,7 +69,7 @@
                 rememberSupportingPaneSceneStrategy<TestKey>(
                     directive = PaneScaffoldDirective.Default
                 )
-            scene = strategy.calculateScene(listOf(nonSupportingPaneEntry, mainEntry)) {}
+            scene = strategy.calculateScene(listOf(nonSupportingPaneEntry, mainEntry))
         }
 
         composeRule.waitForIdle()
@@ -84,7 +85,7 @@
                 rememberSupportingPaneSceneStrategy<TestKey>(
                     directive = MockDualVerticalPaneScaffoldDirective
                 )
-            scene = strategy.calculateScene(entries) {}
+            scene = strategy.calculateScene(entries)
         }
 
         composeRule.waitForIdle()
@@ -100,7 +101,7 @@
                 rememberSupportingPaneSceneStrategy<TestKey>(
                     directive = MockDualPaneScaffoldDirective
                 )
-            scene = strategy.calculateScene(entries) {}
+            scene = strategy.calculateScene(entries)
         }
 
         composeRule.waitForIdle()
@@ -115,7 +116,7 @@
                 rememberSupportingPaneSceneStrategy<TestKey>(
                     directive = MockDualPaneScaffoldDirective
                 )
-            scene = strategy.calculateScene(listOf(nonSupportingPaneEntry, mainEntry)) {}
+            scene = strategy.calculateScene(listOf(nonSupportingPaneEntry, mainEntry))
         }
 
         composeRule.waitForIdle()
@@ -131,9 +132,7 @@
                     directive = MockDualPaneScaffoldDirective
                 )
             scene =
-                strategy.calculateScene(
-                    listOf(mainEntry, nonSupportingPaneEntry, supportingEntry)
-                ) {}
+                strategy.calculateScene(listOf(mainEntry, nonSupportingPaneEntry, supportingEntry))
         }
 
         composeRule.waitForIdle()
@@ -154,7 +153,7 @@
                 rememberSupportingPaneSceneStrategy<TestKey>(
                     directive = MockDualPaneScaffoldDirective
                 )
-            scene = strategy.calculateScene(listOf(mainEntry1, mainEntry2)) {}
+            scene = strategy.calculateScene(listOf(mainEntry1, mainEntry2))
         }
 
         composeRule.waitForIdle()
@@ -270,3 +269,8 @@
 
 private val MockDualVerticalPaneScaffoldDirective =
     PaneScaffoldDirective.Default.copy(maxVerticalPartitions = 2)
+
+private val EmptySceneStrategyScope = SceneStrategyScope<TestKey> {}
+
+private fun SupportingPaneSceneStrategy<TestKey>.calculateScene(entries: List<NavEntry<TestKey>>) =
+    with(this) { EmptySceneStrategyScope.calculateScene(entries) }
diff --git a/compose/material3/adaptive/adaptive-navigation3/src/commonMain/kotlin/androidx/compose/material3/adaptive/navigation3/ListDetailSceneStrategy.kt b/compose/material3/adaptive/adaptive-navigation3/src/commonMain/kotlin/androidx/compose/material3/adaptive/navigation3/ListDetailSceneStrategy.kt
index ea4ab3c..097305a 100644
--- a/compose/material3/adaptive/adaptive-navigation3/src/commonMain/kotlin/androidx/compose/material3/adaptive/navigation3/ListDetailSceneStrategy.kt
+++ b/compose/material3/adaptive/adaptive-navigation3/src/commonMain/kotlin/androidx/compose/material3/adaptive/navigation3/ListDetailSceneStrategy.kt
@@ -34,6 +34,7 @@
 import androidx.navigation3.runtime.NavEntry
 import androidx.navigation3.scene.Scene
 import androidx.navigation3.scene.SceneStrategy
+import androidx.navigation3.scene.SceneStrategyScope
 
 /**
  * Creates and remembers a [ListDetailSceneStrategy].
@@ -42,6 +43,7 @@
  *   during the back navigation. See [BackNavigationBehavior].
  * @param directive The top-level directives about how the list-detail scaffold should arrange its
  *   panes.
+ * @sample androidx.compose.material3.adaptive.samples.ListDetailWithNavigation3Sample
  */
 @ExperimentalMaterial3AdaptiveApi
 @Composable
@@ -69,14 +71,15 @@
  *   during the back navigation. See [BackNavigationBehavior].
  * @param directive The top-level directives about how the list-detail scaffold should arrange its
  *   panes.
+ * @sample androidx.compose.material3.adaptive.samples.ListDetailWithNavigation3Sample
  */
 @ExperimentalMaterial3AdaptiveApi
 public class ListDetailSceneStrategy<T : Any>(
     public val backNavigationBehavior: BackNavigationBehavior,
     public val directive: PaneScaffoldDirective,
 ) : SceneStrategy<T> {
-    @Composable
-    override fun calculateScene(entries: List<NavEntry<T>>, onBack: () -> Unit): Scene<T>? {
+
+    override fun SceneStrategyScope<T>.calculateScene(entries: List<NavEntry<T>>): Scene<T>? {
         val lastPaneMetadata = getPaneMetadata(entries.last()) ?: return null
         val sceneKey = lastPaneMetadata.sceneKey
 
diff --git a/compose/material3/adaptive/adaptive-navigation3/src/commonMain/kotlin/androidx/compose/material3/adaptive/navigation3/SupportingPaneSceneStrategy.kt b/compose/material3/adaptive/adaptive-navigation3/src/commonMain/kotlin/androidx/compose/material3/adaptive/navigation3/SupportingPaneSceneStrategy.kt
index dccef0d..c7d0bdc 100644
--- a/compose/material3/adaptive/adaptive-navigation3/src/commonMain/kotlin/androidx/compose/material3/adaptive/navigation3/SupportingPaneSceneStrategy.kt
+++ b/compose/material3/adaptive/adaptive-navigation3/src/commonMain/kotlin/androidx/compose/material3/adaptive/navigation3/SupportingPaneSceneStrategy.kt
@@ -31,6 +31,7 @@
 import androidx.navigation3.runtime.NavEntry
 import androidx.navigation3.scene.Scene
 import androidx.navigation3.scene.SceneStrategy
+import androidx.navigation3.scene.SceneStrategyScope
 
 /**
  * Creates and remembers a [SupportingPaneSceneStrategy].
@@ -71,8 +72,8 @@
     public val backNavigationBehavior: BackNavigationBehavior,
     public val directive: PaneScaffoldDirective,
 ) : SceneStrategy<T> {
-    @Composable
-    override fun calculateScene(entries: List<NavEntry<T>>, onBack: () -> Unit): Scene<T>? {
+
+    override fun SceneStrategyScope<T>.calculateScene(entries: List<NavEntry<T>>): Scene<T>? {
         val lastPaneMetadata = getPaneMetadata(entries.last()) ?: return null
         val sceneKey = lastPaneMetadata.sceneKey
 
diff --git a/compose/material3/adaptive/adaptive/build.gradle b/compose/material3/adaptive/adaptive/build.gradle
index 1835998..5e9f284 100644
--- a/compose/material3/adaptive/adaptive/build.gradle
+++ b/compose/material3/adaptive/adaptive/build.gradle
@@ -95,7 +95,7 @@
             }
         }
 
-        androidUnitTest {
+        androidHostTest {
             dependsOn(commonTest)
             dependencies {
                 implementation(libs.junit)
diff --git a/compose/material3/adaptive/samples/build.gradle b/compose/material3/adaptive/samples/build.gradle
index 30c14f2..22082aa 100644
--- a/compose/material3/adaptive/samples/build.gradle
+++ b/compose/material3/adaptive/samples/build.gradle
@@ -29,11 +29,13 @@
     id("com.android.library")
     id("AndroidXComposePlugin")
     id("org.jetbrains.kotlin.android")
+    alias(libs.plugins.kotlinSerialization)
 }
 
 dependencies {
 
     implementation(libs.kotlinStdlib)
+    implementation(libs.kotlinSerializationCore)
 
     compileOnly(project(":annotation:annotation-sampled"))
 
@@ -42,12 +44,15 @@
     implementation("androidx.compose.material:material-icons-core:1.6.8")
     implementation(project(":compose:material3:adaptive:adaptive-layout"))
     implementation(project(":compose:material3:adaptive:adaptive-navigation"))
+    implementation(project(":compose:material3:adaptive:adaptive-navigation3"))
     implementation(project(":compose:material3:material3"))
     implementation(project(":compose:material3:material3-window-size-class"))
     implementation("androidx.compose.ui:ui-util:1.6.0-rc01")
     implementation("androidx.compose.ui:ui-tooling:1.4.1")
     implementation("androidx.compose.ui:ui-tooling-preview:1.4.1")
     implementation("androidx.navigation:navigation-compose:2.7.7")
+    implementation(project(":navigation3:navigation3-runtime"))
+    implementation(project(":navigation3:navigation3-ui"))
 }
 
 androidx {
@@ -58,7 +63,7 @@
 }
 
 android {
-    compileSdk = 35
+    compileSdk = 36
 
     namespace = "androidx.compose.material3.adaptive.samples"
 }
diff --git a/compose/material3/adaptive/samples/src/main/java/androidx/compose/material3/adaptive/samples/ThreePaneScaffoldSample.kt b/compose/material3/adaptive/samples/src/main/java/androidx/compose/material3/adaptive/samples/ThreePaneScaffoldSample.kt
index a2e38b6..1991cbf 100644
--- a/compose/material3/adaptive/samples/src/main/java/androidx/compose/material3/adaptive/samples/ThreePaneScaffoldSample.kt
+++ b/compose/material3/adaptive/samples/src/main/java/androidx/compose/material3/adaptive/samples/ThreePaneScaffoldSample.kt
@@ -29,6 +29,7 @@
 import androidx.compose.animation.slideOutHorizontally
 import androidx.compose.foundation.interaction.MutableInteractionSource
 import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.Column
 import androidx.compose.foundation.layout.ColumnScope
 import androidx.compose.foundation.layout.Row
@@ -84,6 +85,8 @@
 import androidx.compose.material3.adaptive.navigation.ThreePaneScaffoldNavigator
 import androidx.compose.material3.adaptive.navigation.rememberListDetailPaneScaffoldNavigator
 import androidx.compose.material3.adaptive.navigation.rememberSupportingPaneScaffoldNavigator
+import androidx.compose.material3.adaptive.navigation3.ListDetailSceneStrategy
+import androidx.compose.material3.adaptive.navigation3.rememberListDetailSceneStrategy
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.getValue
 import androidx.compose.runtime.mutableIntStateOf
@@ -105,8 +108,13 @@
 import androidx.navigation.compose.NavHost
 import androidx.navigation.compose.composable
 import androidx.navigation.compose.rememberNavController
+import androidx.navigation3.runtime.NavKey
+import androidx.navigation3.runtime.entryProvider
+import androidx.navigation3.runtime.rememberNavBackStack
+import androidx.navigation3.ui.NavDisplay
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.launch
+import kotlinx.serialization.Serializable
 
 @OptIn(ExperimentalMaterial3AdaptiveApi::class)
 @Preview
@@ -411,7 +419,7 @@
 @Preview
 @Sampled
 @Composable
-fun NavigableListDetailPaneScaffoldSample() {
+fun ListDetailWithNavigation2Sample() {
     val welcomeRoute = "welcome"
     val listDetailRoute = "listdetail"
 
@@ -539,6 +547,77 @@
 }
 
 @OptIn(ExperimentalMaterial3AdaptiveApi::class)
+@Preview
+@Sampled
+@Composable
+fun ListDetailWithNavigation3Sample() {
+    val backStack = rememberNavBackStack(HomeKey)
+    val sceneStrategy = rememberListDetailSceneStrategy<Any>()
+
+    val items = listOf("Item 1", "Item 2", "Item 3")
+    val extraItems = listOf("Extra 1", "Extra 2", "Extra 3")
+
+    val selectedIndex =
+        backStack.lastOrNull()?.let {
+            when (it) {
+                is DetailKey -> it.index
+                is ExtraKey -> it.index
+                else -> null
+            }
+        }
+
+    NavDisplay(
+        backStack = backStack,
+        modifier = Modifier.fillMaxSize(),
+        sceneStrategy = sceneStrategy,
+        entryProvider =
+            entryProvider {
+                entry<HomeKey> {
+                    Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
+                        Button(
+                            onClick = { if (backStack.last() != ListKey) backStack.add(ListKey) }
+                        ) {
+                            Text("Go to list")
+                        }
+                    }
+                }
+
+                entry<ListKey>(
+                    metadata =
+                        ListDetailSceneStrategy.listPane(
+                            detailPlaceholder = {
+                                DetailPaneContent(selectedItem = null, onShowExtra = {})
+                            }
+                        )
+                ) {
+                    ListPaneContent(
+                        items = items,
+                        selectedIndex = selectedIndex,
+                        onItemClick = { index ->
+                            val dest = DetailKey(index)
+                            if (backStack.last() != dest) backStack.add(dest)
+                        },
+                    )
+                }
+
+                entry<DetailKey>(metadata = ListDetailSceneStrategy.detailPane()) {
+                    DetailPaneContent(
+                        selectedItem = selectedIndex?.let { items[it] },
+                        onShowExtra = {
+                            val dest = ExtraKey(selectedIndex!!)
+                            if (backStack.last() != dest) backStack.add(dest)
+                        },
+                    )
+                }
+
+                entry<ExtraKey>(metadata = ListDetailSceneStrategy.extraPane()) {
+                    ExtraPaneContent(item = extraItems[selectedIndex!!])
+                }
+            },
+    )
+}
+
+@OptIn(ExperimentalMaterial3AdaptiveApi::class)
 private fun ThreePaneScaffoldNavigator<*>.isExpanded(role: ThreePaneScaffoldRole) =
     scaffoldValue[role] == PaneAdaptedValue.Expanded
 
@@ -559,6 +638,14 @@
     }
 }
 
+@Serializable private data object HomeKey : NavKey
+
+@Serializable private data object ListKey : NavKey
+
+@Serializable private data class DetailKey(val index: Int) : NavKey
+
+@Serializable private data class ExtraKey(val index: Int) : NavKey
+
 @Composable
 private fun ListCard(
     title: String,
@@ -632,6 +719,27 @@
     }
 }
 
+@Composable
+private fun ListPaneContent(
+    items: List<String>,
+    selectedIndex: Int?,
+    onItemClick: (index: Int) -> Unit,
+    modifier: Modifier = Modifier,
+) {
+    Column(
+        modifier = modifier.selectableGroup(),
+        verticalArrangement = Arrangement.spacedBy(8.dp),
+    ) {
+        items.forEachIndexed { index, item ->
+            ListCard(
+                title = item,
+                isSelected = index == selectedIndex,
+                onClick = { onItemClick(index) },
+            )
+        }
+    }
+}
+
 @OptIn(ExperimentalMaterial3AdaptiveApi::class)
 @Composable
 private fun DetailPaneContent(
@@ -683,6 +791,35 @@
     }
 }
 
+@Composable
+private fun DetailPaneContent(
+    selectedItem: String?,
+    onShowExtra: () -> Unit,
+    modifier: Modifier = Modifier,
+) {
+    val title: String
+    val description: String
+    if (selectedItem == null) {
+        title = "No item selected"
+        description = "Select an item from the list."
+    } else {
+        title = selectedItem
+        description = "This is a description about $selectedItem."
+    }
+
+    BasicScreen(
+        modifier = modifier,
+        title = title,
+        containerColor = MaterialTheme.colorScheme.surfaceContainer,
+        backButton = {},
+    ) {
+        Text(description)
+        if (selectedItem != null) {
+            Button(onClick = onShowExtra) { Text("Show extra") }
+        }
+    }
+}
+
 @OptIn(ExperimentalMaterial3AdaptiveApi::class)
 @Composable
 private fun MainPaneContent(
@@ -767,6 +904,18 @@
     }
 }
 
+@Composable
+private fun ExtraPaneContent(item: String, modifier: Modifier = Modifier) {
+    BasicScreen(
+        modifier = modifier,
+        title = item,
+        containerColor = MaterialTheme.colorScheme.surfaceContainerHighest,
+        backButton = {},
+    ) {
+        Text("This is extra content about $item.")
+    }
+}
+
 @OptIn(ExperimentalMaterial3Api::class)
 @Composable
 private fun BasicScreen(
diff --git a/compose/material3/material3-adaptive-navigation-suite/build.gradle b/compose/material3/material3-adaptive-navigation-suite/build.gradle
index 10fb68e..4afccb9 100644
--- a/compose/material3/material3-adaptive-navigation-suite/build.gradle
+++ b/compose/material3/material3-adaptive-navigation-suite/build.gradle
@@ -86,7 +86,7 @@
             }
         }
 
-        androidUnitTest {
+        androidHostTest {
             dependsOn(commonTest)
             dependencies {
                 implementation(libs.junit)
diff --git a/compose/material3/material3-adaptive-navigation-suite/src/androidUnitTest/kotlin/androidx/compose/material3/adaptive/navigationsuite/NavigationSuiteScaffoldTest.kt b/compose/material3/material3-adaptive-navigation-suite/src/androidHostTest/kotlin/androidx/compose/material3/adaptive/navigationsuite/NavigationSuiteScaffoldTest.kt
similarity index 100%
rename from compose/material3/material3-adaptive-navigation-suite/src/androidUnitTest/kotlin/androidx/compose/material3/adaptive/navigationsuite/NavigationSuiteScaffoldTest.kt
rename to compose/material3/material3-adaptive-navigation-suite/src/androidHostTest/kotlin/androidx/compose/material3/adaptive/navigationsuite/NavigationSuiteScaffoldTest.kt
diff --git a/compose/material3/material3-window-size-class/build.gradle b/compose/material3/material3-window-size-class/build.gradle
index 314b4b1..7abbe15 100644
--- a/compose/material3/material3-window-size-class/build.gradle
+++ b/compose/material3/material3-window-size-class/build.gradle
@@ -95,7 +95,7 @@
             }
         }
 
-        androidUnitTest {
+        androidHostTest {
             dependsOn(commonTest)
             dependencies {
                 implementation(libs.kotlinTest)
diff --git a/compose/material3/material3-window-size-class/src/androidUnitTest/kotlin/androidx/compose/material3/windowsizeclass/WindowSizeClassTest.kt b/compose/material3/material3-window-size-class/src/androidHostTest/kotlin/androidx/compose/material3/windowsizeclass/WindowSizeClassTest.kt
similarity index 100%
rename from compose/material3/material3-window-size-class/src/androidUnitTest/kotlin/androidx/compose/material3/windowsizeclass/WindowSizeClassTest.kt
rename to compose/material3/material3-window-size-class/src/androidHostTest/kotlin/androidx/compose/material3/windowsizeclass/WindowSizeClassTest.kt
diff --git a/compose/material3/material3/build.gradle b/compose/material3/material3/build.gradle
index 3604592..e2519f0 100644
--- a/compose/material3/material3/build.gradle
+++ b/compose/material3/material3/build.gradle
@@ -93,7 +93,7 @@
             dependsOn(commonStubsMain)
         }
 
-        androidUnitTest {
+        androidHostTest {
             dependsOn(commonTest)
             dependencies {
                 implementation(libs.testRules)
diff --git a/compose/material3/material3/integration-tests/material3-catalog/build.gradle b/compose/material3/material3/integration-tests/material3-catalog/build.gradle
index c2e18c4..76ad1e1 100644
--- a/compose/material3/material3/integration-tests/material3-catalog/build.gradle
+++ b/compose/material3/material3/integration-tests/material3-catalog/build.gradle
@@ -55,6 +55,6 @@
 }
 
 android {
-    compileSdk = 35
+    compileSdk = 36
     namespace = "androidx.compose.material3.catalog.library"
 }
diff --git a/compose/material3/material3/integration-tests/material3-catalog/src/main/java/androidx/compose/material3/catalog/library/model/Examples.kt b/compose/material3/material3/integration-tests/material3-catalog/src/main/java/androidx/compose/material3/catalog/library/model/Examples.kt
index 89b3356..6054891 100644
--- a/compose/material3/material3/integration-tests/material3-catalog/src/main/java/androidx/compose/material3/catalog/library/model/Examples.kt
+++ b/compose/material3/material3/integration-tests/material3-catalog/src/main/java/androidx/compose/material3/catalog/library/model/Examples.kt
@@ -24,7 +24,8 @@
 import androidx.compose.material3.adaptive.samples.ListDetailPaneScaffoldSample
 import androidx.compose.material3.adaptive.samples.ListDetailPaneScaffoldSampleWithExtraPane
 import androidx.compose.material3.adaptive.samples.ListDetailPaneScaffoldSampleWithExtraPaneLevitatedAsDialog
-import androidx.compose.material3.adaptive.samples.NavigableListDetailPaneScaffoldSample
+import androidx.compose.material3.adaptive.samples.ListDetailWithNavigation2Sample
+import androidx.compose.material3.adaptive.samples.ListDetailWithNavigation3Sample
 import androidx.compose.material3.adaptive.samples.SupportingPaneScaffoldSample
 import androidx.compose.material3.catalog.library.util.AdaptiveNavigationSuiteSampleSourceUrl
 import androidx.compose.material3.catalog.library.util.AdaptiveSampleSourceUrl
@@ -323,14 +324,6 @@
             ListDetailPaneScaffoldSampleWithExtraPaneLevitatedAsDialog()
         },
         Example(
-            name = "NavigableListDetailPaneScaffoldSample",
-            description = AdaptiveExampleDescription,
-            sourceUrl = AdaptiveExampleSourceUrl,
-            isExpressive = false,
-        ) {
-            NavigableListDetailPaneScaffoldSample()
-        },
-        Example(
             name = "SupportingPaneScaffoldSample",
             description = AdaptiveExampleDescription,
             sourceUrl = AdaptiveExampleSourceUrl,
@@ -338,6 +331,22 @@
         ) {
             SupportingPaneScaffoldSample()
         },
+        Example(
+            name = "ListDetailWithNavigation2Sample",
+            description = AdaptiveExampleDescription,
+            sourceUrl = AdaptiveExampleSourceUrl,
+            isExpressive = false,
+        ) {
+            ListDetailWithNavigation2Sample()
+        },
+        Example(
+            name = "ListDetailWithNavigation3Sample",
+            description = AdaptiveExampleDescription,
+            sourceUrl = AdaptiveExampleSourceUrl,
+            isExpressive = false,
+        ) {
+            ListDetailWithNavigation3Sample()
+        },
     )
 
 private const val BadgeExampleDescription = "Badge examples"
diff --git a/compose/material3/material3/src/androidUnitTest/AndroidManifest.xml b/compose/material3/material3/src/androidHostTest/AndroidManifest.xml
similarity index 100%
rename from compose/material3/material3/src/androidUnitTest/AndroidManifest.xml
rename to compose/material3/material3/src/androidHostTest/AndroidManifest.xml
diff --git a/compose/material3/material3/src/androidUnitTest/kotlin/androidx/compose/material3/carousel/ArrangementTest.kt b/compose/material3/material3/src/androidHostTest/kotlin/androidx/compose/material3/carousel/ArrangementTest.kt
similarity index 100%
rename from compose/material3/material3/src/androidUnitTest/kotlin/androidx/compose/material3/carousel/ArrangementTest.kt
rename to compose/material3/material3/src/androidHostTest/kotlin/androidx/compose/material3/carousel/ArrangementTest.kt
diff --git a/compose/material3/material3/src/androidUnitTest/kotlin/androidx/compose/material3/carousel/CenteredHeroTest.kt b/compose/material3/material3/src/androidHostTest/kotlin/androidx/compose/material3/carousel/CenteredHeroTest.kt
similarity index 100%
rename from compose/material3/material3/src/androidUnitTest/kotlin/androidx/compose/material3/carousel/CenteredHeroTest.kt
rename to compose/material3/material3/src/androidHostTest/kotlin/androidx/compose/material3/carousel/CenteredHeroTest.kt
diff --git a/compose/material3/material3/src/androidUnitTest/kotlin/androidx/compose/material3/carousel/KeylineSnapPositionTest.kt b/compose/material3/material3/src/androidHostTest/kotlin/androidx/compose/material3/carousel/KeylineSnapPositionTest.kt
similarity index 100%
rename from compose/material3/material3/src/androidUnitTest/kotlin/androidx/compose/material3/carousel/KeylineSnapPositionTest.kt
rename to compose/material3/material3/src/androidHostTest/kotlin/androidx/compose/material3/carousel/KeylineSnapPositionTest.kt
diff --git a/compose/material3/material3/src/androidUnitTest/kotlin/androidx/compose/material3/carousel/KeylineTest.kt b/compose/material3/material3/src/androidHostTest/kotlin/androidx/compose/material3/carousel/KeylineTest.kt
similarity index 100%
rename from compose/material3/material3/src/androidUnitTest/kotlin/androidx/compose/material3/carousel/KeylineTest.kt
rename to compose/material3/material3/src/androidHostTest/kotlin/androidx/compose/material3/carousel/KeylineTest.kt
diff --git a/compose/material3/material3/src/androidUnitTest/kotlin/androidx/compose/material3/carousel/MultiBrowseTest.kt b/compose/material3/material3/src/androidHostTest/kotlin/androidx/compose/material3/carousel/MultiBrowseTest.kt
similarity index 100%
rename from compose/material3/material3/src/androidUnitTest/kotlin/androidx/compose/material3/carousel/MultiBrowseTest.kt
rename to compose/material3/material3/src/androidHostTest/kotlin/androidx/compose/material3/carousel/MultiBrowseTest.kt
diff --git a/compose/material3/material3/src/androidUnitTest/kotlin/androidx/compose/material3/carousel/StrategyTest.kt b/compose/material3/material3/src/androidHostTest/kotlin/androidx/compose/material3/carousel/StrategyTest.kt
similarity index 100%
rename from compose/material3/material3/src/androidUnitTest/kotlin/androidx/compose/material3/carousel/StrategyTest.kt
rename to compose/material3/material3/src/androidHostTest/kotlin/androidx/compose/material3/carousel/StrategyTest.kt
diff --git a/compose/material3/material3/src/androidUnitTest/kotlin/androidx/compose/material3/carousel/UncontainedTest.kt b/compose/material3/material3/src/androidHostTest/kotlin/androidx/compose/material3/carousel/UncontainedTest.kt
similarity index 100%
rename from compose/material3/material3/src/androidUnitTest/kotlin/androidx/compose/material3/carousel/UncontainedTest.kt
rename to compose/material3/material3/src/androidHostTest/kotlin/androidx/compose/material3/carousel/UncontainedTest.kt
diff --git a/compose/material3/material3/src/androidInstrumentedTest/kotlin/androidx/compose/material3/ToggleButtonScreenshotTest.kt b/compose/material3/material3/src/androidInstrumentedTest/kotlin/androidx/compose/material3/ToggleButtonScreenshotTest.kt
index 5efdff1..178bfc0 100644
--- a/compose/material3/material3/src/androidInstrumentedTest/kotlin/androidx/compose/material3/ToggleButtonScreenshotTest.kt
+++ b/compose/material3/material3/src/androidInstrumentedTest/kotlin/androidx/compose/material3/ToggleButtonScreenshotTest.kt
@@ -35,7 +35,6 @@
 import androidx.test.filters.SdkSuppress
 import androidx.test.screenshot.AndroidXScreenshotTestRule
 import kotlinx.coroutines.test.StandardTestDispatcher
-import org.junit.Ignore
 import org.junit.Rule
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -103,7 +102,6 @@
         assertAgainstGolden("toggleButton_checked_darkTheme")
     }
 
-    @Ignore("b/355413615")
     @Test
     fun toggleButton_lightTheme_defaultToPressed() {
         rule.setMaterialContent(lightColorScheme()) {
@@ -126,7 +124,6 @@
         assertAgainstGolden("toggleButton_lightTheme_defaultToPressed")
     }
 
-    @Ignore("b/355413615")
     @Test
     fun toggleButton_lightTheme_checkedToPressed() {
         rule.setMaterialContent(lightColorScheme()) {
@@ -201,7 +198,6 @@
         assertAgainstGolden("elevatedToggleButton_checked_darkTheme")
     }
 
-    @Ignore("b/355413615")
     @Test
     fun elevatedToggleButton_lightTheme_defaultToPressed() {
         rule.setMaterialContent(lightColorScheme()) {
@@ -224,7 +220,6 @@
         assertAgainstGolden("elevatedToggleButton_lightTheme_defaultToPressed")
     }
 
-    @Ignore("b/355413615")
     @Test
     fun elevatedToggleButton_lightTheme_checkedToPressed() {
         rule.setMaterialContent(lightColorScheme()) {
@@ -299,7 +294,6 @@
         assertAgainstGolden("tonalToggleButton_checked_darkTheme")
     }
 
-    @Ignore("b/355413615")
     @Test
     fun tonalToggleButton_lightTheme_defaultToPressed() {
         rule.setMaterialContent(lightColorScheme()) {
@@ -322,7 +316,6 @@
         assertAgainstGolden("tonalToggleButton_lightTheme_defaultToPressed")
     }
 
-    @Ignore("b/355413615")
     @Test
     fun tonalToggleButton_lightTheme_checkedToPressed() {
         rule.setMaterialContent(lightColorScheme()) {
@@ -397,7 +390,6 @@
         assertAgainstGolden("outlinedToggleButton_checked_darkTheme")
     }
 
-    @Ignore("b/355413615")
     @Test
     fun outlinedToggleButton_lightTheme_defaultToPressed() {
         rule.setMaterialContent(lightColorScheme()) {
@@ -420,7 +412,6 @@
         assertAgainstGolden("outlinedToggleButton_lightTheme_defaultToPressed")
     }
 
-    @Ignore("b/355413615")
     @Test
     fun outlinedToggleButton_lightTheme_checkedToPressed() {
         rule.setMaterialContent(lightColorScheme()) {
@@ -533,7 +524,6 @@
         assertAgainstGolden("toggleButton_withIcon_checked_darkTheme")
     }
 
-    @Ignore("b/355413615")
     @Test
     fun toggleButton_withIcon_lightTheme_defaultToPressed() {
         rule.setMaterialContent(lightColorScheme()) {
@@ -564,7 +554,6 @@
         assertAgainstGolden("toggleButton_withIcon_lightTheme_defaultToPressed")
     }
 
-    @Ignore("b/355413615")
     @Test
     fun toggleButton_withIcon_lightTheme_checkedToPressed() {
         rule.setMaterialContent(lightColorScheme()) {
diff --git a/compose/remote/remote-creation-compose/src/androidTest/java/androidx/compose/remote/creation/compose/capture/CaptureRemoteDocumentTest.kt b/compose/remote/remote-creation-compose/src/androidTest/java/androidx/compose/remote/creation/compose/capture/CaptureRemoteDocumentTest.kt
new file mode 100644
index 0000000..3aed853
--- /dev/null
+++ b/compose/remote/remote-creation-compose/src/androidTest/java/androidx/compose/remote/creation/compose/capture/CaptureRemoteDocumentTest.kt
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2025 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 androidx.compose.remote.creation.compose.capture
+
+import android.content.Context
+import androidx.compose.remote.core.CoreDocument
+import androidx.compose.remote.core.RemoteComposeBuffer
+import androidx.compose.remote.creation.compose.SCREENSHOT_GOLDEN_DIRECTORY
+import androidx.compose.remote.creation.compose.layout.RemoteBox
+import androidx.compose.remote.creation.compose.modifier.RemoteModifier
+import androidx.compose.remote.creation.compose.modifier.background
+import androidx.compose.remote.creation.compose.modifier.fillMaxSize
+import androidx.compose.ui.graphics.Color
+import androidx.test.core.app.ApplicationProvider
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.MediumTest
+import androidx.test.filters.SdkSuppress
+import androidx.test.screenshot.AndroidXScreenshotTestRule
+import java.io.ByteArrayInputStream
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.test.runTest
+import kotlinx.coroutines.withContext
+import org.junit.Assert.assertTrue
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+
+/** Emulator-based screenshot test of [RecordingCanvas]. */
+@SdkSuppress(minSdkVersion = 35, maxSdkVersion = 35)
+@RunWith(AndroidJUnit4::class)
+@MediumTest
+class CaptureRemoteDocumentTest {
+    private val context: Context = ApplicationProvider.getApplicationContext()
+    @get:Rule val screenshotRule = AndroidXScreenshotTestRule(SCREENSHOT_GOLDEN_DIRECTORY)
+
+    @Test
+    fun captureDocument() = runTest {
+        val document: ByteArray =
+            withContext(Dispatchers.Main) {
+                captureRemoteDocument(context) {
+                    RemoteBox(modifier = RemoteModifier.fillMaxSize().background(Color.Red)) {}
+                }
+            }
+
+        val remoteComposeDocument =
+            CoreDocument().apply {
+                ByteArrayInputStream(document).use {
+                    initFromBuffer(RemoteComposeBuffer.fromInputStream(it))
+                }
+            }
+
+        assertTrue(remoteComposeDocument.docInfo.mNumberOfOps > 0)
+    }
+}
diff --git a/compose/remote/remote-creation-compose/src/androidTest/java/androidx/compose/remote/creation/compose/capture/RecordingCanvasTest.kt b/compose/remote/remote-creation-compose/src/androidTest/java/androidx/compose/remote/creation/compose/capture/RecordingCanvasTest.kt
index 0d12aa5..6c53427 100644
--- a/compose/remote/remote-creation-compose/src/androidTest/java/androidx/compose/remote/creation/compose/capture/RecordingCanvasTest.kt
+++ b/compose/remote/remote-creation-compose/src/androidTest/java/androidx/compose/remote/creation/compose/capture/RecordingCanvasTest.kt
@@ -23,6 +23,8 @@
 import android.graphics.Canvas
 import android.graphics.Color
 import android.graphics.Paint
+import android.graphics.Rect
+import android.graphics.Typeface
 import androidx.compose.remote.core.CoreDocument
 import androidx.compose.remote.core.Operation
 import androidx.compose.remote.core.Profiles
@@ -286,6 +288,48 @@
         assertThat(paintCopy.remoteColorFilter).isEqualTo(paint.remoteColorFilter)
     }
 
+    @Test
+    fun drawToOffscreenBitmap() {
+        recordingCanvas.drawRect(0, 0, WIDTH, HEIGHT, Paint().apply { color = Color.BLACK })
+        recordingCanvas.drawRect(
+            20,
+            20,
+            WIDTH - 20,
+            HEIGHT - 20,
+            Paint().apply { color = Color.YELLOW },
+        )
+        val bitmap =
+            recordingCanvas.drawToOffscreenBitmap(WIDTH, HEIGHT, Color.BLACK) {
+                recordingCanvas.drawOval(
+                    20,
+                    20,
+                    WIDTH - 20,
+                    HEIGHT - 20,
+                    Paint().apply { color = Color.RED },
+                )
+                recordingCanvas.drawText(
+                    "HI",
+                    20,
+                    HEIGHT - 50,
+                    Paint().apply {
+                        textSize = 380f
+                        typeface = Typeface.DEFAULT_BOLD
+                        blendMode = BlendMode.CLEAR
+                    },
+                )
+            }
+        val rect = Rect(0, 0, WIDTH, HEIGHT)
+        recordingCanvas.drawBitmap(
+            bitmap,
+            rect,
+            rect,
+            Paint().apply { blendMode = BlendMode.SRC_OVER },
+        )
+
+        val document = constructDocument()
+        assertScreenshot(document, "offscreenBitmap")
+    }
+
     private fun constructDocument() =
         CoreDocument().apply {
             val buffer = creationState.document.buffer
diff --git a/compose/remote/remote-creation-compose/src/main/java/androidx/compose/remote/creation/compose/capture/CaptureRemoteDocument.kt b/compose/remote/remote-creation-compose/src/main/java/androidx/compose/remote/creation/compose/capture/CaptureRemoteDocument.kt
new file mode 100644
index 0000000..24f3a0b
--- /dev/null
+++ b/compose/remote/remote-creation-compose/src/main/java/androidx/compose/remote/creation/compose/capture/CaptureRemoteDocument.kt
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2025 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 androidx.compose.remote.creation.compose.capture
+
+import android.content.Context
+import androidx.annotation.RestrictTo
+import androidx.compose.remote.creation.compose.layout.RemoteComposable
+import androidx.compose.remote.creation.profile.PlatformProfile
+import androidx.compose.remote.creation.profile.Profile
+import androidx.compose.runtime.Composable
+import kotlin.coroutines.resume
+import kotlin.coroutines.suspendCoroutine
+
+/**
+ * Capture a RemoteCompose document by rendering the specified [content] Composable in a virtual
+ * display and returning the resulting bytes.
+ *
+ * This can be used for testing, or for generating documents on the fly to be sent to a remote
+ * client.
+ *
+ * @param context the Android [Context] to use for the capture.
+ * @param creationDisplayInfo details about the virtual display to create.
+ * @param profile the [Profile] to use for the capture, determining which operations are supported.
+ * @param content the Composable content to render and capture.
+ * @return a [ByteArray] containing the RemoteCompose document.
+ */
+@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+public suspend fun captureRemoteDocument(
+    context: Context,
+    creationDisplayInfo: CreationDisplayInfo = CreationDisplayInfo(),
+    profile: Profile = PlatformProfile.ANDROIDX,
+    content: @Composable @RemoteComposable () -> Unit,
+): ByteArray = suspendCoroutine { continuation ->
+    var completed = false
+    RemoteComposeCapture(
+        context = context,
+        creationDisplayInfo = creationDisplayInfo,
+        immediateCapture = true,
+        onPaint = { view, writer ->
+            if (!completed) {
+                completed = true
+                continuation.resume(writer.encodeToByteArray())
+            }
+            true
+        },
+        onCaptureReady = @Composable {},
+        profile = profile,
+        content = content,
+    )
+}
diff --git a/compose/remote/remote-creation-compose/src/main/java/androidx/compose/remote/creation/compose/capture/RecordingCanvas.kt b/compose/remote/remote-creation-compose/src/main/java/androidx/compose/remote/creation/compose/capture/RecordingCanvas.kt
index a48bcbf..e1c1852 100644
--- a/compose/remote/remote-creation-compose/src/main/java/androidx/compose/remote/creation/compose/capture/RecordingCanvas.kt
+++ b/compose/remote/remote-creation-compose/src/main/java/androidx/compose/remote/creation/compose/capture/RecordingCanvas.kt
@@ -21,6 +21,7 @@
 import android.graphics.BlendMode
 import android.graphics.BlendModeColorFilter
 import android.graphics.Canvas
+import android.graphics.Color
 import android.graphics.ColorFilter
 import android.graphics.Paint
 import android.graphics.Path
@@ -29,6 +30,7 @@
 import android.graphics.Region
 import android.graphics.Typeface
 import android.os.Build
+import androidx.annotation.ColorInt
 import androidx.annotation.RequiresApi
 import androidx.annotation.RestrictTo
 import androidx.compose.remote.core.operations.ConditionalOperations
@@ -1421,9 +1423,49 @@
         )
         forceSendingPaint(true)
         drawCommands()
+        forceSendingPaint(true)
         document.endConditionalOperations()
     }
 
+    /**
+     * Instructs the player to draw [drawCommands] into an offscreen [RemoteBitmap] created with the
+     * specified [width] & [height]. The offscreen bitmap will be cleared with [clearColor] before
+     * any [drawCommands] are processed.
+     *
+     * @param width The width in pixels for the created offscreen bitmap.
+     * @param height The height in pixels for the created offscreen bitmap.
+     * @param clearColor If non-null the color the created offecreen bitmap will be cleared with.
+     * @param drawCommands The commands the player will execute in the offscreen buffer.
+     * @return The [RemoteBitmap] the [drawCommands] were drawn into.
+     */
+    public fun drawToOffscreenBitmap(
+        width: Int,
+        height: Int,
+        @ColorInt clearColor: Int,
+        drawCommands: () -> Unit,
+    ): RemoteBitmap {
+        val bitmapId = document.createBitmap(width, height)
+        if (clearColor != Color.BLACK) {
+            document.drawOnBitmap(bitmapId, 0, clearColor)
+        } else {
+            document.drawOnBitmap(bitmapId, 1, 0)
+        }
+        forceSendingPaint(true)
+        drawCommands()
+        forceSendingPaint(true)
+        document.drawOnBitmap(0, 0, 0)
+
+        return object : RemoteBitmap(creationState, null) {
+            public override fun writeToDocument(creationState: RemoteComposeCreationState): Int =
+                bitmapId
+
+            public override val value: Bitmap
+                get() {
+                    throw UnsupportedOperationException()
+                }
+        }
+    }
+
     public companion object {
         // TODO replace this with a dedicated color space for RemoteCompose.
         internal const val REMOTE_COMPOSE_EXPRESSION_COLOR_SPACE_ID = 5L
diff --git a/compose/runtime/runtime-retain/build.gradle b/compose/runtime/runtime-retain/build.gradle
index d7f821d..b9f797b 100644
--- a/compose/runtime/runtime-retain/build.gradle
+++ b/compose/runtime/runtime-retain/build.gradle
@@ -93,7 +93,7 @@
             dependsOn(jvmMain)
         }
 
-        androidUnitTest {
+        androidHostTest {
             dependsOn(jvmTest)
         }
 
diff --git a/compose/runtime/runtime-saveable/build.gradle b/compose/runtime/runtime-saveable/build.gradle
index f12c736..f19a779 100644
--- a/compose/runtime/runtime-saveable/build.gradle
+++ b/compose/runtime/runtime-saveable/build.gradle
@@ -96,7 +96,7 @@
             }
         }
 
-        androidUnitTest {
+        androidHostTest {
             dependsOn(commonTest)
             dependencies {
                 implementation(libs.testRules)
diff --git a/compose/runtime/runtime-saveable/src/androidUnitTest/kotlin/androidx/compose/runtime/saveable/AutoSaverTest.kt b/compose/runtime/runtime-saveable/src/androidHostTest/kotlin/androidx/compose/runtime/saveable/AutoSaverTest.kt
similarity index 100%
rename from compose/runtime/runtime-saveable/src/androidUnitTest/kotlin/androidx/compose/runtime/saveable/AutoSaverTest.kt
rename to compose/runtime/runtime-saveable/src/androidHostTest/kotlin/androidx/compose/runtime/saveable/AutoSaverTest.kt
diff --git a/compose/runtime/runtime-saveable/src/androidUnitTest/kotlin/androidx/compose/runtime/saveable/ListSaverTest.kt b/compose/runtime/runtime-saveable/src/androidHostTest/kotlin/androidx/compose/runtime/saveable/ListSaverTest.kt
similarity index 100%
rename from compose/runtime/runtime-saveable/src/androidUnitTest/kotlin/androidx/compose/runtime/saveable/ListSaverTest.kt
rename to compose/runtime/runtime-saveable/src/androidHostTest/kotlin/androidx/compose/runtime/saveable/ListSaverTest.kt
diff --git a/compose/runtime/runtime-saveable/src/androidUnitTest/kotlin/androidx/compose/runtime/saveable/MapSaverTest.kt b/compose/runtime/runtime-saveable/src/androidHostTest/kotlin/androidx/compose/runtime/saveable/MapSaverTest.kt
similarity index 100%
rename from compose/runtime/runtime-saveable/src/androidUnitTest/kotlin/androidx/compose/runtime/saveable/MapSaverTest.kt
rename to compose/runtime/runtime-saveable/src/androidHostTest/kotlin/androidx/compose/runtime/saveable/MapSaverTest.kt
diff --git a/compose/runtime/runtime-saveable/src/androidUnitTest/kotlin/androidx/compose/runtime/saveable/SaveableStateRegistryTest.kt b/compose/runtime/runtime-saveable/src/androidHostTest/kotlin/androidx/compose/runtime/saveable/SaveableStateRegistryTest.kt
similarity index 100%
rename from compose/runtime/runtime-saveable/src/androidUnitTest/kotlin/androidx/compose/runtime/saveable/SaveableStateRegistryTest.kt
rename to compose/runtime/runtime-saveable/src/androidHostTest/kotlin/androidx/compose/runtime/saveable/SaveableStateRegistryTest.kt
diff --git a/compose/runtime/runtime/build.gradle b/compose/runtime/runtime/build.gradle
index ec3714f..22b06de 100644
--- a/compose/runtime/runtime/build.gradle
+++ b/compose/runtime/runtime/build.gradle
@@ -121,7 +121,7 @@
             }
         }
 
-        androidUnitTest {
+        androidHostTest {
             dependsOn(jvmTest)
             dependsOn(nonEmulatorJvmTest)
         }
diff --git a/compose/runtime/runtime/src/androidUnitTest/kotlin/kotlinx/test/IgnoreTargets.android.kt b/compose/runtime/runtime/src/androidHostTest/kotlin/kotlinx/test/IgnoreTargets.android.kt
similarity index 100%
rename from compose/runtime/runtime/src/androidUnitTest/kotlin/kotlinx/test/IgnoreTargets.android.kt
rename to compose/runtime/runtime/src/androidHostTest/kotlin/kotlinx/test/IgnoreTargets.android.kt
diff --git a/compose/test-utils/build.gradle b/compose/test-utils/build.gradle
index 29781c1..4400e49 100644
--- a/compose/test-utils/build.gradle
+++ b/compose/test-utils/build.gradle
@@ -95,7 +95,7 @@
             }
         }
 
-        androidUnitTest {
+        androidHostTest {
             dependsOn(commonTest)
             dependencies {
                 implementation(libs.truth)
diff --git a/compose/test-utils/src/androidUnitTest/kotlin/androidx/compose/testutils/DpAssertionsTest.kt b/compose/test-utils/src/androidHostTest/kotlin/androidx/compose/testutils/DpAssertionsTest.kt
similarity index 100%
rename from compose/test-utils/src/androidUnitTest/kotlin/androidx/compose/testutils/DpAssertionsTest.kt
rename to compose/test-utils/src/androidHostTest/kotlin/androidx/compose/testutils/DpAssertionsTest.kt
diff --git a/compose/test-utils/src/androidUnitTest/kotlin/androidx/compose/testutils/ExpectTest.kt b/compose/test-utils/src/androidHostTest/kotlin/androidx/compose/testutils/ExpectTest.kt
similarity index 100%
rename from compose/test-utils/src/androidUnitTest/kotlin/androidx/compose/testutils/ExpectTest.kt
rename to compose/test-utils/src/androidHostTest/kotlin/androidx/compose/testutils/ExpectTest.kt
diff --git a/compose/ui/ui-geometry/build.gradle b/compose/ui/ui-geometry/build.gradle
index 9a69298..0b06ca2 100644
--- a/compose/ui/ui-geometry/build.gradle
+++ b/compose/ui/ui-geometry/build.gradle
@@ -88,7 +88,7 @@
             }
         }
 
-        androidUnitTest {
+        androidHostTest {
             dependsOn(jvmTest)
         }
     }
diff --git a/compose/ui/ui-graphics/build.gradle b/compose/ui/ui-graphics/build.gradle
index b3e3313..85563aa 100644
--- a/compose/ui/ui-graphics/build.gradle
+++ b/compose/ui/ui-graphics/build.gradle
@@ -102,7 +102,7 @@
             }
         }
 
-        androidUnitTest {
+        androidHostTest {
             dependencies {
                 implementation(libs.testRules)
                 implementation(libs.testRunner)
diff --git a/compose/ui/ui-graphics/src/androidUnitTest/kotlin/androidx/compose/ui/graphics/BrushInterpolationTests.kt b/compose/ui/ui-graphics/src/androidHostTest/kotlin/androidx/compose/ui/graphics/BrushInterpolationTests.kt
similarity index 100%
rename from compose/ui/ui-graphics/src/androidUnitTest/kotlin/androidx/compose/ui/graphics/BrushInterpolationTests.kt
rename to compose/ui/ui-graphics/src/androidHostTest/kotlin/androidx/compose/ui/graphics/BrushInterpolationTests.kt
diff --git a/compose/ui/ui-graphics/src/androidUnitTest/kotlin/androidx/compose/ui/graphics/InterpolatableTests.kt b/compose/ui/ui-graphics/src/androidHostTest/kotlin/androidx/compose/ui/graphics/InterpolatableTests.kt
similarity index 100%
rename from compose/ui/ui-graphics/src/androidUnitTest/kotlin/androidx/compose/ui/graphics/InterpolatableTests.kt
rename to compose/ui/ui-graphics/src/androidHostTest/kotlin/androidx/compose/ui/graphics/InterpolatableTests.kt
diff --git a/compose/ui/ui-graphics/src/androidUnitTest/kotlin/androidx/compose/ui/graphics/ShadowInterpolationTests.kt b/compose/ui/ui-graphics/src/androidHostTest/kotlin/androidx/compose/ui/graphics/ShadowInterpolationTests.kt
similarity index 100%
rename from compose/ui/ui-graphics/src/androidUnitTest/kotlin/androidx/compose/ui/graphics/ShadowInterpolationTests.kt
rename to compose/ui/ui-graphics/src/androidHostTest/kotlin/androidx/compose/ui/graphics/ShadowInterpolationTests.kt
diff --git a/compose/ui/ui-graphics/src/androidUnitTest/kotlin/androidx/compose/ui/graphics/layer/RobolectricGraphicsLayerTest.kt b/compose/ui/ui-graphics/src/androidHostTest/kotlin/androidx/compose/ui/graphics/layer/RobolectricGraphicsLayerTest.kt
similarity index 100%
rename from compose/ui/ui-graphics/src/androidUnitTest/kotlin/androidx/compose/ui/graphics/layer/RobolectricGraphicsLayerTest.kt
rename to compose/ui/ui-graphics/src/androidHostTest/kotlin/androidx/compose/ui/graphics/layer/RobolectricGraphicsLayerTest.kt
diff --git a/compose/ui/ui-lint/src/main/java/androidx/compose/ui/lint/LocalContextResourcesConfigurationReadDetector.kt b/compose/ui/ui-lint/src/main/java/androidx/compose/ui/lint/LocalContextResourcesConfigurationReadDetector.kt
index ccae551..28c6ef6 100644
--- a/compose/ui/ui-lint/src/main/java/androidx/compose/ui/lint/LocalContextResourcesConfigurationReadDetector.kt
+++ b/compose/ui/ui-lint/src/main/java/androidx/compose/ui/lint/LocalContextResourcesConfigurationReadDetector.kt
@@ -31,7 +31,6 @@
 import com.android.tools.lint.detector.api.Implementation
 import com.android.tools.lint.detector.api.Issue
 import com.android.tools.lint.detector.api.JavaContext
-import com.android.tools.lint.detector.api.LintFix
 import com.android.tools.lint.detector.api.Scope
 import com.android.tools.lint.detector.api.Severity
 import com.android.tools.lint.detector.api.SourceCodeScanner
@@ -39,6 +38,7 @@
 import com.intellij.psi.PsiMember
 import com.intellij.psi.PsiMethod
 import java.util.EnumSet
+import org.jetbrains.kotlin.psi.KtCallExpression
 import org.jetbrains.uast.UCallExpression
 import org.jetbrains.uast.UElement
 import org.jetbrains.uast.UExpression
@@ -80,7 +80,7 @@
                         node,
                         context.getNameLocation(node),
                         "Reading Configuration using $LocalContextCurrentResourcesConfiguration",
-                        LintFix.create()
+                        fix()
                             .replace()
                             .name("Replace with $LocalConfigurationCurrent")
                             .all()
@@ -122,8 +122,9 @@
                 val selector = node.selector.skipParenthesizedExprDown()
                 val configurationCall = selector.isCallToGetConfiguration()
                 val resourcesCall = selector.isCallToGetResources()
-                val contextGetResourceValueCall = selector.isContextGetResourceValueCall()
-                if (!configurationCall && !resourcesCall && !contextGetResourceValueCall) return
+                val contextGetResourceValueCallName = selector.getContextGetResourceValueCallName()
+                if (!configurationCall && !resourcesCall && contextGetResourceValueCallName == null)
+                    return
 
                 // Either the expression with resources when the selector is resources.configuration
                 // or the expression with context when the selector is
@@ -188,12 +189,89 @@
                             // report after we analyze the file, to avoid double reporting as
                             // mentioned above
                             contextResourcesCalls.add(node)
-                        } else if (contextGetResourceValueCall) {
+                        } else if (contextGetResourceValueCallName != null) {
+                            val selectorCallExpression = selector.sourcePsi as? KtCallExpression
+                            // Text of the call's value arguments
+                            val valueArgumentText = selectorCallExpression?.valueArgumentList?.text
+                            // Whole text of the node
+                            val nodeText = node.sourcePsi?.text
+                            val textToReplace =
+                                if (valueArgumentText != null && nodeText != null) {
+                                    nodeText.substringBefore(valueArgumentText)
+                                } else null
+                            val replaceWith =
+                                textToReplace?.let {
+                                    when (contextGetResourceValueCallName) {
+                                        ContextGetString -> {
+                                            fix()
+                                                .replace()
+                                                .name("Replace with stringResource")
+                                                .text(textToReplace)
+                                                .with("stringResource")
+                                                .imports("$ComposeUiResPackage.stringResource")
+                                                .autoFix()
+                                                .build()
+                                        }
+
+                                        ContextGetColor -> {
+                                            fix()
+                                                .replace()
+                                                .name("Replace with colorResource")
+                                                .text(textToReplace)
+                                                .with("colorResource")
+                                                .imports("$ComposeUiResPackage.colorResource")
+                                                .autoFix()
+                                                .build()
+                                        }
+
+                                        ContextGetDrawable -> {
+                                            fix()
+                                                .alternatives(
+                                                    fix()
+                                                        .replace()
+                                                        .name("Replace with painterResource")
+                                                        .text(textToReplace)
+                                                        .with("painterResource")
+                                                        .imports(
+                                                            "$ComposeUiResPackage.painterResource"
+                                                        )
+                                                        .autoFix()
+                                                        .build(),
+                                                    fix()
+                                                        .replace()
+                                                        .name(
+                                                            "Replace with ImageBitmap.imageResource"
+                                                        )
+                                                        .text(textToReplace)
+                                                        .with("ImageBitmap.imageResource")
+                                                        .imports(
+                                                            "$ComposeUiResPackage.imageResource"
+                                                        )
+                                                        .autoFix()
+                                                        .build(),
+                                                    fix()
+                                                        .replace()
+                                                        .name(
+                                                            "Replace with ImageVector.vectorResource"
+                                                        )
+                                                        .text(textToReplace)
+                                                        .with("ImageVector.vectorResource")
+                                                        .imports(
+                                                            "$ComposeUiResPackage.vectorResource"
+                                                        )
+                                                        .autoFix()
+                                                        .build(),
+                                                )
+                                        }
+                                        else -> null
+                                    }
+                                }
                             context.report(
                                 LocalContextGetResourceValueCall,
                                 node,
                                 context.getNameLocation(node),
                                 "Querying resource values using $LocalContextCurrent",
+                                replaceWith,
                             )
                         }
                     }
@@ -246,7 +324,7 @@
                         resourcesCall,
                         context.getNameLocation(resourcesCall),
                         "Reading Resources using $LocalContextCurrentResources",
-                        LintFix.create()
+                        fix()
                             .replace()
                             .name("Replace with $LocalResourcesCurrent")
                             .all()
@@ -323,12 +401,19 @@
         return resolved.name == "getResources" && resolved.isInPackageName(ContentPackage)
     }
 
-    private fun UElement.isContextGetResourceValueCall(): Boolean {
-        val expression = (this as? UCallExpression) ?: return false
-        if (expression.receiverType?.inheritsFrom(ContextName) != true) return false
-        val resolved = expression.resolve() ?: return false
-        return ContextGetResourceValueMethods.any { resolved.name == it } &&
-            resolved.isInPackageName(ContentPackage)
+    /**
+     * @return the method name if this is a call to one of the resource value methods in
+     *   [ContextGetResourceValueMethods], else null
+     */
+    private fun UElement.getContextGetResourceValueCallName(): String? {
+        val expression = (this as? UCallExpression) ?: return null
+        if (expression.receiverType?.inheritsFrom(ContextName) != true) return null
+        val resolved = expression.resolve() ?: return null
+        return if (resolved.isInPackageName(ContentPackage)) {
+            ContextGetResourceValueMethods.firstOrNull { resolved.name == it }
+        } else {
+            null
+        }
     }
 
     /**
@@ -361,8 +446,20 @@
             "LocalContext.current.resources.configuration"
         private const val LocalResourcesCurrent = "LocalResources.current"
         private const val LocalConfigurationCurrent = "LocalConfiguration.current"
+        private const val ContextGetText = "getText"
+        private const val ContextGetString = "getString"
+        private const val ContextGetColor = "getColor"
+        private const val ContextGetDrawable = "getDrawable"
+        private const val ContextGetColorStateList = "getColorStateList"
+        private const val ComposeUiResPackage = "androidx.compose.ui.res"
         private val ContextGetResourceValueMethods =
-            listOf("getText", "getString", "getColor", "getDrawable", "getColorStateList")
+            listOf(
+                ContextGetText,
+                ContextGetString,
+                ContextGetColor,
+                ContextGetDrawable,
+                ContextGetColorStateList,
+            )
         private val ContentPackage = Package("android.content")
         private val ResPackage = Package("android.content.res")
         private val ContextName = Name(ContentPackage, "Context")
@@ -389,7 +486,14 @@
             Issue.create(
                 "LocalContextGetResourceValueCall",
                 "Querying resource properties using $LocalContextCurrent",
-                "Changes to the Configuration object will not cause $LocalContextCurrent reads to be invalidated, so calls to APIs such as Context.getString() will not be updated when the Configuration changes, and so stale values might be used. Instead, use $LocalResourcesCurrent and query properties from Resources directly - this will invalidate callers when the Configuration changes, to ensure that these calls reflect the latest values.",
+                "Changes to the Configuration object will not cause " +
+                    "$LocalContextCurrent reads to be invalidated, so calls to APIs such as " +
+                    "Context.getString() will not be updated when the Configuration changes, " +
+                    "and so stale values might be used. Instead, you can use Compose APIs such " +
+                    "as stringResource, colorResource, and painterResource - or " +
+                    "$LocalResourcesCurrent and query properties from Resources directly. Using " +
+                    "these APIs will invalidate callers when the Configuration changes, to " +
+                    "ensure that these calls reflect the latest values.",
                 Category.CORRECTNESS,
                 3,
                 Severity.ERROR,
diff --git a/compose/ui/ui-lint/src/test/java/androidx/compose/ui/lint/LocalContextResourcesConfigurationReadDetectorTest.kt b/compose/ui/ui-lint/src/test/java/androidx/compose/ui/lint/LocalContextResourcesConfigurationReadDetectorTest.kt
index fdd2ee8..3faf81d4 100644
--- a/compose/ui/ui-lint/src/test/java/androidx/compose/ui/lint/LocalContextResourcesConfigurationReadDetectorTest.kt
+++ b/compose/ui/ui-lint/src/test/java/androidx/compose/ui/lint/LocalContextResourcesConfigurationReadDetectorTest.kt
@@ -188,19 +188,55 @@
             .expectFixDiffs(
                 """
 Autofix for src/test/test.kt line 11: Replace with LocalConfiguration.current:
-@@ -5 +5
--                 import androidx.compose.ui.platform.LocalContext
-+                 import androidx.compose.ui.platform.LocalConfiguration
-+ import androidx.compose.ui.platform.LocalContext
-@@ -11 +12
--                     LocalContext.current.resources.configuration
-+                     LocalConfiguration.current
+@@ -5 +5,2 @@
+-                import androidx.compose.ui.platform.LocalContext
++                import androidx.compose.ui.platform.LocalConfiguration
++import androidx.compose.ui.platform.LocalContext
+@@ -11 +12 @@
+-                    LocalContext.current.resources.configuration
++                    LocalConfiguration.current
+Autofix for src/test/test.kt line 14: Replace with stringResource:
+@@ -5,0 +6 @@
++import androidx.compose.ui.res.stringResource
+@@ -14 +15 @@
+-                    LocalContext.current.getString(-1)
++                    stringResource(-1)
+Autofix for src/test/test.kt line 15: Replace with stringResource:
+@@ -5,0 +6 @@
++import androidx.compose.ui.res.stringResource
+@@ -15 +16 @@
+-                    LocalContext.current.getString(-1, Any())
++                    stringResource(-1, Any())
+Autofix for src/test/test.kt line 16: Replace with colorResource:
+@@ -5,0 +6 @@
++import androidx.compose.ui.res.colorResource
+@@ -16 +17 @@
+-                    LocalContext.current.getColor(-1)
++                    colorResource(-1)
+Autofix for src/test/test.kt line 17: Replace with painterResource:
+@@ -5,0 +6 @@
++import androidx.compose.ui.res.painterResource
+@@ -17 +18 @@
+-                    LocalContext.current.getDrawable(-1)
++                    painterResource(-1)
+Autofix for src/test/test.kt line 17: Replace with ImageBitmap.imageResource:
+@@ -5,0 +6 @@
++import androidx.compose.ui.res.imageResource
+@@ -17 +18 @@
+-                    LocalContext.current.getDrawable(-1)
++                    ImageBitmap.imageResource(-1)
+Autofix for src/test/test.kt line 17: Replace with ImageVector.vectorResource:
+@@ -5,0 +6 @@
++import androidx.compose.ui.res.vectorResource
+@@ -17 +18 @@
+-                    LocalContext.current.getDrawable(-1)
++                    ImageVector.vectorResource(-1)
 Autofix for src/test/test.kt line 9: Replace with LocalResources.current:
-@@ -6 +6
-+ import androidx.compose.ui.platform.LocalResources
-@@ -9 +10
--                     LocalContext.current.resources
-+                     LocalResources.current
+@@ -5,0 +6 @@
++import androidx.compose.ui.platform.LocalResources
+@@ -9 +10 @@
+-                    LocalContext.current.resources
++                    LocalResources.current
                 """
             )
     }
@@ -298,6 +334,46 @@
 9 errors, 1 warning
             """
             )
+            .expectFixDiffs(
+                """
+Autofix for src/test/test.kt line 36: Replace with stringResource:
+@@ -5,0 +6 @@
++import androidx.compose.ui.res.stringResource
+@@ -36 +37 @@
+-                    context.getString(-1)
++                    stringResource(-1)
+Autofix for src/test/test.kt line 37: Replace with stringResource:
+@@ -5,0 +6 @@
++import androidx.compose.ui.res.stringResource
+@@ -37 +38 @@
+-                    context.getString(-1, Any())
++                    stringResource(-1, Any())
+Autofix for src/test/test.kt line 38: Replace with colorResource:
+@@ -5,0 +6 @@
++import androidx.compose.ui.res.colorResource
+@@ -38 +39 @@
+-                    context.getColor(-1)
++                    colorResource(-1)
+Autofix for src/test/test.kt line 39: Replace with painterResource:
+@@ -5,0 +6 @@
++import androidx.compose.ui.res.painterResource
+@@ -39 +40 @@
+-                    context.getDrawable(-1)
++                    painterResource(-1)
+Autofix for src/test/test.kt line 39: Replace with ImageBitmap.imageResource:
+@@ -5,0 +6 @@
++import androidx.compose.ui.res.imageResource
+@@ -39 +40 @@
+-                    context.getDrawable(-1)
++                    ImageBitmap.imageResource(-1)
+Autofix for src/test/test.kt line 39: Replace with ImageVector.vectorResource:
+@@ -5,0 +6 @@
++import androidx.compose.ui.res.vectorResource
+@@ -39 +40 @@
+-                    context.getDrawable(-1)
++                    ImageVector.vectorResource(-1)
+                """
+            )
     }
 
     @Test
diff --git a/compose/ui/ui-test/build.gradle b/compose/ui/ui-test/build.gradle
index 1dca62e..e439682 100644
--- a/compose/ui/ui-test/build.gradle
+++ b/compose/ui/ui-test/build.gradle
@@ -125,7 +125,7 @@
             }
         }
 
-        androidUnitTest {
+        androidHostTest {
             dependsOn(commonTest)
             dependsOn(androidCommonTest)
             dependencies {
diff --git a/compose/ui/ui-test/src/androidUnitTest/kotlin/androidx/compose/ui/test/ApplyingContinuationInterceptorTest.kt b/compose/ui/ui-test/src/androidHostTest/kotlin/androidx/compose/ui/test/ApplyingContinuationInterceptorTest.kt
similarity index 100%
rename from compose/ui/ui-test/src/androidUnitTest/kotlin/androidx/compose/ui/test/ApplyingContinuationInterceptorTest.kt
rename to compose/ui/ui-test/src/androidHostTest/kotlin/androidx/compose/ui/test/ApplyingContinuationInterceptorTest.kt
diff --git a/compose/ui/ui-test/src/androidUnitTest/kotlin/androidx/compose/ui/test/BitmapCapturingRetryLogicTest.kt b/compose/ui/ui-test/src/androidHostTest/kotlin/androidx/compose/ui/test/BitmapCapturingRetryLogicTest.kt
similarity index 100%
rename from compose/ui/ui-test/src/androidUnitTest/kotlin/androidx/compose/ui/test/BitmapCapturingRetryLogicTest.kt
rename to compose/ui/ui-test/src/androidHostTest/kotlin/androidx/compose/ui/test/BitmapCapturingRetryLogicTest.kt
diff --git a/compose/ui/ui-test/src/androidUnitTest/kotlin/androidx/compose/ui/test/Constants.kt b/compose/ui/ui-test/src/androidHostTest/kotlin/androidx/compose/ui/test/Constants.kt
similarity index 100%
rename from compose/ui/ui-test/src/androidUnitTest/kotlin/androidx/compose/ui/test/Constants.kt
rename to compose/ui/ui-test/src/androidHostTest/kotlin/androidx/compose/ui/test/Constants.kt
diff --git a/compose/ui/ui-test/src/androidUnitTest/kotlin/androidx/compose/ui/test/InfiniteAnimationPolicyTest.kt b/compose/ui/ui-test/src/androidHostTest/kotlin/androidx/compose/ui/test/InfiniteAnimationPolicyTest.kt
similarity index 100%
rename from compose/ui/ui-test/src/androidUnitTest/kotlin/androidx/compose/ui/test/InfiniteAnimationPolicyTest.kt
rename to compose/ui/ui-test/src/androidHostTest/kotlin/androidx/compose/ui/test/InfiniteAnimationPolicyTest.kt
diff --git a/compose/ui/ui-test/src/androidUnitTest/kotlin/androidx/compose/ui/test/PrefetchNotHangingMainThreadTest.kt b/compose/ui/ui-test/src/androidHostTest/kotlin/androidx/compose/ui/test/PrefetchNotHangingMainThreadTest.kt
similarity index 100%
rename from compose/ui/ui-test/src/androidUnitTest/kotlin/androidx/compose/ui/test/PrefetchNotHangingMainThreadTest.kt
rename to compose/ui/ui-test/src/androidHostTest/kotlin/androidx/compose/ui/test/PrefetchNotHangingMainThreadTest.kt
diff --git a/compose/ui/ui-test/src/androidUnitTest/kotlin/androidx/compose/ui/test/RobolectricComposeTest.kt b/compose/ui/ui-test/src/androidHostTest/kotlin/androidx/compose/ui/test/RobolectricComposeTest.kt
similarity index 100%
rename from compose/ui/ui-test/src/androidUnitTest/kotlin/androidx/compose/ui/test/RobolectricComposeTest.kt
rename to compose/ui/ui-test/src/androidHostTest/kotlin/androidx/compose/ui/test/RobolectricComposeTest.kt
diff --git a/compose/ui/ui-test/src/androidUnitTest/kotlin/androidx/compose/ui/test/ViewVisibilityRobolectricTest.kt b/compose/ui/ui-test/src/androidHostTest/kotlin/androidx/compose/ui/test/ViewVisibilityRobolectricTest.kt
similarity index 100%
rename from compose/ui/ui-test/src/androidUnitTest/kotlin/androidx/compose/ui/test/ViewVisibilityRobolectricTest.kt
rename to compose/ui/ui-test/src/androidHostTest/kotlin/androidx/compose/ui/test/ViewVisibilityRobolectricTest.kt
diff --git a/compose/ui/ui-test/src/androidUnitTest/kotlin/androidx/compose/ui/test/inputdispatcher/AdvanceEventTimeTest.kt b/compose/ui/ui-test/src/androidHostTest/kotlin/androidx/compose/ui/test/inputdispatcher/AdvanceEventTimeTest.kt
similarity index 100%
rename from compose/ui/ui-test/src/androidUnitTest/kotlin/androidx/compose/ui/test/inputdispatcher/AdvanceEventTimeTest.kt
rename to compose/ui/ui-test/src/androidHostTest/kotlin/androidx/compose/ui/test/inputdispatcher/AdvanceEventTimeTest.kt
diff --git a/compose/ui/ui-test/src/androidUnitTest/kotlin/androidx/compose/ui/test/inputdispatcher/BatchingTest.kt b/compose/ui/ui-test/src/androidHostTest/kotlin/androidx/compose/ui/test/inputdispatcher/BatchingTest.kt
similarity index 100%
rename from compose/ui/ui-test/src/androidUnitTest/kotlin/androidx/compose/ui/test/inputdispatcher/BatchingTest.kt
rename to compose/ui/ui-test/src/androidHostTest/kotlin/androidx/compose/ui/test/inputdispatcher/BatchingTest.kt
diff --git a/compose/ui/ui-test/src/androidUnitTest/kotlin/androidx/compose/ui/test/inputdispatcher/InputDispatcherTest.kt b/compose/ui/ui-test/src/androidHostTest/kotlin/androidx/compose/ui/test/inputdispatcher/InputDispatcherTest.kt
similarity index 100%
rename from compose/ui/ui-test/src/androidUnitTest/kotlin/androidx/compose/ui/test/inputdispatcher/InputDispatcherTest.kt
rename to compose/ui/ui-test/src/androidHostTest/kotlin/androidx/compose/ui/test/inputdispatcher/InputDispatcherTest.kt
diff --git a/compose/ui/ui-test/src/androidUnitTest/kotlin/androidx/compose/ui/test/inputdispatcher/IsGestureInProgressTest.kt b/compose/ui/ui-test/src/androidHostTest/kotlin/androidx/compose/ui/test/inputdispatcher/IsGestureInProgressTest.kt
similarity index 100%
rename from compose/ui/ui-test/src/androidUnitTest/kotlin/androidx/compose/ui/test/inputdispatcher/IsGestureInProgressTest.kt
rename to compose/ui/ui-test/src/androidHostTest/kotlin/androidx/compose/ui/test/inputdispatcher/IsGestureInProgressTest.kt
diff --git a/compose/ui/ui-test/src/androidUnitTest/kotlin/androidx/compose/ui/test/inputdispatcher/KeyAndMouseEventsTest.kt b/compose/ui/ui-test/src/androidHostTest/kotlin/androidx/compose/ui/test/inputdispatcher/KeyAndMouseEventsTest.kt
similarity index 100%
rename from compose/ui/ui-test/src/androidUnitTest/kotlin/androidx/compose/ui/test/inputdispatcher/KeyAndMouseEventsTest.kt
rename to compose/ui/ui-test/src/androidHostTest/kotlin/androidx/compose/ui/test/inputdispatcher/KeyAndMouseEventsTest.kt
diff --git a/compose/ui/ui-test/src/androidUnitTest/kotlin/androidx/compose/ui/test/inputdispatcher/KeyEventsTest.kt b/compose/ui/ui-test/src/androidHostTest/kotlin/androidx/compose/ui/test/inputdispatcher/KeyEventsTest.kt
similarity index 100%
rename from compose/ui/ui-test/src/androidUnitTest/kotlin/androidx/compose/ui/test/inputdispatcher/KeyEventsTest.kt
rename to compose/ui/ui-test/src/androidHostTest/kotlin/androidx/compose/ui/test/inputdispatcher/KeyEventsTest.kt
diff --git a/compose/ui/ui-test/src/androidUnitTest/kotlin/androidx/compose/ui/test/inputdispatcher/MouseEventsTest.kt b/compose/ui/ui-test/src/androidHostTest/kotlin/androidx/compose/ui/test/inputdispatcher/MouseEventsTest.kt
similarity index 100%
rename from compose/ui/ui-test/src/androidUnitTest/kotlin/androidx/compose/ui/test/inputdispatcher/MouseEventsTest.kt
rename to compose/ui/ui-test/src/androidHostTest/kotlin/androidx/compose/ui/test/inputdispatcher/MouseEventsTest.kt
diff --git a/compose/ui/ui-test/src/androidUnitTest/kotlin/androidx/compose/ui/test/inputdispatcher/TouchEventsTest.kt b/compose/ui/ui-test/src/androidHostTest/kotlin/androidx/compose/ui/test/inputdispatcher/TouchEventsTest.kt
similarity index 100%
rename from compose/ui/ui-test/src/androidUnitTest/kotlin/androidx/compose/ui/test/inputdispatcher/TouchEventsTest.kt
rename to compose/ui/ui-test/src/androidHostTest/kotlin/androidx/compose/ui/test/inputdispatcher/TouchEventsTest.kt
diff --git a/compose/ui/ui-test/src/androidUnitTest/kotlin/androidx/compose/ui/test/util/IsMonotonicBetweenTest.kt b/compose/ui/ui-test/src/androidHostTest/kotlin/androidx/compose/ui/test/util/IsMonotonicBetweenTest.kt
similarity index 100%
rename from compose/ui/ui-test/src/androidUnitTest/kotlin/androidx/compose/ui/test/util/IsMonotonicBetweenTest.kt
rename to compose/ui/ui-test/src/androidHostTest/kotlin/androidx/compose/ui/test/util/IsMonotonicBetweenTest.kt
diff --git a/compose/ui/ui-test/src/androidUnitTest/kotlin/androidx/compose/ui/test/util/SplitsDurationEquallyIntoTest.kt b/compose/ui/ui-test/src/androidHostTest/kotlin/androidx/compose/ui/test/util/SplitsDurationEquallyIntoTest.kt
similarity index 100%
rename from compose/ui/ui-test/src/androidUnitTest/kotlin/androidx/compose/ui/test/util/SplitsDurationEquallyIntoTest.kt
rename to compose/ui/ui-test/src/androidHostTest/kotlin/androidx/compose/ui/test/util/SplitsDurationEquallyIntoTest.kt
diff --git a/compose/ui/ui-test/src/androidUnitTest/resources/mockito-extensions/org.mockito.plugins.MockMaker b/compose/ui/ui-test/src/androidHostTest/resources/mockito-extensions/org.mockito.plugins.MockMaker
similarity index 100%
rename from compose/ui/ui-test/src/androidUnitTest/resources/mockito-extensions/org.mockito.plugins.MockMaker
rename to compose/ui/ui-test/src/androidHostTest/resources/mockito-extensions/org.mockito.plugins.MockMaker
diff --git a/compose/ui/ui-text/build.gradle b/compose/ui/ui-text/build.gradle
index 65525bc..4d5ad89 100644
--- a/compose/ui/ui-text/build.gradle
+++ b/compose/ui/ui-text/build.gradle
@@ -121,7 +121,7 @@
             }
         }
 
-        androidUnitTest {
+        androidHostTest {
             dependsOn(commonTest)
             dependencies {
                 implementation(project(":internal-testutils-fonts"))
diff --git a/compose/ui/ui-text/src/androidUnitTest/kotlin/androidx/compose/ui/text/AnnotatedStringBuilderTest.kt b/compose/ui/ui-text/src/androidHostTest/kotlin/androidx/compose/ui/text/AnnotatedStringBuilderTest.kt
similarity index 100%
rename from compose/ui/ui-text/src/androidUnitTest/kotlin/androidx/compose/ui/text/AnnotatedStringBuilderTest.kt
rename to compose/ui/ui-text/src/androidHostTest/kotlin/androidx/compose/ui/text/AnnotatedStringBuilderTest.kt
diff --git a/compose/ui/ui-text/src/androidUnitTest/kotlin/androidx/compose/ui/text/AnnotatedStringTest.kt b/compose/ui/ui-text/src/androidHostTest/kotlin/androidx/compose/ui/text/AnnotatedStringTest.kt
similarity index 100%
rename from compose/ui/ui-text/src/androidUnitTest/kotlin/androidx/compose/ui/text/AnnotatedStringTest.kt
rename to compose/ui/ui-text/src/androidHostTest/kotlin/androidx/compose/ui/text/AnnotatedStringTest.kt
diff --git a/compose/ui/ui-text/src/androidUnitTest/kotlin/androidx/compose/ui/text/AnnotatedStringTransformTest.kt b/compose/ui/ui-text/src/androidHostTest/kotlin/androidx/compose/ui/text/AnnotatedStringTransformTest.kt
similarity index 100%
rename from compose/ui/ui-text/src/androidUnitTest/kotlin/androidx/compose/ui/text/AnnotatedStringTransformTest.kt
rename to compose/ui/ui-text/src/androidHostTest/kotlin/androidx/compose/ui/text/AnnotatedStringTransformTest.kt
diff --git a/compose/ui/ui-text/src/androidUnitTest/kotlin/androidx/compose/ui/text/LinkAnnotationTest.kt b/compose/ui/ui-text/src/androidHostTest/kotlin/androidx/compose/ui/text/LinkAnnotationTest.kt
similarity index 100%
rename from compose/ui/ui-text/src/androidUnitTest/kotlin/androidx/compose/ui/text/LinkAnnotationTest.kt
rename to compose/ui/ui-text/src/androidHostTest/kotlin/androidx/compose/ui/text/LinkAnnotationTest.kt
diff --git a/compose/ui/ui-text/src/androidUnitTest/kotlin/androidx/compose/ui/text/MultiParagraphTest.kt b/compose/ui/ui-text/src/androidHostTest/kotlin/androidx/compose/ui/text/MultiParagraphTest.kt
similarity index 100%
rename from compose/ui/ui-text/src/androidUnitTest/kotlin/androidx/compose/ui/text/MultiParagraphTest.kt
rename to compose/ui/ui-text/src/androidHostTest/kotlin/androidx/compose/ui/text/MultiParagraphTest.kt
diff --git a/compose/ui/ui-text/src/androidUnitTest/kotlin/androidx/compose/ui/text/ParagraphStyleTest.kt b/compose/ui/ui-text/src/androidHostTest/kotlin/androidx/compose/ui/text/ParagraphStyleTest.kt
similarity index 100%
rename from compose/ui/ui-text/src/androidUnitTest/kotlin/androidx/compose/ui/text/ParagraphStyleTest.kt
rename to compose/ui/ui-text/src/androidHostTest/kotlin/androidx/compose/ui/text/ParagraphStyleTest.kt
diff --git a/compose/ui/ui-text/src/androidUnitTest/kotlin/androidx/compose/ui/text/PlaceholderTest.kt b/compose/ui/ui-text/src/androidHostTest/kotlin/androidx/compose/ui/text/PlaceholderTest.kt
similarity index 100%
rename from compose/ui/ui-text/src/androidUnitTest/kotlin/androidx/compose/ui/text/PlaceholderTest.kt
rename to compose/ui/ui-text/src/androidHostTest/kotlin/androidx/compose/ui/text/PlaceholderTest.kt
diff --git a/compose/ui/ui-text/src/androidUnitTest/kotlin/androidx/compose/ui/text/SaversTest.kt b/compose/ui/ui-text/src/androidHostTest/kotlin/androidx/compose/ui/text/SaversTest.kt
similarity index 100%
rename from compose/ui/ui-text/src/androidUnitTest/kotlin/androidx/compose/ui/text/SaversTest.kt
rename to compose/ui/ui-text/src/androidHostTest/kotlin/androidx/compose/ui/text/SaversTest.kt
diff --git a/compose/ui/ui-text/src/androidUnitTest/kotlin/androidx/compose/ui/text/SpanStyleTest.kt b/compose/ui/ui-text/src/androidHostTest/kotlin/androidx/compose/ui/text/SpanStyleTest.kt
similarity index 100%
rename from compose/ui/ui-text/src/androidUnitTest/kotlin/androidx/compose/ui/text/SpanStyleTest.kt
rename to compose/ui/ui-text/src/androidHostTest/kotlin/androidx/compose/ui/text/SpanStyleTest.kt
diff --git a/compose/ui/ui-text/src/androidUnitTest/kotlin/androidx/compose/ui/text/TextInputServiceTest.kt b/compose/ui/ui-text/src/androidHostTest/kotlin/androidx/compose/ui/text/TextInputServiceTest.kt
similarity index 100%
rename from compose/ui/ui-text/src/androidUnitTest/kotlin/androidx/compose/ui/text/TextInputServiceTest.kt
rename to compose/ui/ui-text/src/androidHostTest/kotlin/androidx/compose/ui/text/TextInputServiceTest.kt
diff --git a/compose/ui/ui-text/src/androidUnitTest/kotlin/androidx/compose/ui/text/TextRangeTest.kt b/compose/ui/ui-text/src/androidHostTest/kotlin/androidx/compose/ui/text/TextRangeTest.kt
similarity index 100%
rename from compose/ui/ui-text/src/androidUnitTest/kotlin/androidx/compose/ui/text/TextRangeTest.kt
rename to compose/ui/ui-text/src/androidHostTest/kotlin/androidx/compose/ui/text/TextRangeTest.kt
diff --git a/compose/ui/ui-text/src/androidUnitTest/kotlin/androidx/compose/ui/text/TextSpanParagraphStyleTest.kt b/compose/ui/ui-text/src/androidHostTest/kotlin/androidx/compose/ui/text/TextSpanParagraphStyleTest.kt
similarity index 100%
rename from compose/ui/ui-text/src/androidUnitTest/kotlin/androidx/compose/ui/text/TextSpanParagraphStyleTest.kt
rename to compose/ui/ui-text/src/androidHostTest/kotlin/androidx/compose/ui/text/TextSpanParagraphStyleTest.kt
diff --git a/compose/ui/ui-text/src/androidUnitTest/kotlin/androidx/compose/ui/text/TextStyleLayoutAttributesTest.kt b/compose/ui/ui-text/src/androidHostTest/kotlin/androidx/compose/ui/text/TextStyleLayoutAttributesTest.kt
similarity index 100%
rename from compose/ui/ui-text/src/androidUnitTest/kotlin/androidx/compose/ui/text/TextStyleLayoutAttributesTest.kt
rename to compose/ui/ui-text/src/androidHostTest/kotlin/androidx/compose/ui/text/TextStyleLayoutAttributesTest.kt
diff --git a/compose/ui/ui-text/src/androidUnitTest/kotlin/androidx/compose/ui/text/TextStyleResolveDefaultsTest.kt b/compose/ui/ui-text/src/androidHostTest/kotlin/androidx/compose/ui/text/TextStyleResolveDefaultsTest.kt
similarity index 100%
rename from compose/ui/ui-text/src/androidUnitTest/kotlin/androidx/compose/ui/text/TextStyleResolveDefaultsTest.kt
rename to compose/ui/ui-text/src/androidHostTest/kotlin/androidx/compose/ui/text/TextStyleResolveDefaultsTest.kt
diff --git a/compose/ui/ui-text/src/androidUnitTest/kotlin/androidx/compose/ui/text/TextStyleTest.kt b/compose/ui/ui-text/src/androidHostTest/kotlin/androidx/compose/ui/text/TextStyleTest.kt
similarity index 100%
rename from compose/ui/ui-text/src/androidUnitTest/kotlin/androidx/compose/ui/text/TextStyleTest.kt
rename to compose/ui/ui-text/src/androidHostTest/kotlin/androidx/compose/ui/text/TextStyleTest.kt
diff --git a/compose/ui/ui-text/src/androidUnitTest/kotlin/androidx/compose/ui/text/font/AndroidFontResolverInterceptorTest.kt b/compose/ui/ui-text/src/androidHostTest/kotlin/androidx/compose/ui/text/font/AndroidFontResolverInterceptorTest.kt
similarity index 100%
rename from compose/ui/ui-text/src/androidUnitTest/kotlin/androidx/compose/ui/text/font/AndroidFontResolverInterceptorTest.kt
rename to compose/ui/ui-text/src/androidHostTest/kotlin/androidx/compose/ui/text/font/AndroidFontResolverInterceptorTest.kt
diff --git a/compose/ui/ui-text/src/androidUnitTest/kotlin/androidx/compose/ui/text/font/AsyncFontListLoaderTest.kt b/compose/ui/ui-text/src/androidHostTest/kotlin/androidx/compose/ui/text/font/AsyncFontListLoaderTest.kt
similarity index 100%
rename from compose/ui/ui-text/src/androidUnitTest/kotlin/androidx/compose/ui/text/font/AsyncFontListLoaderTest.kt
rename to compose/ui/ui-text/src/androidHostTest/kotlin/androidx/compose/ui/text/font/AsyncFontListLoaderTest.kt
diff --git a/compose/ui/ui-text/src/androidUnitTest/kotlin/androidx/compose/ui/text/font/FontFamilyTest.kt b/compose/ui/ui-text/src/androidHostTest/kotlin/androidx/compose/ui/text/font/FontFamilyTest.kt
similarity index 100%
rename from compose/ui/ui-text/src/androidUnitTest/kotlin/androidx/compose/ui/text/font/FontFamilyTest.kt
rename to compose/ui/ui-text/src/androidHostTest/kotlin/androidx/compose/ui/text/font/FontFamilyTest.kt
diff --git a/compose/ui/ui-text/src/androidUnitTest/kotlin/androidx/compose/ui/text/font/FontMatcherTest.kt b/compose/ui/ui-text/src/androidHostTest/kotlin/androidx/compose/ui/text/font/FontMatcherTest.kt
similarity index 100%
rename from compose/ui/ui-text/src/androidUnitTest/kotlin/androidx/compose/ui/text/font/FontMatcherTest.kt
rename to compose/ui/ui-text/src/androidHostTest/kotlin/androidx/compose/ui/text/font/FontMatcherTest.kt
diff --git a/compose/ui/ui-text/src/androidUnitTest/kotlin/androidx/compose/ui/text/font/FontTest.kt b/compose/ui/ui-text/src/androidHostTest/kotlin/androidx/compose/ui/text/font/FontTest.kt
similarity index 100%
rename from compose/ui/ui-text/src/androidUnitTest/kotlin/androidx/compose/ui/text/font/FontTest.kt
rename to compose/ui/ui-text/src/androidHostTest/kotlin/androidx/compose/ui/text/font/FontTest.kt
diff --git a/compose/ui/ui-text/src/androidUnitTest/kotlin/androidx/compose/ui/text/font/FontTestData.kt b/compose/ui/ui-text/src/androidHostTest/kotlin/androidx/compose/ui/text/font/FontTestData.kt
similarity index 100%
rename from compose/ui/ui-text/src/androidUnitTest/kotlin/androidx/compose/ui/text/font/FontTestData.kt
rename to compose/ui/ui-text/src/androidHostTest/kotlin/androidx/compose/ui/text/font/FontTestData.kt
diff --git a/compose/ui/ui-text/src/androidUnitTest/kotlin/androidx/compose/ui/text/font/FontVariationTest.kt b/compose/ui/ui-text/src/androidHostTest/kotlin/androidx/compose/ui/text/font/FontVariationTest.kt
similarity index 100%
rename from compose/ui/ui-text/src/androidUnitTest/kotlin/androidx/compose/ui/text/font/FontVariationTest.kt
rename to compose/ui/ui-text/src/androidHostTest/kotlin/androidx/compose/ui/text/font/FontVariationTest.kt
diff --git a/compose/ui/ui-text/src/androidUnitTest/kotlin/androidx/compose/ui/text/font/FontWeightTest.kt b/compose/ui/ui-text/src/androidHostTest/kotlin/androidx/compose/ui/text/font/FontWeightTest.kt
similarity index 100%
rename from compose/ui/ui-text/src/androidUnitTest/kotlin/androidx/compose/ui/text/font/FontWeightTest.kt
rename to compose/ui/ui-text/src/androidHostTest/kotlin/androidx/compose/ui/text/font/FontWeightTest.kt
diff --git a/compose/ui/ui-text/src/androidUnitTest/kotlin/androidx/compose/ui/text/font/LoadedFontFamilyTest.kt b/compose/ui/ui-text/src/androidHostTest/kotlin/androidx/compose/ui/text/font/LoadedFontFamilyTest.kt
similarity index 100%
rename from compose/ui/ui-text/src/androidUnitTest/kotlin/androidx/compose/ui/text/font/LoadedFontFamilyTest.kt
rename to compose/ui/ui-text/src/androidHostTest/kotlin/androidx/compose/ui/text/font/LoadedFontFamilyTest.kt
diff --git a/compose/ui/ui-text/src/androidUnitTest/kotlin/androidx/compose/ui/text/font/ResourceFontVariationSettingsTest.kt b/compose/ui/ui-text/src/androidHostTest/kotlin/androidx/compose/ui/text/font/ResourceFontVariationSettingsTest.kt
similarity index 100%
rename from compose/ui/ui-text/src/androidUnitTest/kotlin/androidx/compose/ui/text/font/ResourceFontVariationSettingsTest.kt
rename to compose/ui/ui-text/src/androidHostTest/kotlin/androidx/compose/ui/text/font/ResourceFontVariationSettingsTest.kt
diff --git a/compose/ui/ui-text/src/androidUnitTest/kotlin/androidx/compose/ui/text/input/CommitTextCommandTest.kt b/compose/ui/ui-text/src/androidHostTest/kotlin/androidx/compose/ui/text/input/CommitTextCommandTest.kt
similarity index 100%
rename from compose/ui/ui-text/src/androidUnitTest/kotlin/androidx/compose/ui/text/input/CommitTextCommandTest.kt
rename to compose/ui/ui-text/src/androidHostTest/kotlin/androidx/compose/ui/text/input/CommitTextCommandTest.kt
diff --git a/compose/ui/ui-text/src/androidUnitTest/kotlin/androidx/compose/ui/text/input/DeleteSurroundingTextCommandTest.kt b/compose/ui/ui-text/src/androidHostTest/kotlin/androidx/compose/ui/text/input/DeleteSurroundingTextCommandTest.kt
similarity index 100%
rename from compose/ui/ui-text/src/androidUnitTest/kotlin/androidx/compose/ui/text/input/DeleteSurroundingTextCommandTest.kt
rename to compose/ui/ui-text/src/androidHostTest/kotlin/androidx/compose/ui/text/input/DeleteSurroundingTextCommandTest.kt
diff --git a/compose/ui/ui-text/src/androidUnitTest/kotlin/androidx/compose/ui/text/input/DeleteSurroundingTextInCodePointsCommandTest.kt b/compose/ui/ui-text/src/androidHostTest/kotlin/androidx/compose/ui/text/input/DeleteSurroundingTextInCodePointsCommandTest.kt
similarity index 100%
rename from compose/ui/ui-text/src/androidUnitTest/kotlin/androidx/compose/ui/text/input/DeleteSurroundingTextInCodePointsCommandTest.kt
rename to compose/ui/ui-text/src/androidHostTest/kotlin/androidx/compose/ui/text/input/DeleteSurroundingTextInCodePointsCommandTest.kt
diff --git a/compose/ui/ui-text/src/androidUnitTest/kotlin/androidx/compose/ui/text/input/EditProcessorTest.kt b/compose/ui/ui-text/src/androidHostTest/kotlin/androidx/compose/ui/text/input/EditProcessorTest.kt
similarity index 100%
rename from compose/ui/ui-text/src/androidUnitTest/kotlin/androidx/compose/ui/text/input/EditProcessorTest.kt
rename to compose/ui/ui-text/src/androidHostTest/kotlin/androidx/compose/ui/text/input/EditProcessorTest.kt
diff --git a/compose/ui/ui-text/src/androidUnitTest/kotlin/androidx/compose/ui/text/input/EditingBufferDeleteRangeTest.kt b/compose/ui/ui-text/src/androidHostTest/kotlin/androidx/compose/ui/text/input/EditingBufferDeleteRangeTest.kt
similarity index 100%
rename from compose/ui/ui-text/src/androidUnitTest/kotlin/androidx/compose/ui/text/input/EditingBufferDeleteRangeTest.kt
rename to compose/ui/ui-text/src/androidHostTest/kotlin/androidx/compose/ui/text/input/EditingBufferDeleteRangeTest.kt
diff --git a/compose/ui/ui-text/src/androidUnitTest/kotlin/androidx/compose/ui/text/input/EditingBufferTest.kt b/compose/ui/ui-text/src/androidHostTest/kotlin/androidx/compose/ui/text/input/EditingBufferTest.kt
similarity index 100%
rename from compose/ui/ui-text/src/androidUnitTest/kotlin/androidx/compose/ui/text/input/EditingBufferTest.kt
rename to compose/ui/ui-text/src/androidHostTest/kotlin/androidx/compose/ui/text/input/EditingBufferTest.kt
diff --git a/compose/ui/ui-text/src/androidUnitTest/kotlin/androidx/compose/ui/text/input/FinishComposingTextCommandTest.kt b/compose/ui/ui-text/src/androidHostTest/kotlin/androidx/compose/ui/text/input/FinishComposingTextCommandTest.kt
similarity index 100%
rename from compose/ui/ui-text/src/androidUnitTest/kotlin/androidx/compose/ui/text/input/FinishComposingTextCommandTest.kt
rename to compose/ui/ui-text/src/androidHostTest/kotlin/androidx/compose/ui/text/input/FinishComposingTextCommandTest.kt
diff --git a/compose/ui/ui-text/src/androidUnitTest/kotlin/androidx/compose/ui/text/input/GapBufferTest.kt b/compose/ui/ui-text/src/androidHostTest/kotlin/androidx/compose/ui/text/input/GapBufferTest.kt
similarity index 100%
rename from compose/ui/ui-text/src/androidUnitTest/kotlin/androidx/compose/ui/text/input/GapBufferTest.kt
rename to compose/ui/ui-text/src/androidHostTest/kotlin/androidx/compose/ui/text/input/GapBufferTest.kt
diff --git a/compose/ui/ui-text/src/androidUnitTest/kotlin/androidx/compose/ui/text/input/PasswordVisualTransformationTest.kt b/compose/ui/ui-text/src/androidHostTest/kotlin/androidx/compose/ui/text/input/PasswordVisualTransformationTest.kt
similarity index 100%
rename from compose/ui/ui-text/src/androidUnitTest/kotlin/androidx/compose/ui/text/input/PasswordVisualTransformationTest.kt
rename to compose/ui/ui-text/src/androidHostTest/kotlin/androidx/compose/ui/text/input/PasswordVisualTransformationTest.kt
diff --git a/compose/ui/ui-text/src/androidUnitTest/kotlin/androidx/compose/ui/text/input/SetComposingRegionCommandTest.kt b/compose/ui/ui-text/src/androidHostTest/kotlin/androidx/compose/ui/text/input/SetComposingRegionCommandTest.kt
similarity index 100%
rename from compose/ui/ui-text/src/androidUnitTest/kotlin/androidx/compose/ui/text/input/SetComposingRegionCommandTest.kt
rename to compose/ui/ui-text/src/androidHostTest/kotlin/androidx/compose/ui/text/input/SetComposingRegionCommandTest.kt
diff --git a/compose/ui/ui-text/src/androidUnitTest/kotlin/androidx/compose/ui/text/input/SetComposingTextCommandTest.kt b/compose/ui/ui-text/src/androidHostTest/kotlin/androidx/compose/ui/text/input/SetComposingTextCommandTest.kt
similarity index 100%
rename from compose/ui/ui-text/src/androidUnitTest/kotlin/androidx/compose/ui/text/input/SetComposingTextCommandTest.kt
rename to compose/ui/ui-text/src/androidHostTest/kotlin/androidx/compose/ui/text/input/SetComposingTextCommandTest.kt
diff --git a/compose/ui/ui-text/src/androidUnitTest/kotlin/androidx/compose/ui/text/input/SetSelectionCommandTest.kt b/compose/ui/ui-text/src/androidHostTest/kotlin/androidx/compose/ui/text/input/SetSelectionCommandTest.kt
similarity index 100%
rename from compose/ui/ui-text/src/androidUnitTest/kotlin/androidx/compose/ui/text/input/SetSelectionCommandTest.kt
rename to compose/ui/ui-text/src/androidHostTest/kotlin/androidx/compose/ui/text/input/SetSelectionCommandTest.kt
diff --git a/compose/ui/ui-text/src/androidUnitTest/kotlin/androidx/compose/ui/text/input/TextFieldValueTest.kt b/compose/ui/ui-text/src/androidHostTest/kotlin/androidx/compose/ui/text/input/TextFieldValueTest.kt
similarity index 100%
rename from compose/ui/ui-text/src/androidUnitTest/kotlin/androidx/compose/ui/text/input/TextFieldValueTest.kt
rename to compose/ui/ui-text/src/androidHostTest/kotlin/androidx/compose/ui/text/input/TextFieldValueTest.kt
diff --git a/compose/ui/ui-text/src/androidUnitTest/kotlin/androidx/compose/ui/text/matchers/EditBufferSubject.kt b/compose/ui/ui-text/src/androidHostTest/kotlin/androidx/compose/ui/text/matchers/EditBufferSubject.kt
similarity index 100%
rename from compose/ui/ui-text/src/androidUnitTest/kotlin/androidx/compose/ui/text/matchers/EditBufferSubject.kt
rename to compose/ui/ui-text/src/androidHostTest/kotlin/androidx/compose/ui/text/matchers/EditBufferSubject.kt
diff --git a/compose/ui/ui-text/src/androidUnitTest/kotlin/androidx/compose/ui/text/style/BaselineShiftTest.kt b/compose/ui/ui-text/src/androidHostTest/kotlin/androidx/compose/ui/text/style/BaselineShiftTest.kt
similarity index 100%
rename from compose/ui/ui-text/src/androidUnitTest/kotlin/androidx/compose/ui/text/style/BaselineShiftTest.kt
rename to compose/ui/ui-text/src/androidHostTest/kotlin/androidx/compose/ui/text/style/BaselineShiftTest.kt
diff --git a/compose/ui/ui-text/src/androidUnitTest/kotlin/androidx/compose/ui/text/style/HyphensTest.kt b/compose/ui/ui-text/src/androidHostTest/kotlin/androidx/compose/ui/text/style/HyphensTest.kt
similarity index 100%
rename from compose/ui/ui-text/src/androidUnitTest/kotlin/androidx/compose/ui/text/style/HyphensTest.kt
rename to compose/ui/ui-text/src/androidHostTest/kotlin/androidx/compose/ui/text/style/HyphensTest.kt
diff --git a/compose/ui/ui-text/src/androidUnitTest/kotlin/androidx/compose/ui/text/style/LineHeightStyleTest.kt b/compose/ui/ui-text/src/androidHostTest/kotlin/androidx/compose/ui/text/style/LineHeightStyleTest.kt
similarity index 100%
rename from compose/ui/ui-text/src/androidUnitTest/kotlin/androidx/compose/ui/text/style/LineHeightStyleTest.kt
rename to compose/ui/ui-text/src/androidHostTest/kotlin/androidx/compose/ui/text/style/LineHeightStyleTest.kt
diff --git a/compose/ui/ui-text/src/androidUnitTest/kotlin/androidx/compose/ui/text/style/TextDecorationTest.kt b/compose/ui/ui-text/src/androidHostTest/kotlin/androidx/compose/ui/text/style/TextDecorationTest.kt
similarity index 100%
rename from compose/ui/ui-text/src/androidUnitTest/kotlin/androidx/compose/ui/text/style/TextDecorationTest.kt
rename to compose/ui/ui-text/src/androidHostTest/kotlin/androidx/compose/ui/text/style/TextDecorationTest.kt
diff --git a/compose/ui/ui-text/src/androidUnitTest/kotlin/androidx/compose/ui/text/style/TextForegroundStyleTest.kt b/compose/ui/ui-text/src/androidHostTest/kotlin/androidx/compose/ui/text/style/TextForegroundStyleTest.kt
similarity index 100%
rename from compose/ui/ui-text/src/androidUnitTest/kotlin/androidx/compose/ui/text/style/TextForegroundStyleTest.kt
rename to compose/ui/ui-text/src/androidHostTest/kotlin/androidx/compose/ui/text/style/TextForegroundStyleTest.kt
diff --git a/compose/ui/ui-text/src/androidUnitTest/resources/mockito-extensions/org.mockito.plugins.MockMaker b/compose/ui/ui-text/src/androidHostTest/resources/mockito-extensions/org.mockito.plugins.MockMaker
similarity index 100%
rename from compose/ui/ui-text/src/androidUnitTest/resources/mockito-extensions/org.mockito.plugins.MockMaker
rename to compose/ui/ui-text/src/androidHostTest/resources/mockito-extensions/org.mockito.plugins.MockMaker
diff --git a/compose/ui/ui-tooling-data/build.gradle b/compose/ui/ui-tooling-data/build.gradle
index c09268c..5c8dc9b 100644
--- a/compose/ui/ui-tooling-data/build.gradle
+++ b/compose/ui/ui-tooling-data/build.gradle
@@ -93,7 +93,7 @@
             }
         }
 
-        androidUnitTest {
+        androidHostTest {
             dependsOn(commonTest)
             dependencies {
                 implementation(libs.truth)
diff --git a/compose/ui/ui-tooling-preview/build.gradle b/compose/ui/ui-tooling-preview/build.gradle
index 2dc8629..a8699d9 100644
--- a/compose/ui/ui-tooling-preview/build.gradle
+++ b/compose/ui/ui-tooling-preview/build.gradle
@@ -72,7 +72,7 @@
             }
         }
 
-        androidUnitTest {
+        androidHostTest {
             dependsOn(jvmTest)
             dependencies {
                 implementation(libs.junit)
diff --git a/compose/ui/ui-tooling-preview/src/androidUnitTest/kotlin/androidx/compose/ui/tooling/preview/AndroidUiModesTest.kt b/compose/ui/ui-tooling-preview/src/androidHostTest/kotlin/androidx/compose/ui/tooling/preview/AndroidUiModesTest.kt
similarity index 100%
rename from compose/ui/ui-tooling-preview/src/androidUnitTest/kotlin/androidx/compose/ui/tooling/preview/AndroidUiModesTest.kt
rename to compose/ui/ui-tooling-preview/src/androidHostTest/kotlin/androidx/compose/ui/tooling/preview/AndroidUiModesTest.kt
diff --git a/compose/ui/ui-tooling-preview/src/androidUnitTest/kotlin/androidx/compose/ui/tooling/preview/datasource/LoremIpsumTest.kt b/compose/ui/ui-tooling-preview/src/androidHostTest/kotlin/androidx/compose/ui/tooling/preview/datasource/LoremIpsumTest.kt
similarity index 100%
rename from compose/ui/ui-tooling-preview/src/androidUnitTest/kotlin/androidx/compose/ui/tooling/preview/datasource/LoremIpsumTest.kt
rename to compose/ui/ui-tooling-preview/src/androidHostTest/kotlin/androidx/compose/ui/tooling/preview/datasource/LoremIpsumTest.kt
diff --git a/compose/ui/ui-tooling/build.gradle b/compose/ui/ui-tooling/build.gradle
index 18be942..d151860 100644
--- a/compose/ui/ui-tooling/build.gradle
+++ b/compose/ui/ui-tooling/build.gradle
@@ -107,7 +107,7 @@
             }
         }
 
-        androidUnitTest {
+        androidHostTest {
             dependsOn(commonTest)
             dependencies {
             }
diff --git a/compose/ui/ui-unit/build.gradle b/compose/ui/ui-unit/build.gradle
index 93f5df6..1b64289 100644
--- a/compose/ui/ui-unit/build.gradle
+++ b/compose/ui/ui-unit/build.gradle
@@ -102,7 +102,7 @@
             }
         }
 
-        androidUnitTest {
+        androidHostTest {
             dependsOn(jvmTest)
             dependencies {
                 implementation(libs.truth)
diff --git a/compose/ui/ui-util/build.gradle b/compose/ui/ui-util/build.gradle
index 9801431..a672760 100644
--- a/compose/ui/ui-util/build.gradle
+++ b/compose/ui/ui-util/build.gradle
@@ -93,7 +93,7 @@
             }
         }
 
-        androidUnitTest {
+        androidHostTest {
             dependsOn(jvmTest)
             dependencies {
                 implementation(libs.truth)
diff --git a/compose/ui/ui/build.gradle b/compose/ui/ui/build.gradle
index 7c9ff20..0dcd844 100644
--- a/compose/ui/ui/build.gradle
+++ b/compose/ui/ui/build.gradle
@@ -192,7 +192,7 @@
             }
         }
 
-        androidUnitTest {
+        androidHostTest {
             dependencies {
                 implementation(libs.testRules)
                 implementation(libs.testRunner)
diff --git a/compose/ui/ui/lint-baseline.xml b/compose/ui/ui/lint-baseline.xml
index 098618f..349ee5f 100644
--- a/compose/ui/ui/lint-baseline.xml
+++ b/compose/ui/ui/lint-baseline.xml
@@ -169,7 +169,7 @@
         errorLine1="internal fun FakePointerInputModifierNode.toModifier(): Modifier {"
         errorLine2="                                          ~~~~~~~~~~">
         <location
-            file="src/androidUnitTest/kotlin/androidx/compose/ui/node/HitTestTouchBoundsExpansionTest.kt"/>
+            file="src/androidHostTest/kotlin/androidx/compose/ui/node/HitTestTouchBoundsExpansionTest.kt"/>
     </issue>
 
     <issue
@@ -178,7 +178,7 @@
         errorLine1="fun DelegatableNode.toModifier(): Modifier.Element {"
         errorLine2="                    ~~~~~~~~~~">
         <location
-            file="src/androidUnitTest/kotlin/androidx/compose/ui/node/LayoutNodeTest.kt"/>
+            file="src/androidHostTest/kotlin/androidx/compose/ui/node/LayoutNodeTest.kt"/>
     </issue>
 
     <issue
@@ -295,7 +295,7 @@
         errorLine1="fun DelegatableNode.toModifier(): Modifier.Element {"
         errorLine2="                    ~~~~~~~~~~">
         <location
-            file="src/androidUnitTest/kotlin/androidx/compose/ui/node/LayoutNodeTest.kt"/>
+            file="src/androidHostTest/kotlin/androidx/compose/ui/node/LayoutNodeTest.kt"/>
     </issue>
 
     <issue
diff --git a/compose/ui/ui/samples/src/main/java/androidx/compose/ui/samples/NestedScrollInteropSamples.kt b/compose/ui/ui/samples/src/main/java/androidx/compose/ui/samples/NestedScrollInteropSamples.kt
index 888ce2c..4f86c99 100644
--- a/compose/ui/ui/samples/src/main/java/androidx/compose/ui/samples/NestedScrollInteropSamples.kt
+++ b/compose/ui/ui/samples/src/main/java/androidx/compose/ui/samples/NestedScrollInteropSamples.kt
@@ -133,7 +133,7 @@
 
 private fun AndroidViewWithCompose(context: Context): View {
     return LayoutInflater.from(context)
-        .inflate(R.layout.three_fold_nested_scroll_interop, null)
+        .inflate(R.layout.ui_sample_three_fold_nested_scroll_interop, null)
         .apply {
             with(findViewById<ComposeView>(R.id.compose_view)) {
                 // Compose
diff --git a/compose/ui/ui/samples/src/main/res/layout/three_fold_nested_scroll_interop.xml b/compose/ui/ui/samples/src/main/res/layout/ui_sample_three_fold_nested_scroll_interop.xml
similarity index 100%
rename from compose/ui/ui/samples/src/main/res/layout/three_fold_nested_scroll_interop.xml
rename to compose/ui/ui/samples/src/main/res/layout/ui_sample_three_fold_nested_scroll_interop.xml
diff --git a/compose/ui/ui/src/androidUnitTest/kotlin/androidx/compose/ui/ComposedModifierTest.kt b/compose/ui/ui/src/androidHostTest/kotlin/androidx/compose/ui/ComposedModifierTest.kt
similarity index 100%
rename from compose/ui/ui/src/androidUnitTest/kotlin/androidx/compose/ui/ComposedModifierTest.kt
rename to compose/ui/ui/src/androidHostTest/kotlin/androidx/compose/ui/ComposedModifierTest.kt
diff --git a/compose/ui/ui/src/androidUnitTest/kotlin/androidx/compose/ui/ModifierTest.kt b/compose/ui/ui/src/androidHostTest/kotlin/androidx/compose/ui/ModifierTest.kt
similarity index 100%
rename from compose/ui/ui/src/androidUnitTest/kotlin/androidx/compose/ui/ModifierTest.kt
rename to compose/ui/ui/src/androidHostTest/kotlin/androidx/compose/ui/ModifierTest.kt
diff --git a/compose/ui/ui/src/androidUnitTest/kotlin/androidx/compose/ui/SessionMutexTest.kt b/compose/ui/ui/src/androidHostTest/kotlin/androidx/compose/ui/SessionMutexTest.kt
similarity index 100%
rename from compose/ui/ui/src/androidUnitTest/kotlin/androidx/compose/ui/SessionMutexTest.kt
rename to compose/ui/ui/src/androidHostTest/kotlin/androidx/compose/ui/SessionMutexTest.kt
diff --git a/compose/ui/ui/src/androidUnitTest/kotlin/androidx/compose/ui/TransformOriginTest.kt b/compose/ui/ui/src/androidHostTest/kotlin/androidx/compose/ui/TransformOriginTest.kt
similarity index 100%
rename from compose/ui/ui/src/androidUnitTest/kotlin/androidx/compose/ui/TransformOriginTest.kt
rename to compose/ui/ui/src/androidHostTest/kotlin/androidx/compose/ui/TransformOriginTest.kt
diff --git a/compose/ui/ui/src/androidUnitTest/kotlin/androidx/compose/ui/autofill/AndroidAutofillTypeTest.kt b/compose/ui/ui/src/androidHostTest/kotlin/androidx/compose/ui/autofill/AndroidAutofillTypeTest.kt
similarity index 100%
rename from compose/ui/ui/src/androidUnitTest/kotlin/androidx/compose/ui/autofill/AndroidAutofillTypeTest.kt
rename to compose/ui/ui/src/androidHostTest/kotlin/androidx/compose/ui/autofill/AndroidAutofillTypeTest.kt
diff --git a/compose/ui/ui/src/androidUnitTest/kotlin/androidx/compose/ui/autofill/AndroidContentDataTypeTest.kt b/compose/ui/ui/src/androidHostTest/kotlin/androidx/compose/ui/autofill/AndroidContentDataTypeTest.kt
similarity index 100%
rename from compose/ui/ui/src/androidUnitTest/kotlin/androidx/compose/ui/autofill/AndroidContentDataTypeTest.kt
rename to compose/ui/ui/src/androidHostTest/kotlin/androidx/compose/ui/autofill/AndroidContentDataTypeTest.kt
diff --git a/compose/ui/ui/src/androidUnitTest/kotlin/androidx/compose/ui/autofill/AndroidContentTypeTest.kt b/compose/ui/ui/src/androidHostTest/kotlin/androidx/compose/ui/autofill/AndroidContentTypeTest.kt
similarity index 100%
rename from compose/ui/ui/src/androidUnitTest/kotlin/androidx/compose/ui/autofill/AndroidContentTypeTest.kt
rename to compose/ui/ui/src/androidHostTest/kotlin/androidx/compose/ui/autofill/AndroidContentTypeTest.kt
diff --git a/compose/ui/ui/src/androidUnitTest/kotlin/androidx/compose/ui/autofill/AndroidPerformAutofillTest.kt b/compose/ui/ui/src/androidHostTest/kotlin/androidx/compose/ui/autofill/AndroidPerformAutofillTest.kt
similarity index 100%
rename from compose/ui/ui/src/androidUnitTest/kotlin/androidx/compose/ui/autofill/AndroidPerformAutofillTest.kt
rename to compose/ui/ui/src/androidHostTest/kotlin/androidx/compose/ui/autofill/AndroidPerformAutofillTest.kt
diff --git a/compose/ui/ui/src/androidUnitTest/kotlin/androidx/compose/ui/autofill/AndroidPopulateViewStructureTest.kt b/compose/ui/ui/src/androidHostTest/kotlin/androidx/compose/ui/autofill/AndroidPopulateViewStructureTest.kt
similarity index 100%
rename from compose/ui/ui/src/androidUnitTest/kotlin/androidx/compose/ui/autofill/AndroidPopulateViewStructureTest.kt
rename to compose/ui/ui/src/androidHostTest/kotlin/androidx/compose/ui/autofill/AndroidPopulateViewStructureTest.kt
diff --git a/compose/ui/ui/src/androidUnitTest/kotlin/androidx/compose/ui/autofill/AutofillNodeTest.kt b/compose/ui/ui/src/androidHostTest/kotlin/androidx/compose/ui/autofill/AutofillNodeTest.kt
similarity index 100%
rename from compose/ui/ui/src/androidUnitTest/kotlin/androidx/compose/ui/autofill/AutofillNodeTest.kt
rename to compose/ui/ui/src/androidHostTest/kotlin/androidx/compose/ui/autofill/AutofillNodeTest.kt
diff --git a/compose/ui/ui/src/androidUnitTest/kotlin/androidx/compose/ui/autofill/FakeViewStructure.kt b/compose/ui/ui/src/androidHostTest/kotlin/androidx/compose/ui/autofill/FakeViewStructure.kt
similarity index 100%
rename from compose/ui/ui/src/androidUnitTest/kotlin/androidx/compose/ui/autofill/FakeViewStructure.kt
rename to compose/ui/ui/src/androidHostTest/kotlin/androidx/compose/ui/autofill/FakeViewStructure.kt
diff --git a/compose/ui/ui/src/androidUnitTest/kotlin/androidx/compose/ui/focus/FocusChangedModifierTest.kt b/compose/ui/ui/src/androidHostTest/kotlin/androidx/compose/ui/focus/FocusChangedModifierTest.kt
similarity index 100%
rename from compose/ui/ui/src/androidUnitTest/kotlin/androidx/compose/ui/focus/FocusChangedModifierTest.kt
rename to compose/ui/ui/src/androidHostTest/kotlin/androidx/compose/ui/focus/FocusChangedModifierTest.kt
diff --git a/compose/ui/ui/src/androidUnitTest/kotlin/androidx/compose/ui/focus/FocusEventModifierTest.kt b/compose/ui/ui/src/androidHostTest/kotlin/androidx/compose/ui/focus/FocusEventModifierTest.kt
similarity index 100%
rename from compose/ui/ui/src/androidUnitTest/kotlin/androidx/compose/ui/focus/FocusEventModifierTest.kt
rename to compose/ui/ui/src/androidHostTest/kotlin/androidx/compose/ui/focus/FocusEventModifierTest.kt
diff --git a/compose/ui/ui/src/androidUnitTest/kotlin/androidx/compose/ui/focus/FocusRequesterModifierTest.kt b/compose/ui/ui/src/androidHostTest/kotlin/androidx/compose/ui/focus/FocusRequesterModifierTest.kt
similarity index 100%
rename from compose/ui/ui/src/androidUnitTest/kotlin/androidx/compose/ui/focus/FocusRequesterModifierTest.kt
rename to compose/ui/ui/src/androidHostTest/kotlin/androidx/compose/ui/focus/FocusRequesterModifierTest.kt
diff --git a/compose/ui/ui/src/androidUnitTest/kotlin/androidx/compose/ui/gesture/TestUtils.kt b/compose/ui/ui/src/androidHostTest/kotlin/androidx/compose/ui/gesture/TestUtils.kt
similarity index 100%
rename from compose/ui/ui/src/androidUnitTest/kotlin/androidx/compose/ui/gesture/TestUtils.kt
rename to compose/ui/ui/src/androidHostTest/kotlin/androidx/compose/ui/gesture/TestUtils.kt
diff --git a/compose/ui/ui/src/androidUnitTest/kotlin/androidx/compose/ui/gesture/scrollorientationlocking/PolyFitLeastSquaresTest.kt b/compose/ui/ui/src/androidHostTest/kotlin/androidx/compose/ui/gesture/scrollorientationlocking/PolyFitLeastSquaresTest.kt
similarity index 100%
rename from compose/ui/ui/src/androidUnitTest/kotlin/androidx/compose/ui/gesture/scrollorientationlocking/PolyFitLeastSquaresTest.kt
rename to compose/ui/ui/src/androidHostTest/kotlin/androidx/compose/ui/gesture/scrollorientationlocking/PolyFitLeastSquaresTest.kt
diff --git a/compose/ui/ui/src/androidUnitTest/kotlin/androidx/compose/ui/graphics/GraphicsLayerScopeTest.kt b/compose/ui/ui/src/androidHostTest/kotlin/androidx/compose/ui/graphics/GraphicsLayerScopeTest.kt
similarity index 100%
rename from compose/ui/ui/src/androidUnitTest/kotlin/androidx/compose/ui/graphics/GraphicsLayerScopeTest.kt
rename to compose/ui/ui/src/androidHostTest/kotlin/androidx/compose/ui/graphics/GraphicsLayerScopeTest.kt
diff --git a/compose/ui/ui/src/androidUnitTest/kotlin/androidx/compose/ui/graphics/vector/ImageVectorBuilderTest.kt b/compose/ui/ui/src/androidHostTest/kotlin/androidx/compose/ui/graphics/vector/ImageVectorBuilderTest.kt
similarity index 100%
rename from compose/ui/ui/src/androidUnitTest/kotlin/androidx/compose/ui/graphics/vector/ImageVectorBuilderTest.kt
rename to compose/ui/ui/src/androidHostTest/kotlin/androidx/compose/ui/graphics/vector/ImageVectorBuilderTest.kt
diff --git a/compose/ui/ui/src/androidUnitTest/kotlin/androidx/compose/ui/hapticfeedback/HapticFeedbackTest.kt b/compose/ui/ui/src/androidHostTest/kotlin/androidx/compose/ui/hapticfeedback/HapticFeedbackTest.kt
similarity index 100%
rename from compose/ui/ui/src/androidUnitTest/kotlin/androidx/compose/ui/hapticfeedback/HapticFeedbackTest.kt
rename to compose/ui/ui/src/androidHostTest/kotlin/androidx/compose/ui/hapticfeedback/HapticFeedbackTest.kt
diff --git a/compose/ui/ui/src/androidUnitTest/kotlin/androidx/compose/ui/input/IndirectTouchEventWithInputDeviceMockTest.kt b/compose/ui/ui/src/androidHostTest/kotlin/androidx/compose/ui/input/IndirectTouchEventWithInputDeviceMockTest.kt
similarity index 100%
rename from compose/ui/ui/src/androidUnitTest/kotlin/androidx/compose/ui/input/IndirectTouchEventWithInputDeviceMockTest.kt
rename to compose/ui/ui/src/androidHostTest/kotlin/androidx/compose/ui/input/IndirectTouchEventWithInputDeviceMockTest.kt
diff --git a/compose/ui/ui/src/androidUnitTest/kotlin/androidx/compose/ui/input/RecordingInputConnectionInactiveTest.kt b/compose/ui/ui/src/androidHostTest/kotlin/androidx/compose/ui/input/RecordingInputConnectionInactiveTest.kt
similarity index 100%
rename from compose/ui/ui/src/androidUnitTest/kotlin/androidx/compose/ui/input/RecordingInputConnectionInactiveTest.kt
rename to compose/ui/ui/src/androidHostTest/kotlin/androidx/compose/ui/input/RecordingInputConnectionInactiveTest.kt
diff --git a/compose/ui/ui/src/androidUnitTest/kotlin/androidx/compose/ui/input/RecordingInputConnectionUpdateTextFieldValueTest.kt b/compose/ui/ui/src/androidHostTest/kotlin/androidx/compose/ui/input/RecordingInputConnectionUpdateTextFieldValueTest.kt
similarity index 100%
rename from compose/ui/ui/src/androidUnitTest/kotlin/androidx/compose/ui/input/RecordingInputConnectionUpdateTextFieldValueTest.kt
rename to compose/ui/ui/src/androidHostTest/kotlin/androidx/compose/ui/input/RecordingInputConnectionUpdateTextFieldValueTest.kt
diff --git a/compose/ui/ui/src/androidUnitTest/kotlin/androidx/compose/ui/input/key/KeyInputModifierTest.kt b/compose/ui/ui/src/androidHostTest/kotlin/androidx/compose/ui/input/key/KeyInputModifierTest.kt
similarity index 100%
rename from compose/ui/ui/src/androidUnitTest/kotlin/androidx/compose/ui/input/key/KeyInputModifierTest.kt
rename to compose/ui/ui/src/androidHostTest/kotlin/androidx/compose/ui/input/key/KeyInputModifierTest.kt
diff --git a/compose/ui/ui/src/androidUnitTest/kotlin/androidx/compose/ui/input/pointer/IndirectPointerInputChangeTest.kt b/compose/ui/ui/src/androidHostTest/kotlin/androidx/compose/ui/input/pointer/IndirectPointerInputChangeTest.kt
similarity index 100%
rename from compose/ui/ui/src/androidUnitTest/kotlin/androidx/compose/ui/input/pointer/IndirectPointerInputChangeTest.kt
rename to compose/ui/ui/src/androidHostTest/kotlin/androidx/compose/ui/input/pointer/IndirectPointerInputChangeTest.kt
diff --git a/compose/ui/ui/src/androidUnitTest/kotlin/androidx/compose/ui/input/pointer/PointerInputTest.kt b/compose/ui/ui/src/androidHostTest/kotlin/androidx/compose/ui/input/pointer/PointerInputTest.kt
similarity index 100%
rename from compose/ui/ui/src/androidUnitTest/kotlin/androidx/compose/ui/input/pointer/PointerInputTest.kt
rename to compose/ui/ui/src/androidHostTest/kotlin/androidx/compose/ui/input/pointer/PointerInputTest.kt
diff --git a/compose/ui/ui/src/androidUnitTest/kotlin/androidx/compose/ui/input/pointer/util/VelocityTracker1DTest.kt b/compose/ui/ui/src/androidHostTest/kotlin/androidx/compose/ui/input/pointer/util/VelocityTracker1DTest.kt
similarity index 100%
rename from compose/ui/ui/src/androidUnitTest/kotlin/androidx/compose/ui/input/pointer/util/VelocityTracker1DTest.kt
rename to compose/ui/ui/src/androidHostTest/kotlin/androidx/compose/ui/input/pointer/util/VelocityTracker1DTest.kt
diff --git a/compose/ui/ui/src/androidUnitTest/kotlin/androidx/compose/ui/input/pointer/util/VelocityTrackerTest.kt b/compose/ui/ui/src/androidHostTest/kotlin/androidx/compose/ui/input/pointer/util/VelocityTrackerTest.kt
similarity index 100%
rename from compose/ui/ui/src/androidUnitTest/kotlin/androidx/compose/ui/input/pointer/util/VelocityTrackerTest.kt
rename to compose/ui/ui/src/androidHostTest/kotlin/androidx/compose/ui/input/pointer/util/VelocityTrackerTest.kt
diff --git a/compose/ui/ui/src/androidUnitTest/kotlin/androidx/compose/ui/layout/AlignmentCombineTest.kt b/compose/ui/ui/src/androidHostTest/kotlin/androidx/compose/ui/layout/AlignmentCombineTest.kt
similarity index 100%
rename from compose/ui/ui/src/androidUnitTest/kotlin/androidx/compose/ui/layout/AlignmentCombineTest.kt
rename to compose/ui/ui/src/androidHostTest/kotlin/androidx/compose/ui/layout/AlignmentCombineTest.kt
diff --git a/compose/ui/ui/src/androidUnitTest/kotlin/androidx/compose/ui/layout/AlignmentTest.kt b/compose/ui/ui/src/androidHostTest/kotlin/androidx/compose/ui/layout/AlignmentTest.kt
similarity index 100%
rename from compose/ui/ui/src/androidUnitTest/kotlin/androidx/compose/ui/layout/AlignmentTest.kt
rename to compose/ui/ui/src/androidHostTest/kotlin/androidx/compose/ui/layout/AlignmentTest.kt
diff --git a/compose/ui/ui/src/androidUnitTest/kotlin/androidx/compose/ui/layout/ConstraintsTest.kt b/compose/ui/ui/src/androidHostTest/kotlin/androidx/compose/ui/layout/ConstraintsTest.kt
similarity index 100%
rename from compose/ui/ui/src/androidUnitTest/kotlin/androidx/compose/ui/layout/ConstraintsTest.kt
rename to compose/ui/ui/src/androidHostTest/kotlin/androidx/compose/ui/layout/ConstraintsTest.kt
diff --git a/compose/ui/ui/src/androidUnitTest/kotlin/androidx/compose/ui/layout/ContentScaleTest.kt b/compose/ui/ui/src/androidHostTest/kotlin/androidx/compose/ui/layout/ContentScaleTest.kt
similarity index 100%
rename from compose/ui/ui/src/androidUnitTest/kotlin/androidx/compose/ui/layout/ContentScaleTest.kt
rename to compose/ui/ui/src/androidHostTest/kotlin/androidx/compose/ui/layout/ContentScaleTest.kt
diff --git a/compose/ui/ui/src/androidUnitTest/kotlin/androidx/compose/ui/layout/ScaleFactorTest.kt b/compose/ui/ui/src/androidHostTest/kotlin/androidx/compose/ui/layout/ScaleFactorTest.kt
similarity index 100%
rename from compose/ui/ui/src/androidUnitTest/kotlin/androidx/compose/ui/layout/ScaleFactorTest.kt
rename to compose/ui/ui/src/androidHostTest/kotlin/androidx/compose/ui/layout/ScaleFactorTest.kt
diff --git a/compose/ui/ui/src/androidUnitTest/kotlin/androidx/compose/ui/modifier/ModifierLocalMapTest.kt b/compose/ui/ui/src/androidHostTest/kotlin/androidx/compose/ui/modifier/ModifierLocalMapTest.kt
similarity index 100%
rename from compose/ui/ui/src/androidUnitTest/kotlin/androidx/compose/ui/modifier/ModifierLocalMapTest.kt
rename to compose/ui/ui/src/androidHostTest/kotlin/androidx/compose/ui/modifier/ModifierLocalMapTest.kt
diff --git a/compose/ui/ui/src/androidUnitTest/kotlin/androidx/compose/ui/node/DelegatingNodeTest.kt b/compose/ui/ui/src/androidHostTest/kotlin/androidx/compose/ui/node/DelegatingNodeTest.kt
similarity index 100%
rename from compose/ui/ui/src/androidUnitTest/kotlin/androidx/compose/ui/node/DelegatingNodeTest.kt
rename to compose/ui/ui/src/androidHostTest/kotlin/androidx/compose/ui/node/DelegatingNodeTest.kt
diff --git a/compose/ui/ui/src/androidUnitTest/kotlin/androidx/compose/ui/node/HitTestResultTest.kt b/compose/ui/ui/src/androidHostTest/kotlin/androidx/compose/ui/node/HitTestResultTest.kt
similarity index 100%
rename from compose/ui/ui/src/androidUnitTest/kotlin/androidx/compose/ui/node/HitTestResultTest.kt
rename to compose/ui/ui/src/androidHostTest/kotlin/androidx/compose/ui/node/HitTestResultTest.kt
diff --git a/compose/ui/ui/src/androidUnitTest/kotlin/androidx/compose/ui/node/HitTestTouchBoundsExpansionTest.kt b/compose/ui/ui/src/androidHostTest/kotlin/androidx/compose/ui/node/HitTestTouchBoundsExpansionTest.kt
similarity index 100%
rename from compose/ui/ui/src/androidUnitTest/kotlin/androidx/compose/ui/node/HitTestTouchBoundsExpansionTest.kt
rename to compose/ui/ui/src/androidHostTest/kotlin/androidx/compose/ui/node/HitTestTouchBoundsExpansionTest.kt
diff --git a/compose/ui/ui/src/androidUnitTest/kotlin/androidx/compose/ui/node/LayoutNodeTest.kt b/compose/ui/ui/src/androidHostTest/kotlin/androidx/compose/ui/node/LayoutNodeTest.kt
similarity index 100%
rename from compose/ui/ui/src/androidUnitTest/kotlin/androidx/compose/ui/node/LayoutNodeTest.kt
rename to compose/ui/ui/src/androidHostTest/kotlin/androidx/compose/ui/node/LayoutNodeTest.kt
diff --git a/compose/ui/ui/src/androidUnitTest/kotlin/androidx/compose/ui/node/ModifierLocalConsumerEntityTest.kt b/compose/ui/ui/src/androidHostTest/kotlin/androidx/compose/ui/node/ModifierLocalConsumerEntityTest.kt
similarity index 100%
rename from compose/ui/ui/src/androidUnitTest/kotlin/androidx/compose/ui/node/ModifierLocalConsumerEntityTest.kt
rename to compose/ui/ui/src/androidHostTest/kotlin/androidx/compose/ui/node/ModifierLocalConsumerEntityTest.kt
diff --git a/compose/ui/ui/src/androidUnitTest/kotlin/androidx/compose/ui/node/ModifierNodeElementTest.kt b/compose/ui/ui/src/androidHostTest/kotlin/androidx/compose/ui/node/ModifierNodeElementTest.kt
similarity index 100%
rename from compose/ui/ui/src/androidUnitTest/kotlin/androidx/compose/ui/node/ModifierNodeElementTest.kt
rename to compose/ui/ui/src/androidHostTest/kotlin/androidx/compose/ui/node/ModifierNodeElementTest.kt
diff --git a/compose/ui/ui/src/androidUnitTest/kotlin/androidx/compose/ui/node/TouchBoundsExpansionTest.kt b/compose/ui/ui/src/androidHostTest/kotlin/androidx/compose/ui/node/TouchBoundsExpansionTest.kt
similarity index 100%
rename from compose/ui/ui/src/androidUnitTest/kotlin/androidx/compose/ui/node/TouchBoundsExpansionTest.kt
rename to compose/ui/ui/src/androidHostTest/kotlin/androidx/compose/ui/node/TouchBoundsExpansionTest.kt
diff --git a/compose/ui/ui/src/androidUnitTest/kotlin/androidx/compose/ui/platform/ClipboardTest.kt b/compose/ui/ui/src/androidHostTest/kotlin/androidx/compose/ui/platform/ClipboardTest.kt
similarity index 100%
rename from compose/ui/ui/src/androidUnitTest/kotlin/androidx/compose/ui/platform/ClipboardTest.kt
rename to compose/ui/ui/src/androidHostTest/kotlin/androidx/compose/ui/platform/ClipboardTest.kt
diff --git a/compose/ui/ui/src/androidUnitTest/kotlin/androidx/compose/ui/platform/WindowInfoTest.kt b/compose/ui/ui/src/androidHostTest/kotlin/androidx/compose/ui/platform/WindowInfoTest.kt
similarity index 100%
rename from compose/ui/ui/src/androidUnitTest/kotlin/androidx/compose/ui/platform/WindowInfoTest.kt
rename to compose/ui/ui/src/androidHostTest/kotlin/androidx/compose/ui/platform/WindowInfoTest.kt
diff --git a/compose/ui/ui/src/androidUnitTest/kotlin/androidx/compose/ui/spatial/RectListTest.kt b/compose/ui/ui/src/androidHostTest/kotlin/androidx/compose/ui/spatial/RectListTest.kt
similarity index 100%
rename from compose/ui/ui/src/androidUnitTest/kotlin/androidx/compose/ui/spatial/RectListTest.kt
rename to compose/ui/ui/src/androidHostTest/kotlin/androidx/compose/ui/spatial/RectListTest.kt
diff --git a/compose/ui/ui/src/androidUnitTest/kotlin/androidx/compose/ui/spatial/SpatialTestData.kt b/compose/ui/ui/src/androidHostTest/kotlin/androidx/compose/ui/spatial/SpatialTestData.kt
similarity index 100%
rename from compose/ui/ui/src/androidUnitTest/kotlin/androidx/compose/ui/spatial/SpatialTestData.kt
rename to compose/ui/ui/src/androidHostTest/kotlin/androidx/compose/ui/spatial/SpatialTestData.kt
diff --git a/compose/ui/ui/src/androidUnitTest/kotlin/androidx/compose/ui/spatial/ThrottledCallbacksTest.kt b/compose/ui/ui/src/androidHostTest/kotlin/androidx/compose/ui/spatial/ThrottledCallbacksTest.kt
similarity index 100%
rename from compose/ui/ui/src/androidUnitTest/kotlin/androidx/compose/ui/spatial/ThrottledCallbacksTest.kt
rename to compose/ui/ui/src/androidHostTest/kotlin/androidx/compose/ui/spatial/ThrottledCallbacksTest.kt
diff --git a/compose/ui/ui/src/androidUnitTest/kotlin/androidx/compose/ui/text/TextActionModeCallbackTest.kt b/compose/ui/ui/src/androidHostTest/kotlin/androidx/compose/ui/text/TextActionModeCallbackTest.kt
similarity index 100%
rename from compose/ui/ui/src/androidUnitTest/kotlin/androidx/compose/ui/text/TextActionModeCallbackTest.kt
rename to compose/ui/ui/src/androidHostTest/kotlin/androidx/compose/ui/text/TextActionModeCallbackTest.kt
diff --git a/compose/ui/ui/src/androidUnitTest/kotlin/androidx/compose/ui/text/input/TextInputServiceAndroidCommandDebouncingTest.kt b/compose/ui/ui/src/androidHostTest/kotlin/androidx/compose/ui/text/input/TextInputServiceAndroidCommandDebouncingTest.kt
similarity index 100%
rename from compose/ui/ui/src/androidUnitTest/kotlin/androidx/compose/ui/text/input/TextInputServiceAndroidCommandDebouncingTest.kt
rename to compose/ui/ui/src/androidHostTest/kotlin/androidx/compose/ui/text/input/TextInputServiceAndroidCommandDebouncingTest.kt
diff --git a/compose/ui/ui/src/androidUnitTest/kotlin/androidx/compose/ui/window/PopupPositionProviderTest.kt b/compose/ui/ui/src/androidHostTest/kotlin/androidx/compose/ui/window/PopupPositionProviderTest.kt
similarity index 100%
rename from compose/ui/ui/src/androidUnitTest/kotlin/androidx/compose/ui/window/PopupPositionProviderTest.kt
rename to compose/ui/ui/src/androidHostTest/kotlin/androidx/compose/ui/window/PopupPositionProviderTest.kt
diff --git a/compose/ui/ui/src/androidUnitTest/resources/mockito-extensions/org.mockito.plugins.MockMaker b/compose/ui/ui/src/androidHostTest/resources/mockito-extensions/org.mockito.plugins.MockMaker
similarity index 100%
rename from compose/ui/ui/src/androidUnitTest/resources/mockito-extensions/org.mockito.plugins.MockMaker
rename to compose/ui/ui/src/androidHostTest/resources/mockito-extensions/org.mockito.plugins.MockMaker
diff --git a/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/input/pointer/RequestUnbufferedDispatchTest.kt b/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/input/pointer/RequestUnbufferedDispatchTest.kt
new file mode 100644
index 0000000..e0a4aa0
--- /dev/null
+++ b/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/input/pointer/RequestUnbufferedDispatchTest.kt
@@ -0,0 +1,327 @@
+/*
+ * Copyright 2025 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 androidx.compose.ui.input.pointer
+
+import android.app.Instrumentation
+import android.os.SystemClock
+import android.view.InputDevice
+import android.view.MotionEvent
+import androidx.compose.foundation.gestures.awaitEachGesture
+import androidx.compose.foundation.layout.Spacer
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.runtime.rememberCoroutineScope
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.geometry.Offset
+import androidx.compose.ui.platform.LocalDensity
+import androidx.compose.ui.platform.LocalView
+import androidx.compose.ui.platform.testTag
+import androidx.compose.ui.test.junit4.createComposeRule
+import androidx.compose.ui.test.onNodeWithTag
+import androidx.compose.ui.unit.Density
+import androidx.compose.ui.unit.center
+import androidx.compose.ui.unit.dp
+import androidx.compose.ui.unit.toOffset
+import androidx.compose.ui.util.lerp
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.MediumTest
+import androidx.test.platform.app.InstrumentationRegistry
+import kotlin.math.PI
+import kotlin.math.cos
+import kotlin.math.sin
+import kotlin.test.assertEquals
+import kotlin.test.assertTrue
+import kotlinx.coroutines.Job
+import kotlinx.coroutines.android.awaitFrame
+import kotlinx.coroutines.launch
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+
+/**
+ * This is a test validating that unbuffered dispatch will forward motion events without additional
+ * batching in the Compose input pipeline.
+ */
+@MediumTest
+@RunWith(AndroidJUnit4::class)
+class RequestUnbufferedDispatchTest {
+    @get:Rule val rule = createComposeRule()
+
+    @Test
+    fun checkMotionEventsAreBatchedWhenBuffered() {
+        lateinit var density: Density
+        var framesDuringMotionEventInjection = 0
+        val iterations = 1000
+        val frameIndexToPointerEvents = mutableMapOf<Int, MutableList<PointerEvent>>()
+        frameIndexToPointerEvents[framesDuringMotionEventInjection] = mutableListOf()
+        var frameCountingJob: Job? = null
+
+        rule.setContent {
+            density = LocalDensity.current
+            val coroutineScope = rememberCoroutineScope()
+
+            Spacer(
+                modifier =
+                    Modifier.fillMaxSize().testTag("PointerInput").pointerInput(Unit) {
+                        awaitPointerEventScope {
+                            while (true) {
+                                val pointerEvent = awaitPointerEvent()
+                                if (pointerEvent.type == PointerEventType.Press) {
+                                    frameCountingJob =
+                                        coroutineScope.launch {
+                                            while (true) {
+                                                awaitFrame()
+                                                framesDuringMotionEventInjection++
+                                                frameIndexToPointerEvents[
+                                                    framesDuringMotionEventInjection] =
+                                                    mutableListOf()
+                                            }
+                                        }
+                                } else if (pointerEvent.type == PointerEventType.Release) {
+                                    frameCountingJob?.cancel()
+                                } else {
+                                    frameIndexToPointerEvents
+                                        .getValue(framesDuringMotionEventInjection)
+                                        .add(pointerEvent)
+                                }
+                            }
+                        }
+                    }
+            )
+        }
+
+        rule.waitForIdle()
+
+        val pointerInputCenterCoordinates: Offset =
+            rule.onNodeWithTag("PointerInput").fetchSemanticsNode().let { node ->
+                node.positionOnScreen + node.size.center.toOffset()
+            }
+        val radius = with(density) { 16.dp.toPx() }
+
+        injectCircleTraceEvents(pointerInputCenterCoordinates, radius, iterations)
+
+        assertTrue(
+            frameIndexToPointerEvents.values.maxOf { it.size } == 1,
+            "Expected to see exactly one pointer event per frame",
+        )
+    }
+
+    @Test
+    fun checkAllMotionEventsAreReceivedWhenUnbuffered_withPointerInteropFilter() {
+        lateinit var density: Density
+        var framesDuringMotionEventInjection = 0
+        val iterations = 1000
+        val frameIndexToPointerEvents = mutableMapOf<Int, MutableList<PointerEvent>>()
+        frameIndexToPointerEvents[framesDuringMotionEventInjection] = mutableListOf()
+        var frameCountingJob: Job? = null
+
+        rule.setContent {
+            density = LocalDensity.current
+            val containingView = LocalView.current
+            val coroutineScope = rememberCoroutineScope()
+
+            Spacer(
+                modifier =
+                    Modifier.fillMaxSize()
+                        .testTag("PointerInput")
+                        .pointerInput(Unit) {
+                            awaitPointerEventScope {
+                                while (true) {
+                                    val pointerEvent = awaitPointerEvent()
+                                    if (pointerEvent.type == PointerEventType.Press) {
+                                        frameCountingJob =
+                                            coroutineScope.launch {
+                                                while (true) {
+                                                    awaitFrame()
+                                                    framesDuringMotionEventInjection++
+                                                    frameIndexToPointerEvents[
+                                                        framesDuringMotionEventInjection] =
+                                                        mutableListOf()
+                                                }
+                                            }
+                                    } else if (pointerEvent.type == PointerEventType.Release) {
+                                        frameCountingJob?.cancel()
+                                    } else {
+                                        frameIndexToPointerEvents
+                                            .getValue(framesDuringMotionEventInjection)
+                                            .add(pointerEvent)
+                                    }
+                                }
+                            }
+                        }
+                        .pointerInteropFilter {
+                            containingView.requestUnbufferedDispatch(it)
+                            false
+                        }
+            )
+        }
+
+        rule.waitForIdle()
+
+        val pointerInputCenterCoordinates: Offset =
+            rule.onNodeWithTag("PointerInput").fetchSemanticsNode().let { node ->
+                node.positionOnScreen + node.size.center.toOffset()
+            }
+        val radius = with(density) { 16.dp.toPx() }
+
+        injectCircleTraceEvents(pointerInputCenterCoordinates, radius, iterations)
+
+        assertTrue(
+            frameIndexToPointerEvents.values.maxOf { it.size } > 1,
+            "Expected to see more than one pointer event per frame at some point",
+        )
+        assertTrue(
+            frameIndexToPointerEvents.values.maxOf { it.size } <
+                (iterations * 4f / framesDuringMotionEventInjection),
+            "Expected to see no more than four times the fair share of pointer events in any given frame",
+        )
+        assertEquals(
+            iterations,
+            frameIndexToPointerEvents.values.sumOf { it.size },
+            "Expected to receive pointer events for the $iterations moves, " +
+                "but didn't see the correct amount.",
+        )
+    }
+
+    @Test
+    fun checkAllMotionEventsAreReceivedWhenUnbuffered_withPointerInputAndRawMotionEventAccess() {
+        lateinit var density: Density
+        var framesDuringMotionEventInjection = 0
+        val iterations = 1000
+        val frameIndexToPointerEvents = mutableMapOf<Int, MutableList<PointerEvent>>()
+        frameIndexToPointerEvents[framesDuringMotionEventInjection] = mutableListOf()
+        var frameCountingJob: Job? = null
+
+        rule.setContent {
+            density = LocalDensity.current
+            val containingView = LocalView.current
+            val coroutineScope = rememberCoroutineScope()
+
+            Spacer(
+                modifier =
+                    Modifier.fillMaxSize().testTag("PointerInput").pointerInput(Unit) {
+                        awaitEachGesture {
+                            var isFirstPointerEvent = true
+                            while (true) {
+                                val pointerEvent = awaitPointerEvent()
+
+                                if (isFirstPointerEvent) {
+                                    containingView.requestUnbufferedDispatch(
+                                        pointerEvent.motionEvent
+                                    )
+                                    isFirstPointerEvent = false
+                                }
+
+                                if (pointerEvent.type == PointerEventType.Press) {
+                                    frameCountingJob =
+                                        coroutineScope.launch {
+                                            while (true) {
+                                                awaitFrame()
+                                                framesDuringMotionEventInjection++
+                                                frameIndexToPointerEvents[
+                                                    framesDuringMotionEventInjection] =
+                                                    mutableListOf()
+                                            }
+                                        }
+                                } else if (pointerEvent.type == PointerEventType.Release) {
+                                    frameCountingJob?.cancel()
+                                } else {
+                                    frameIndexToPointerEvents
+                                        .getValue(framesDuringMotionEventInjection)
+                                        .add(pointerEvent)
+                                }
+                            }
+                        }
+                    }
+            )
+        }
+
+        rule.waitForIdle()
+
+        val pointerInputCenterCoordinates: Offset =
+            rule.onNodeWithTag("PointerInput").fetchSemanticsNode().let { node ->
+                node.positionOnScreen + node.size.center.toOffset()
+            }
+        val radius = with(density) { 16.dp.toPx() }
+
+        injectCircleTraceEvents(pointerInputCenterCoordinates, radius, iterations)
+
+        assertTrue(
+            frameIndexToPointerEvents.values.maxOf { it.size } > 1,
+            "Expected to see more than one pointer event per frame at some point",
+        )
+        assertTrue(
+            frameIndexToPointerEvents.values.maxOf { it.size } <
+                (iterations * 4f / framesDuringMotionEventInjection),
+            "Expected to see no more than four times the fair share of pointer events in any given frame",
+        )
+        assertEquals(
+            iterations,
+            frameIndexToPointerEvents.values.sumOf { it.size },
+            "Expected to receive pointer events for the $iterations moves, " +
+                "but didn't see the correct amount.",
+        )
+    }
+}
+
+/**
+ * Uses [Instrumentation] to inject a gesture that is a down, followed by [iterations] moves around
+ * in a circle, and then an up. All motion events are emitted as fast as possible so that buffering
+ * would apply in normal use.
+ */
+private fun injectCircleTraceEvents(center: Offset, radius: Float, iterations: Int) {
+    val downTime = SystemClock.uptimeMillis()
+
+    val instrumentation = InstrumentationRegistry.getInstrumentation()
+
+    instrumentation.sendPointerSync(
+        downTime,
+        MotionEvent.ACTION_DOWN,
+        getCoordinatesAroundCircle(center = center, radius = radius, angle = 0f),
+    )
+    repeat(iterations) { index ->
+        instrumentation.sendPointerSync(
+            downTime,
+            MotionEvent.ACTION_MOVE,
+            getCoordinatesAroundCircle(
+                center = center,
+                radius = radius,
+                angle = lerp(0f, 2f * PI.toFloat(), (index + 1).toFloat() / iterations),
+            ),
+        )
+    }
+    instrumentation.sendPointerSync(
+        downTime,
+        MotionEvent.ACTION_UP,
+        getCoordinatesAroundCircle(center = center, radius = radius, angle = 0f),
+    )
+}
+
+private fun getCoordinatesAroundCircle(center: Offset, radius: Float, angle: Float) =
+    center + Offset(cos(angle), sin(angle)) * radius
+
+private fun Instrumentation.sendPointerSync(
+    downTime: Long,
+    action: Int,
+    screenOffset: Offset,
+    eventTime: Long = SystemClock.uptimeMillis(),
+) {
+    MotionEvent.obtain(downTime, eventTime, action, screenOffset.x, screenOffset.y, 0).run {
+        source = InputDevice.SOURCE_STYLUS
+        sendPointerSync(this)
+        recycle()
+    }
+}
diff --git a/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/layout/OnGlobalRectChangedTest.kt b/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/layout/OnGlobalRectChangedTest.kt
index ab21021..988556b 100644
--- a/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/layout/OnGlobalRectChangedTest.kt
+++ b/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/layout/OnGlobalRectChangedTest.kt
@@ -1743,6 +1743,47 @@
     }
 
     @Test
+    fun testLayoutModifierPlacingWithScaledLayerLater() {
+        var actualPosition: IntOffset = IntOffset.Max
+        var actualPositionChild: IntOffset = IntOffset.Max
+        var needLayer by mutableStateOf(false)
+        rule.setContent {
+            CompositionLocalProvider(LocalDensity provides Density(1f)) {
+                Box {
+                    Box(
+                        Modifier.layout { measurable, constraints ->
+                                val placeable = measurable.measure(constraints)
+                                layout(constraints.maxWidth, constraints.maxHeight) {
+                                    if (needLayer) {
+                                        placeable.placeWithLayer(10, 10) {
+                                            scaleX = 2f
+                                            scaleY = 2f
+                                        }
+                                    } else {
+                                        placeable.place(10, 10)
+                                    }
+                                }
+                            }
+                            .onLayoutRectChanged(0, 0) { actualPosition = it.positionInRoot }
+                    ) {
+                        Box(
+                            Modifier.onLayoutRectChanged(0, 0) {
+                                    actualPositionChild = it.positionInRoot
+                                }
+                                .size(10.dp)
+                        )
+                    }
+                }
+            }
+        }
+
+        rule.runOnIdle { needLayer = true }
+
+        rule.runOnIdle { assertThat(actualPosition).isEqualTo(IntOffset(5, 5)) }
+        rule.runOnIdle { assertThat(actualPositionChild).isEqualTo(IntOffset(5, 5)) }
+    }
+
+    @Test
     fun removingLayoutModifierShouldInvalidateOffsetCacheForSubtree() {
         with(rule.density) {
             var actualPosition: IntOffset = IntOffset.Max
diff --git a/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/layout/PlacedChildTest.kt b/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/layout/PlacedChildTest.kt
index 3a80def..bf30028 100644
--- a/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/layout/PlacedChildTest.kt
+++ b/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/layout/PlacedChildTest.kt
@@ -23,6 +23,7 @@
 import androidx.compose.foundation.layout.height
 import androidx.compose.foundation.layout.offset
 import androidx.compose.foundation.layout.size
+import androidx.compose.runtime.CompositionLocalProvider
 import androidx.compose.runtime.getValue
 import androidx.compose.runtime.mutableIntStateOf
 import androidx.compose.runtime.mutableStateOf
@@ -34,6 +35,7 @@
 import androidx.compose.ui.geometry.Offset
 import androidx.compose.ui.graphics.Color
 import androidx.compose.ui.node.LayoutNode
+import androidx.compose.ui.platform.LocalDensity
 import androidx.compose.ui.platform.testTag
 import androidx.compose.ui.test.TestActivity
 import androidx.compose.ui.test.assertIsDisplayed
@@ -42,6 +44,7 @@
 import androidx.compose.ui.test.junit4.createAndroidComposeRule
 import androidx.compose.ui.test.onNodeWithTag
 import androidx.compose.ui.unit.Constraints
+import androidx.compose.ui.unit.Density
 import androidx.compose.ui.unit.IntSize
 import androidx.compose.ui.unit.dp
 import androidx.test.ext.junit.runners.AndroidJUnit4
@@ -635,6 +638,45 @@
 
         rule.runOnIdle { assertThat(actualPosition).isEqualTo(Offset(10f, 10f)) }
     }
+
+    @Test
+    fun testLayoutModifierPlacingWithScaledLayerLater() {
+        var actualPosition: Offset? = null
+        var actualPositionChild: Offset? = null
+        var needLayer by mutableStateOf(false)
+        rule.setContent {
+            CompositionLocalProvider(LocalDensity provides Density(1f)) {
+                Box {
+                    Box(
+                        Modifier.layout { measurable, constraints ->
+                                val placeable = measurable.measure(constraints)
+                                layout(constraints.maxWidth, constraints.maxHeight) {
+                                    if (needLayer) {
+                                        placeable.placeWithLayer(10, 10) {
+                                            scaleX = 2f
+                                            scaleY = 2f
+                                        }
+                                    } else {
+                                        placeable.place(10, 10)
+                                    }
+                                }
+                            }
+                            .onPlaced { actualPosition = it.positionInRoot() }
+                    ) {
+                        Box(
+                            Modifier.onPlaced { actualPositionChild = it.positionInRoot() }
+                                .size(10.dp)
+                        )
+                    }
+                }
+            }
+        }
+
+        rule.runOnIdle { needLayer = true }
+
+        rule.runOnIdle { assertThat(actualPosition).isEqualTo(Offset(5f, 5f)) }
+        rule.runOnIdle { assertThat(actualPositionChild).isEqualTo(Offset(5f, 5f)) }
+    }
 }
 
 private val UseChildSizeButNotPlace =
diff --git a/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/layout/PlacementLayoutCoordinatesTest.kt b/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/layout/PlacementLayoutCoordinatesTest.kt
index ef72244..31ee32f 100644
--- a/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/layout/PlacementLayoutCoordinatesTest.kt
+++ b/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/layout/PlacementLayoutCoordinatesTest.kt
@@ -28,6 +28,7 @@
 import androidx.compose.foundation.layout.size
 import androidx.compose.material.Text
 import androidx.compose.runtime.Composable
+import androidx.compose.runtime.CompositionLocalProvider
 import androidx.compose.runtime.getValue
 import androidx.compose.runtime.movableContentOf
 import androidx.compose.runtime.mutableStateListOf
@@ -40,8 +41,10 @@
 import androidx.compose.ui.geometry.Offset
 import androidx.compose.ui.graphics.graphicsLayer
 import androidx.compose.ui.platform.ComposeView
+import androidx.compose.ui.platform.LocalDensity
 import androidx.compose.ui.test.junit4.createAndroidComposeRule
 import androidx.compose.ui.unit.Constraints
+import androidx.compose.ui.unit.Density
 import androidx.compose.ui.unit.DpOffset
 import androidx.compose.ui.unit.IntOffset
 import androidx.compose.ui.unit.IntSize
@@ -1037,6 +1040,50 @@
 
         rule.runOnIdle { assertThat(actualCoordinates).isEqualTo(listOf(null, Offset(10f, 0f))) }
     }
+
+    @Test
+    fun testLayoutModifierPlacingWithScaledLayerLater() {
+        var actualPosition: Offset? = null
+        var actualPositionChild: Offset? = null
+        var needLayer by mutableStateOf(false)
+        rule.setContent {
+            CompositionLocalProvider(LocalDensity provides Density(1f)) {
+                Box {
+                    Box(
+                        Modifier.layout { measurable, constraints ->
+                                val placeable = measurable.measure(constraints)
+                                layout(constraints.maxWidth, constraints.maxHeight) {
+                                    if (needLayer) {
+                                        placeable.placeWithLayer(10, 10) {
+                                            scaleX = 2f
+                                            scaleY = 2f
+                                        }
+                                    } else {
+                                        placeable.place(10, 10)
+                                    }
+                                }
+                            }
+                            .layout { measurable, constraints ->
+                                val placeable = measurable.measure(constraints)
+                                layout(placeable.width, placeable.height) {
+                                    actualPosition = coordinates?.positionInRoot()
+                                    placeable.place(0, 0)
+                                }
+                            }
+                    ) {
+                        Layout { measurables, constraints ->
+                            layout(10, 10) { actualPositionChild = coordinates?.positionInRoot() }
+                        }
+                    }
+                }
+            }
+        }
+
+        rule.runOnIdle { needLayer = true }
+
+        rule.runOnIdle { assertThat(actualPosition).isEqualTo(Offset(5f, 5f)) }
+        rule.runOnIdle { assertThat(actualPositionChild).isEqualTo(Offset(5f, 5f)) }
+    }
 }
 
 private fun LayoutCoordinates?.use(): LayoutCoordinates? {
diff --git a/compose/ui/ui/src/androidMain/res/values-af/strings.xml b/compose/ui/ui/src/androidMain/res/values-af/strings.xml
index d86ab94..8ffa5ec 100644
--- a/compose/ui/ui/src/androidMain/res/values-af/strings.xml
+++ b/compose/ui/ui/src/androidMain/res/values-af/strings.xml
@@ -36,5 +36,6 @@
     <string name="range_start" msgid="7097486360902471446">"Begingrens"</string>
     <string name="range_end" msgid="5941395253238309765">"Eindgrens"</string>
     <string name="snackbar_pane_title" msgid="2792228137354697160">"Opletberig"</string>
-    <string name="androidx_compose_ui_autofill" msgid="9020470552698189270">"Outovul"</string>
+    <!-- no translation found for androidx_compose_ui_autofill (1150566100598813236) -->
+    <skip />
 </resources>
diff --git a/compose/ui/ui/src/androidMain/res/values-am/strings.xml b/compose/ui/ui/src/androidMain/res/values-am/strings.xml
index 41998e0..2a0f49e 100644
--- a/compose/ui/ui/src/androidMain/res/values-am/strings.xml
+++ b/compose/ui/ui/src/androidMain/res/values-am/strings.xml
@@ -36,5 +36,6 @@
     <string name="range_start" msgid="7097486360902471446">"የክልል መጀመሪያ"</string>
     <string name="range_end" msgid="5941395253238309765">"የክልል መጨረሻ"</string>
     <string name="snackbar_pane_title" msgid="2792228137354697160">"ማንቂያ"</string>
-    <string name="androidx_compose_ui_autofill" msgid="9020470552698189270">"ራስ-ሙላ"</string>
+    <!-- no translation found for androidx_compose_ui_autofill (1150566100598813236) -->
+    <skip />
 </resources>
diff --git a/compose/ui/ui/src/androidMain/res/values-ar/strings.xml b/compose/ui/ui/src/androidMain/res/values-ar/strings.xml
index ee60689..c8afd56 100644
--- a/compose/ui/ui/src/androidMain/res/values-ar/strings.xml
+++ b/compose/ui/ui/src/androidMain/res/values-ar/strings.xml
@@ -36,5 +36,6 @@
     <string name="range_start" msgid="7097486360902471446">"بداية النطاق"</string>
     <string name="range_end" msgid="5941395253238309765">"نهاية النطاق"</string>
     <string name="snackbar_pane_title" msgid="2792228137354697160">"تنبيه"</string>
-    <string name="androidx_compose_ui_autofill" msgid="9020470552698189270">"الملء التلقائي"</string>
+    <!-- no translation found for androidx_compose_ui_autofill (1150566100598813236) -->
+    <skip />
 </resources>
diff --git a/compose/ui/ui/src/androidMain/res/values-as/strings.xml b/compose/ui/ui/src/androidMain/res/values-as/strings.xml
index c223d82..2e76495 100644
--- a/compose/ui/ui/src/androidMain/res/values-as/strings.xml
+++ b/compose/ui/ui/src/androidMain/res/values-as/strings.xml
@@ -36,5 +36,6 @@
     <string name="range_start" msgid="7097486360902471446">"পৰিসৰৰ আৰম্ভণি"</string>
     <string name="range_end" msgid="5941395253238309765">"পৰিসৰৰ সমাপ্তি"</string>
     <string name="snackbar_pane_title" msgid="2792228137354697160">"সতৰ্কবাৰ্তা"</string>
-    <string name="androidx_compose_ui_autofill" msgid="9020470552698189270">"স্বয়ংক্রিয়ভাৱে পূৰ হোৱাৰ সুবিধা"</string>
+    <!-- no translation found for androidx_compose_ui_autofill (1150566100598813236) -->
+    <skip />
 </resources>
diff --git a/compose/ui/ui/src/androidMain/res/values-az/strings.xml b/compose/ui/ui/src/androidMain/res/values-az/strings.xml
index 608f269..ef8d215 100644
--- a/compose/ui/ui/src/androidMain/res/values-az/strings.xml
+++ b/compose/ui/ui/src/androidMain/res/values-az/strings.xml
@@ -36,5 +36,6 @@
     <string name="range_start" msgid="7097486360902471446">"Sıranın başlanğıcı"</string>
     <string name="range_end" msgid="5941395253238309765">"Sıranın sonu"</string>
     <string name="snackbar_pane_title" msgid="2792228137354697160">"Xəbərdarlıq"</string>
-    <string name="androidx_compose_ui_autofill" msgid="9020470552698189270">"Avto-doldurma"</string>
+    <!-- no translation found for androidx_compose_ui_autofill (1150566100598813236) -->
+    <skip />
 </resources>
diff --git a/compose/ui/ui/src/androidMain/res/values-b+sr+Latn/strings.xml b/compose/ui/ui/src/androidMain/res/values-b+sr+Latn/strings.xml
index 5c4fdd4..b65e8ac 100644
--- a/compose/ui/ui/src/androidMain/res/values-b+sr+Latn/strings.xml
+++ b/compose/ui/ui/src/androidMain/res/values-b+sr+Latn/strings.xml
@@ -36,5 +36,6 @@
     <string name="range_start" msgid="7097486360902471446">"Početak opsega"</string>
     <string name="range_end" msgid="5941395253238309765">"Kraj opsega"</string>
     <string name="snackbar_pane_title" msgid="2792228137354697160">"Obaveštenje"</string>
-    <string name="androidx_compose_ui_autofill" msgid="9020470552698189270">"Automatsko popunjavanje"</string>
+    <!-- no translation found for androidx_compose_ui_autofill (1150566100598813236) -->
+    <skip />
 </resources>
diff --git a/compose/ui/ui/src/androidMain/res/values-be/strings.xml b/compose/ui/ui/src/androidMain/res/values-be/strings.xml
index 1561aa5..7eb6da9 100644
--- a/compose/ui/ui/src/androidMain/res/values-be/strings.xml
+++ b/compose/ui/ui/src/androidMain/res/values-be/strings.xml
@@ -36,5 +36,6 @@
     <string name="range_start" msgid="7097486360902471446">"Пачатак пераліку"</string>
     <string name="range_end" msgid="5941395253238309765">"Канец пераліку"</string>
     <string name="snackbar_pane_title" msgid="2792228137354697160">"Абвестка"</string>
-    <string name="androidx_compose_ui_autofill" msgid="9020470552698189270">"Аўтазапаўненне"</string>
+    <!-- no translation found for androidx_compose_ui_autofill (1150566100598813236) -->
+    <skip />
 </resources>
diff --git a/compose/ui/ui/src/androidMain/res/values-bg/strings.xml b/compose/ui/ui/src/androidMain/res/values-bg/strings.xml
index 19e3372..75587c5 100644
--- a/compose/ui/ui/src/androidMain/res/values-bg/strings.xml
+++ b/compose/ui/ui/src/androidMain/res/values-bg/strings.xml
@@ -36,5 +36,6 @@
     <string name="range_start" msgid="7097486360902471446">"Начало на обхвата"</string>
     <string name="range_end" msgid="5941395253238309765">"Край на обхвата"</string>
     <string name="snackbar_pane_title" msgid="2792228137354697160">"Сигнал"</string>
-    <string name="androidx_compose_ui_autofill" msgid="9020470552698189270">"Автоматично попълване"</string>
+    <!-- no translation found for androidx_compose_ui_autofill (1150566100598813236) -->
+    <skip />
 </resources>
diff --git a/compose/ui/ui/src/androidMain/res/values-bn/strings.xml b/compose/ui/ui/src/androidMain/res/values-bn/strings.xml
index 3f449d9..6fc37a0 100644
--- a/compose/ui/ui/src/androidMain/res/values-bn/strings.xml
+++ b/compose/ui/ui/src/androidMain/res/values-bn/strings.xml
@@ -36,5 +36,6 @@
     <string name="range_start" msgid="7097486360902471446">"রেঞ্জ শুরু"</string>
     <string name="range_end" msgid="5941395253238309765">"রেঞ্জ শেষ"</string>
     <string name="snackbar_pane_title" msgid="2792228137354697160">"সতর্কতা"</string>
-    <string name="androidx_compose_ui_autofill" msgid="9020470552698189270">"অটোফিল"</string>
+    <!-- no translation found for androidx_compose_ui_autofill (1150566100598813236) -->
+    <skip />
 </resources>
diff --git a/compose/ui/ui/src/androidMain/res/values-bs/strings.xml b/compose/ui/ui/src/androidMain/res/values-bs/strings.xml
index 710ef809..8d1d657d 100644
--- a/compose/ui/ui/src/androidMain/res/values-bs/strings.xml
+++ b/compose/ui/ui/src/androidMain/res/values-bs/strings.xml
@@ -36,5 +36,6 @@
     <string name="range_start" msgid="7097486360902471446">"Početak raspona"</string>
     <string name="range_end" msgid="5941395253238309765">"Kraj raspona"</string>
     <string name="snackbar_pane_title" msgid="2792228137354697160">"Obavještenje"</string>
-    <string name="androidx_compose_ui_autofill" msgid="9020470552698189270">"Automatsko popunjavanje"</string>
+    <!-- no translation found for androidx_compose_ui_autofill (1150566100598813236) -->
+    <skip />
 </resources>
diff --git a/compose/ui/ui/src/androidMain/res/values-ca/strings.xml b/compose/ui/ui/src/androidMain/res/values-ca/strings.xml
index bf73cc5..f110d37 100644
--- a/compose/ui/ui/src/androidMain/res/values-ca/strings.xml
+++ b/compose/ui/ui/src/androidMain/res/values-ca/strings.xml
@@ -36,5 +36,6 @@
     <string name="range_start" msgid="7097486360902471446">"Inici de l\'interval"</string>
     <string name="range_end" msgid="5941395253238309765">"Fi de l\'interval"</string>
     <string name="snackbar_pane_title" msgid="2792228137354697160">"Alerta"</string>
-    <string name="androidx_compose_ui_autofill" msgid="9020470552698189270">"Emplena automàticament"</string>
+    <!-- no translation found for androidx_compose_ui_autofill (1150566100598813236) -->
+    <skip />
 </resources>
diff --git a/compose/ui/ui/src/androidMain/res/values-cs/strings.xml b/compose/ui/ui/src/androidMain/res/values-cs/strings.xml
index 5f8185c..50bf1b5 100644
--- a/compose/ui/ui/src/androidMain/res/values-cs/strings.xml
+++ b/compose/ui/ui/src/androidMain/res/values-cs/strings.xml
@@ -36,5 +36,6 @@
     <string name="range_start" msgid="7097486360902471446">"Začátek rozsahu"</string>
     <string name="range_end" msgid="5941395253238309765">"Konec rozsahu"</string>
     <string name="snackbar_pane_title" msgid="2792228137354697160">"Upozornění"</string>
-    <string name="androidx_compose_ui_autofill" msgid="9020470552698189270">"Automatické vyplňování"</string>
+    <!-- no translation found for androidx_compose_ui_autofill (1150566100598813236) -->
+    <skip />
 </resources>
diff --git a/compose/ui/ui/src/androidMain/res/values-da/strings.xml b/compose/ui/ui/src/androidMain/res/values-da/strings.xml
index c261f69..158e3f3 100644
--- a/compose/ui/ui/src/androidMain/res/values-da/strings.xml
+++ b/compose/ui/ui/src/androidMain/res/values-da/strings.xml
@@ -36,5 +36,6 @@
     <string name="range_start" msgid="7097486360902471446">"Startinterval"</string>
     <string name="range_end" msgid="5941395253238309765">"Slutinterval"</string>
     <string name="snackbar_pane_title" msgid="2792228137354697160">"Underretning"</string>
-    <string name="androidx_compose_ui_autofill" msgid="9020470552698189270">"Autofyld"</string>
+    <!-- no translation found for androidx_compose_ui_autofill (1150566100598813236) -->
+    <skip />
 </resources>
diff --git a/compose/ui/ui/src/androidMain/res/values-de/strings.xml b/compose/ui/ui/src/androidMain/res/values-de/strings.xml
index 06e312f..84f3cb5 100644
--- a/compose/ui/ui/src/androidMain/res/values-de/strings.xml
+++ b/compose/ui/ui/src/androidMain/res/values-de/strings.xml
@@ -36,5 +36,6 @@
     <string name="range_start" msgid="7097486360902471446">"Bereichsstart"</string>
     <string name="range_end" msgid="5941395253238309765">"Bereichsende"</string>
     <string name="snackbar_pane_title" msgid="2792228137354697160">"Warnmeldung"</string>
-    <string name="androidx_compose_ui_autofill" msgid="9020470552698189270">"Automatisch ausfüllen"</string>
+    <!-- no translation found for androidx_compose_ui_autofill (1150566100598813236) -->
+    <skip />
 </resources>
diff --git a/compose/ui/ui/src/androidMain/res/values-el/strings.xml b/compose/ui/ui/src/androidMain/res/values-el/strings.xml
index c4f2238..bff75c4 100644
--- a/compose/ui/ui/src/androidMain/res/values-el/strings.xml
+++ b/compose/ui/ui/src/androidMain/res/values-el/strings.xml
@@ -36,5 +36,6 @@
     <string name="range_start" msgid="7097486360902471446">"Αρχή εύρους"</string>
     <string name="range_end" msgid="5941395253238309765">"Τέλος εύρους"</string>
     <string name="snackbar_pane_title" msgid="2792228137354697160">"Ειδοποίηση"</string>
-    <string name="androidx_compose_ui_autofill" msgid="9020470552698189270">"Αυτόματη συμπλήρωση"</string>
+    <!-- no translation found for androidx_compose_ui_autofill (1150566100598813236) -->
+    <skip />
 </resources>
diff --git a/compose/ui/ui/src/androidMain/res/values-en-rAU/strings.xml b/compose/ui/ui/src/androidMain/res/values-en-rAU/strings.xml
index b115cc5..0331a5b 100644
--- a/compose/ui/ui/src/androidMain/res/values-en-rAU/strings.xml
+++ b/compose/ui/ui/src/androidMain/res/values-en-rAU/strings.xml
@@ -36,5 +36,6 @@
     <string name="range_start" msgid="7097486360902471446">"Range start"</string>
     <string name="range_end" msgid="5941395253238309765">"Range end"</string>
     <string name="snackbar_pane_title" msgid="2792228137354697160">"Alert"</string>
-    <string name="androidx_compose_ui_autofill" msgid="9020470552698189270">"Autofill"</string>
+    <!-- no translation found for androidx_compose_ui_autofill (1150566100598813236) -->
+    <skip />
 </resources>
diff --git a/compose/ui/ui/src/androidMain/res/values-en-rCA/strings.xml b/compose/ui/ui/src/androidMain/res/values-en-rCA/strings.xml
index 8ae5fa0..a5d430f 100644
--- a/compose/ui/ui/src/androidMain/res/values-en-rCA/strings.xml
+++ b/compose/ui/ui/src/androidMain/res/values-en-rCA/strings.xml
@@ -36,5 +36,6 @@
     <string name="range_start" msgid="7097486360902471446">"Range start"</string>
     <string name="range_end" msgid="5941395253238309765">"Range end"</string>
     <string name="snackbar_pane_title" msgid="2792228137354697160">"Alert"</string>
-    <string name="androidx_compose_ui_autofill" msgid="9020470552698189270">"Autofill"</string>
+    <!-- no translation found for androidx_compose_ui_autofill (1150566100598813236) -->
+    <skip />
 </resources>
diff --git a/compose/ui/ui/src/androidMain/res/values-en-rGB/strings.xml b/compose/ui/ui/src/androidMain/res/values-en-rGB/strings.xml
index b115cc5..0331a5b 100644
--- a/compose/ui/ui/src/androidMain/res/values-en-rGB/strings.xml
+++ b/compose/ui/ui/src/androidMain/res/values-en-rGB/strings.xml
@@ -36,5 +36,6 @@
     <string name="range_start" msgid="7097486360902471446">"Range start"</string>
     <string name="range_end" msgid="5941395253238309765">"Range end"</string>
     <string name="snackbar_pane_title" msgid="2792228137354697160">"Alert"</string>
-    <string name="androidx_compose_ui_autofill" msgid="9020470552698189270">"Autofill"</string>
+    <!-- no translation found for androidx_compose_ui_autofill (1150566100598813236) -->
+    <skip />
 </resources>
diff --git a/compose/ui/ui/src/androidMain/res/values-en-rIN/strings.xml b/compose/ui/ui/src/androidMain/res/values-en-rIN/strings.xml
index b115cc5..0331a5b 100644
--- a/compose/ui/ui/src/androidMain/res/values-en-rIN/strings.xml
+++ b/compose/ui/ui/src/androidMain/res/values-en-rIN/strings.xml
@@ -36,5 +36,6 @@
     <string name="range_start" msgid="7097486360902471446">"Range start"</string>
     <string name="range_end" msgid="5941395253238309765">"Range end"</string>
     <string name="snackbar_pane_title" msgid="2792228137354697160">"Alert"</string>
-    <string name="androidx_compose_ui_autofill" msgid="9020470552698189270">"Autofill"</string>
+    <!-- no translation found for androidx_compose_ui_autofill (1150566100598813236) -->
+    <skip />
 </resources>
diff --git a/compose/ui/ui/src/androidMain/res/values-es-rUS/strings.xml b/compose/ui/ui/src/androidMain/res/values-es-rUS/strings.xml
index c4c0c08..7dcfc5c 100644
--- a/compose/ui/ui/src/androidMain/res/values-es-rUS/strings.xml
+++ b/compose/ui/ui/src/androidMain/res/values-es-rUS/strings.xml
@@ -36,5 +36,6 @@
     <string name="range_start" msgid="7097486360902471446">"Inicio de intervalo"</string>
     <string name="range_end" msgid="5941395253238309765">"Final de intervalo"</string>
     <string name="snackbar_pane_title" msgid="2792228137354697160">"Alerta"</string>
-    <string name="androidx_compose_ui_autofill" msgid="9020470552698189270">"Autocompletar"</string>
+    <!-- no translation found for androidx_compose_ui_autofill (1150566100598813236) -->
+    <skip />
 </resources>
diff --git a/compose/ui/ui/src/androidMain/res/values-es/strings.xml b/compose/ui/ui/src/androidMain/res/values-es/strings.xml
index 88220e4..704dd0d 100644
--- a/compose/ui/ui/src/androidMain/res/values-es/strings.xml
+++ b/compose/ui/ui/src/androidMain/res/values-es/strings.xml
@@ -36,5 +36,6 @@
     <string name="range_start" msgid="7097486360902471446">"Inicio del intervalo"</string>
     <string name="range_end" msgid="5941395253238309765">"Fin del intervalo"</string>
     <string name="snackbar_pane_title" msgid="2792228137354697160">"Alerta"</string>
-    <string name="androidx_compose_ui_autofill" msgid="9020470552698189270">"Autocompletar"</string>
+    <!-- no translation found for androidx_compose_ui_autofill (1150566100598813236) -->
+    <skip />
 </resources>
diff --git a/compose/ui/ui/src/androidMain/res/values-et/strings.xml b/compose/ui/ui/src/androidMain/res/values-et/strings.xml
index 5320e44..3e4dd9e 100644
--- a/compose/ui/ui/src/androidMain/res/values-et/strings.xml
+++ b/compose/ui/ui/src/androidMain/res/values-et/strings.xml
@@ -36,5 +36,6 @@
     <string name="range_start" msgid="7097486360902471446">"Vahemiku algus"</string>
     <string name="range_end" msgid="5941395253238309765">"Vahemiku lõpp"</string>
     <string name="snackbar_pane_title" msgid="2792228137354697160">"Hoiatus"</string>
-    <string name="androidx_compose_ui_autofill" msgid="9020470552698189270">"Automaattäide"</string>
+    <!-- no translation found for androidx_compose_ui_autofill (1150566100598813236) -->
+    <skip />
 </resources>
diff --git a/compose/ui/ui/src/androidMain/res/values-eu/strings.xml b/compose/ui/ui/src/androidMain/res/values-eu/strings.xml
index 7e915b5..a1ad388 100644
--- a/compose/ui/ui/src/androidMain/res/values-eu/strings.xml
+++ b/compose/ui/ui/src/androidMain/res/values-eu/strings.xml
@@ -36,5 +36,6 @@
     <string name="range_start" msgid="7097486360902471446">"Barrutiaren hasiera"</string>
     <string name="range_end" msgid="5941395253238309765">"Barrutiaren amaiera"</string>
     <string name="snackbar_pane_title" msgid="2792228137354697160">"Alerta"</string>
-    <string name="androidx_compose_ui_autofill" msgid="9020470552698189270">"Betetze automatikoa"</string>
+    <!-- no translation found for androidx_compose_ui_autofill (1150566100598813236) -->
+    <skip />
 </resources>
diff --git a/compose/ui/ui/src/androidMain/res/values-fa/strings.xml b/compose/ui/ui/src/androidMain/res/values-fa/strings.xml
index 45fa816..4c23415 100644
--- a/compose/ui/ui/src/androidMain/res/values-fa/strings.xml
+++ b/compose/ui/ui/src/androidMain/res/values-fa/strings.xml
@@ -36,5 +36,6 @@
     <string name="range_start" msgid="7097486360902471446">"شروع محدوده"</string>
     <string name="range_end" msgid="5941395253238309765">"پایان محدوده"</string>
     <string name="snackbar_pane_title" msgid="2792228137354697160">"هشدار"</string>
-    <string name="androidx_compose_ui_autofill" msgid="9020470552698189270">"تکمیل خودکار"</string>
+    <!-- no translation found for androidx_compose_ui_autofill (1150566100598813236) -->
+    <skip />
 </resources>
diff --git a/compose/ui/ui/src/androidMain/res/values-fi/strings.xml b/compose/ui/ui/src/androidMain/res/values-fi/strings.xml
index 68d575a..1cbf935 100644
--- a/compose/ui/ui/src/androidMain/res/values-fi/strings.xml
+++ b/compose/ui/ui/src/androidMain/res/values-fi/strings.xml
@@ -36,5 +36,6 @@
     <string name="range_start" msgid="7097486360902471446">"Alueen alku"</string>
     <string name="range_end" msgid="5941395253238309765">"Alueen loppu"</string>
     <string name="snackbar_pane_title" msgid="2792228137354697160">"Ilmoitus"</string>
-    <string name="androidx_compose_ui_autofill" msgid="9020470552698189270">"Automaattinen täyttö"</string>
+    <!-- no translation found for androidx_compose_ui_autofill (1150566100598813236) -->
+    <skip />
 </resources>
diff --git a/compose/ui/ui/src/androidMain/res/values-fr-rCA/strings.xml b/compose/ui/ui/src/androidMain/res/values-fr-rCA/strings.xml
index 2839b08..df785ef 100644
--- a/compose/ui/ui/src/androidMain/res/values-fr-rCA/strings.xml
+++ b/compose/ui/ui/src/androidMain/res/values-fr-rCA/strings.xml
@@ -36,5 +36,6 @@
     <string name="range_start" msgid="7097486360902471446">"Début de plage"</string>
     <string name="range_end" msgid="5941395253238309765">"Fin de plage"</string>
     <string name="snackbar_pane_title" msgid="2792228137354697160">"Alerte"</string>
-    <string name="androidx_compose_ui_autofill" msgid="9020470552698189270">"Remplissage automatique"</string>
+    <!-- no translation found for androidx_compose_ui_autofill (1150566100598813236) -->
+    <skip />
 </resources>
diff --git a/compose/ui/ui/src/androidMain/res/values-fr/strings.xml b/compose/ui/ui/src/androidMain/res/values-fr/strings.xml
index 87ad38b..5c11dc2 100644
--- a/compose/ui/ui/src/androidMain/res/values-fr/strings.xml
+++ b/compose/ui/ui/src/androidMain/res/values-fr/strings.xml
@@ -36,5 +36,6 @@
     <string name="range_start" msgid="7097486360902471446">"Début de plage"</string>
     <string name="range_end" msgid="5941395253238309765">"Fin de plage"</string>
     <string name="snackbar_pane_title" msgid="2792228137354697160">"Alerte"</string>
-    <string name="androidx_compose_ui_autofill" msgid="9020470552698189270">"Saisie automatique"</string>
+    <!-- no translation found for androidx_compose_ui_autofill (1150566100598813236) -->
+    <skip />
 </resources>
diff --git a/compose/ui/ui/src/androidMain/res/values-gl/strings.xml b/compose/ui/ui/src/androidMain/res/values-gl/strings.xml
index 1a5e9fc..f599a14 100644
--- a/compose/ui/ui/src/androidMain/res/values-gl/strings.xml
+++ b/compose/ui/ui/src/androidMain/res/values-gl/strings.xml
@@ -36,5 +36,6 @@
     <string name="range_start" msgid="7097486360902471446">"Inicio do intervalo"</string>
     <string name="range_end" msgid="5941395253238309765">"Fin do intervalo"</string>
     <string name="snackbar_pane_title" msgid="2792228137354697160">"Alerta"</string>
-    <string name="androidx_compose_ui_autofill" msgid="9020470552698189270">"Autocompletar"</string>
+    <!-- no translation found for androidx_compose_ui_autofill (1150566100598813236) -->
+    <skip />
 </resources>
diff --git a/compose/ui/ui/src/androidMain/res/values-gu/strings.xml b/compose/ui/ui/src/androidMain/res/values-gu/strings.xml
index 011827b..2489a17 100644
--- a/compose/ui/ui/src/androidMain/res/values-gu/strings.xml
+++ b/compose/ui/ui/src/androidMain/res/values-gu/strings.xml
@@ -36,5 +36,6 @@
     <string name="range_start" msgid="7097486360902471446">"રેંજની શરૂઆત"</string>
     <string name="range_end" msgid="5941395253238309765">"રેંજની સમાપ્તિ"</string>
     <string name="snackbar_pane_title" msgid="2792228137354697160">"અલર્ટ"</string>
-    <string name="androidx_compose_ui_autofill" msgid="9020470552698189270">"ઑટોમૅટિક રીતે ભરવાની સુવિધા"</string>
+    <!-- no translation found for androidx_compose_ui_autofill (1150566100598813236) -->
+    <skip />
 </resources>
diff --git a/compose/ui/ui/src/androidMain/res/values-hi/strings.xml b/compose/ui/ui/src/androidMain/res/values-hi/strings.xml
index b14f57d..1cd42f8 100644
--- a/compose/ui/ui/src/androidMain/res/values-hi/strings.xml
+++ b/compose/ui/ui/src/androidMain/res/values-hi/strings.xml
@@ -36,5 +36,6 @@
     <string name="range_start" msgid="7097486360902471446">"रेंज की शुरुआत"</string>
     <string name="range_end" msgid="5941395253238309765">"रेंज की सीमा"</string>
     <string name="snackbar_pane_title" msgid="2792228137354697160">"चेतावनी"</string>
-    <string name="androidx_compose_ui_autofill" msgid="9020470552698189270">"ऑटोमैटिक तरीके से भरें"</string>
+    <!-- no translation found for androidx_compose_ui_autofill (1150566100598813236) -->
+    <skip />
 </resources>
diff --git a/compose/ui/ui/src/androidMain/res/values-hr/strings.xml b/compose/ui/ui/src/androidMain/res/values-hr/strings.xml
index b5a57af..6906d6f 100644
--- a/compose/ui/ui/src/androidMain/res/values-hr/strings.xml
+++ b/compose/ui/ui/src/androidMain/res/values-hr/strings.xml
@@ -36,5 +36,6 @@
     <string name="range_start" msgid="7097486360902471446">"Početak raspona"</string>
     <string name="range_end" msgid="5941395253238309765">"Kraj raspona"</string>
     <string name="snackbar_pane_title" msgid="2792228137354697160">"Upozorenje"</string>
-    <string name="androidx_compose_ui_autofill" msgid="9020470552698189270">"Automatsko popunjavanje"</string>
+    <!-- no translation found for androidx_compose_ui_autofill (1150566100598813236) -->
+    <skip />
 </resources>
diff --git a/compose/ui/ui/src/androidMain/res/values-hu/strings.xml b/compose/ui/ui/src/androidMain/res/values-hu/strings.xml
index 0c687e2..d3cd23c 100644
--- a/compose/ui/ui/src/androidMain/res/values-hu/strings.xml
+++ b/compose/ui/ui/src/androidMain/res/values-hu/strings.xml
@@ -36,5 +36,6 @@
     <string name="range_start" msgid="7097486360902471446">"Tartomány kezdete"</string>
     <string name="range_end" msgid="5941395253238309765">"Tartomány vége"</string>
     <string name="snackbar_pane_title" msgid="2792228137354697160">"Figyelmeztetés"</string>
-    <string name="androidx_compose_ui_autofill" msgid="9020470552698189270">"Automatikus kitöltés"</string>
+    <!-- no translation found for androidx_compose_ui_autofill (1150566100598813236) -->
+    <skip />
 </resources>
diff --git a/compose/ui/ui/src/androidMain/res/values-hy/strings.xml b/compose/ui/ui/src/androidMain/res/values-hy/strings.xml
index 7e4557b..31cd219 100644
--- a/compose/ui/ui/src/androidMain/res/values-hy/strings.xml
+++ b/compose/ui/ui/src/androidMain/res/values-hy/strings.xml
@@ -36,5 +36,6 @@
     <string name="range_start" msgid="7097486360902471446">"Ընդգրկույթի սկիզբ"</string>
     <string name="range_end" msgid="5941395253238309765">"Ընդգրկույթի վերջ"</string>
     <string name="snackbar_pane_title" msgid="2792228137354697160">"Ծանուցում"</string>
-    <string name="androidx_compose_ui_autofill" msgid="9020470552698189270">"Ինքնալրացում"</string>
+    <!-- no translation found for androidx_compose_ui_autofill (1150566100598813236) -->
+    <skip />
 </resources>
diff --git a/compose/ui/ui/src/androidMain/res/values-in/strings.xml b/compose/ui/ui/src/androidMain/res/values-in/strings.xml
index 6c8a534..83b4683 100644
--- a/compose/ui/ui/src/androidMain/res/values-in/strings.xml
+++ b/compose/ui/ui/src/androidMain/res/values-in/strings.xml
@@ -36,5 +36,6 @@
     <string name="range_start" msgid="7097486360902471446">"Rentang awal"</string>
     <string name="range_end" msgid="5941395253238309765">"Rentang akhir"</string>
     <string name="snackbar_pane_title" msgid="2792228137354697160">"Pemberitahuan"</string>
-    <string name="androidx_compose_ui_autofill" msgid="9020470552698189270">"Isi otomatis"</string>
+    <!-- no translation found for androidx_compose_ui_autofill (1150566100598813236) -->
+    <skip />
 </resources>
diff --git a/compose/ui/ui/src/androidMain/res/values-is/strings.xml b/compose/ui/ui/src/androidMain/res/values-is/strings.xml
index 0c1d090..d44d04f 100644
--- a/compose/ui/ui/src/androidMain/res/values-is/strings.xml
+++ b/compose/ui/ui/src/androidMain/res/values-is/strings.xml
@@ -36,5 +36,6 @@
     <string name="range_start" msgid="7097486360902471446">"Upphaf sviðs"</string>
     <string name="range_end" msgid="5941395253238309765">"Lok sviðs"</string>
     <string name="snackbar_pane_title" msgid="2792228137354697160">"Viðvörun"</string>
-    <string name="androidx_compose_ui_autofill" msgid="9020470552698189270">"Sjálfvirk útfylling"</string>
+    <!-- no translation found for androidx_compose_ui_autofill (1150566100598813236) -->
+    <skip />
 </resources>
diff --git a/compose/ui/ui/src/androidMain/res/values-it/strings.xml b/compose/ui/ui/src/androidMain/res/values-it/strings.xml
index 699f379..7d0e4e6 100644
--- a/compose/ui/ui/src/androidMain/res/values-it/strings.xml
+++ b/compose/ui/ui/src/androidMain/res/values-it/strings.xml
@@ -36,5 +36,6 @@
     <string name="range_start" msgid="7097486360902471446">"Inizio intervallo"</string>
     <string name="range_end" msgid="5941395253238309765">"Fine intervallo"</string>
     <string name="snackbar_pane_title" msgid="2792228137354697160">"Avviso"</string>
-    <string name="androidx_compose_ui_autofill" msgid="9020470552698189270">"Compilazione automatica"</string>
+    <!-- no translation found for androidx_compose_ui_autofill (1150566100598813236) -->
+    <skip />
 </resources>
diff --git a/compose/ui/ui/src/androidMain/res/values-iw/strings.xml b/compose/ui/ui/src/androidMain/res/values-iw/strings.xml
index eaac506..bb30159 100644
--- a/compose/ui/ui/src/androidMain/res/values-iw/strings.xml
+++ b/compose/ui/ui/src/androidMain/res/values-iw/strings.xml
@@ -36,5 +36,6 @@
     <string name="range_start" msgid="7097486360902471446">"תחילת הטווח"</string>
     <string name="range_end" msgid="5941395253238309765">"סוף הטווח"</string>
     <string name="snackbar_pane_title" msgid="2792228137354697160">"התראה"</string>
-    <string name="androidx_compose_ui_autofill" msgid="9020470552698189270">"מילוי אוטומטי"</string>
+    <!-- no translation found for androidx_compose_ui_autofill (1150566100598813236) -->
+    <skip />
 </resources>
diff --git a/compose/ui/ui/src/androidMain/res/values-ja/strings.xml b/compose/ui/ui/src/androidMain/res/values-ja/strings.xml
index 4f17a33..6118ba7 100644
--- a/compose/ui/ui/src/androidMain/res/values-ja/strings.xml
+++ b/compose/ui/ui/src/androidMain/res/values-ja/strings.xml
@@ -36,5 +36,6 @@
     <string name="range_start" msgid="7097486360902471446">"範囲の先頭"</string>
     <string name="range_end" msgid="5941395253238309765">"範囲の末尾"</string>
     <string name="snackbar_pane_title" msgid="2792228137354697160">"アラート"</string>
-    <string name="androidx_compose_ui_autofill" msgid="9020470552698189270">"自動入力"</string>
+    <!-- no translation found for androidx_compose_ui_autofill (1150566100598813236) -->
+    <skip />
 </resources>
diff --git a/compose/ui/ui/src/androidMain/res/values-ka/strings.xml b/compose/ui/ui/src/androidMain/res/values-ka/strings.xml
index 47ae694..7b54a70 100644
--- a/compose/ui/ui/src/androidMain/res/values-ka/strings.xml
+++ b/compose/ui/ui/src/androidMain/res/values-ka/strings.xml
@@ -36,5 +36,6 @@
     <string name="range_start" msgid="7097486360902471446">"დიაპაზონის დასაწყისი"</string>
     <string name="range_end" msgid="5941395253238309765">"დიაპაზონის დასასრული"</string>
     <string name="snackbar_pane_title" msgid="2792228137354697160">"გაფრთხილება"</string>
-    <string name="androidx_compose_ui_autofill" msgid="9020470552698189270">"ავტომატური შევსება"</string>
+    <!-- no translation found for androidx_compose_ui_autofill (1150566100598813236) -->
+    <skip />
 </resources>
diff --git a/compose/ui/ui/src/androidMain/res/values-kk/strings.xml b/compose/ui/ui/src/androidMain/res/values-kk/strings.xml
index 423dfa0..0aca46b3 100644
--- a/compose/ui/ui/src/androidMain/res/values-kk/strings.xml
+++ b/compose/ui/ui/src/androidMain/res/values-kk/strings.xml
@@ -36,5 +36,6 @@
     <string name="range_start" msgid="7097486360902471446">"Аралықтың басы"</string>
     <string name="range_end" msgid="5941395253238309765">"Аралықтың соңы"</string>
     <string name="snackbar_pane_title" msgid="2792228137354697160">"Ескерту"</string>
-    <string name="androidx_compose_ui_autofill" msgid="9020470552698189270">"Автотолтыру"</string>
+    <!-- no translation found for androidx_compose_ui_autofill (1150566100598813236) -->
+    <skip />
 </resources>
diff --git a/compose/ui/ui/src/androidMain/res/values-km/strings.xml b/compose/ui/ui/src/androidMain/res/values-km/strings.xml
index 3ad4955..ceb856f 100644
--- a/compose/ui/ui/src/androidMain/res/values-km/strings.xml
+++ b/compose/ui/ui/src/androidMain/res/values-km/strings.xml
@@ -36,5 +36,6 @@
     <string name="range_start" msgid="7097486360902471446">"ចំណុចចាប់ផ្ដើម"</string>
     <string name="range_end" msgid="5941395253238309765">"ចំណុចបញ្ចប់"</string>
     <string name="snackbar_pane_title" msgid="2792228137354697160">"ជូន​ដំណឹង"</string>
-    <string name="androidx_compose_ui_autofill" msgid="9020470552698189270">"បំពេញ​ស្វ័យ​ប្រវត្តិ"</string>
+    <!-- no translation found for androidx_compose_ui_autofill (1150566100598813236) -->
+    <skip />
 </resources>
diff --git a/compose/ui/ui/src/androidMain/res/values-kn/strings.xml b/compose/ui/ui/src/androidMain/res/values-kn/strings.xml
index b5d1f54..fe1f65d 100644
--- a/compose/ui/ui/src/androidMain/res/values-kn/strings.xml
+++ b/compose/ui/ui/src/androidMain/res/values-kn/strings.xml
@@ -36,5 +36,6 @@
     <string name="range_start" msgid="7097486360902471446">"ಶ್ರೇಣಿಯ ಪ್ರಾರಂಭ"</string>
     <string name="range_end" msgid="5941395253238309765">"ಶ್ರೇಣಿಯ ಅಂತ್ಯ"</string>
     <string name="snackbar_pane_title" msgid="2792228137354697160">"ಎಚ್ಚರಿಕೆ"</string>
-    <string name="androidx_compose_ui_autofill" msgid="9020470552698189270">"ಆಟೋಫಿಲ್"</string>
+    <!-- no translation found for androidx_compose_ui_autofill (1150566100598813236) -->
+    <skip />
 </resources>
diff --git a/compose/ui/ui/src/androidMain/res/values-ko/strings.xml b/compose/ui/ui/src/androidMain/res/values-ko/strings.xml
index 9828686..f673c17 100644
--- a/compose/ui/ui/src/androidMain/res/values-ko/strings.xml
+++ b/compose/ui/ui/src/androidMain/res/values-ko/strings.xml
@@ -36,5 +36,6 @@
     <string name="range_start" msgid="7097486360902471446">"범위 시작"</string>
     <string name="range_end" msgid="5941395253238309765">"범위 끝"</string>
     <string name="snackbar_pane_title" msgid="2792228137354697160">"주의"</string>
-    <string name="androidx_compose_ui_autofill" msgid="9020470552698189270">"자동 완성"</string>
+    <!-- no translation found for androidx_compose_ui_autofill (1150566100598813236) -->
+    <skip />
 </resources>
diff --git a/compose/ui/ui/src/androidMain/res/values-ky/strings.xml b/compose/ui/ui/src/androidMain/res/values-ky/strings.xml
index 9fab04c..78486af 100644
--- a/compose/ui/ui/src/androidMain/res/values-ky/strings.xml
+++ b/compose/ui/ui/src/androidMain/res/values-ky/strings.xml
@@ -36,5 +36,6 @@
     <string name="range_start" msgid="7097486360902471446">"Диапазондун башы"</string>
     <string name="range_end" msgid="5941395253238309765">"Диапазондун аягы"</string>
     <string name="snackbar_pane_title" msgid="2792228137354697160">"Эскертүү"</string>
-    <string name="androidx_compose_ui_autofill" msgid="9020470552698189270">"Автотолтуруу функиясы"</string>
+    <!-- no translation found for androidx_compose_ui_autofill (1150566100598813236) -->
+    <skip />
 </resources>
diff --git a/compose/ui/ui/src/androidMain/res/values-lo/strings.xml b/compose/ui/ui/src/androidMain/res/values-lo/strings.xml
index e404f81..69430ea 100644
--- a/compose/ui/ui/src/androidMain/res/values-lo/strings.xml
+++ b/compose/ui/ui/src/androidMain/res/values-lo/strings.xml
@@ -36,5 +36,6 @@
     <string name="range_start" msgid="7097486360902471446">"ເລີ່ມຕົ້ນໄລຍະ"</string>
     <string name="range_end" msgid="5941395253238309765">"ສິ້ນສຸດໄລຍະ"</string>
     <string name="snackbar_pane_title" msgid="2792228137354697160">"ແຈ້ງເຕືອນ"</string>
-    <string name="androidx_compose_ui_autofill" msgid="9020470552698189270">"ຕື່ມຂໍ້ມູນອັດຕະໂນມັດ"</string>
+    <!-- no translation found for androidx_compose_ui_autofill (1150566100598813236) -->
+    <skip />
 </resources>
diff --git a/compose/ui/ui/src/androidMain/res/values-lt/strings.xml b/compose/ui/ui/src/androidMain/res/values-lt/strings.xml
index 8c82fbc..1ddbfee 100644
--- a/compose/ui/ui/src/androidMain/res/values-lt/strings.xml
+++ b/compose/ui/ui/src/androidMain/res/values-lt/strings.xml
@@ -36,5 +36,6 @@
     <string name="range_start" msgid="7097486360902471446">"Diapazono pradžia"</string>
     <string name="range_end" msgid="5941395253238309765">"Diapazono pabaiga"</string>
     <string name="snackbar_pane_title" msgid="2792228137354697160">"Įspėjimas"</string>
-    <string name="androidx_compose_ui_autofill" msgid="9020470552698189270">"Automatinis pildymas"</string>
+    <!-- no translation found for androidx_compose_ui_autofill (1150566100598813236) -->
+    <skip />
 </resources>
diff --git a/compose/ui/ui/src/androidMain/res/values-lv/strings.xml b/compose/ui/ui/src/androidMain/res/values-lv/strings.xml
index 2b1cde0..a493c3f 100644
--- a/compose/ui/ui/src/androidMain/res/values-lv/strings.xml
+++ b/compose/ui/ui/src/androidMain/res/values-lv/strings.xml
@@ -36,5 +36,6 @@
     <string name="range_start" msgid="7097486360902471446">"Diapazona sākums"</string>
     <string name="range_end" msgid="5941395253238309765">"Diapazona beigas"</string>
     <string name="snackbar_pane_title" msgid="2792228137354697160">"Brīdinājums"</string>
-    <string name="androidx_compose_ui_autofill" msgid="9020470552698189270">"Automātiskā aizpilde"</string>
+    <!-- no translation found for androidx_compose_ui_autofill (1150566100598813236) -->
+    <skip />
 </resources>
diff --git a/compose/ui/ui/src/androidMain/res/values-mk/strings.xml b/compose/ui/ui/src/androidMain/res/values-mk/strings.xml
index f97f23e..ab88b3a 100644
--- a/compose/ui/ui/src/androidMain/res/values-mk/strings.xml
+++ b/compose/ui/ui/src/androidMain/res/values-mk/strings.xml
@@ -36,5 +36,6 @@
     <string name="range_start" msgid="7097486360902471446">"Почеток на опсегот"</string>
     <string name="range_end" msgid="5941395253238309765">"Крај на опсегот"</string>
     <string name="snackbar_pane_title" msgid="2792228137354697160">"Предупредување"</string>
-    <string name="androidx_compose_ui_autofill" msgid="9020470552698189270">"Автоматско пополнување"</string>
+    <!-- no translation found for androidx_compose_ui_autofill (1150566100598813236) -->
+    <skip />
 </resources>
diff --git a/compose/ui/ui/src/androidMain/res/values-ml/strings.xml b/compose/ui/ui/src/androidMain/res/values-ml/strings.xml
index 6672b54..7dd9488 100644
--- a/compose/ui/ui/src/androidMain/res/values-ml/strings.xml
+++ b/compose/ui/ui/src/androidMain/res/values-ml/strings.xml
@@ -36,5 +36,6 @@
     <string name="range_start" msgid="7097486360902471446">"ശ്രേണിയുടെ ആരംഭം"</string>
     <string name="range_end" msgid="5941395253238309765">"ശ്രേണിയുടെ അവസാനം"</string>
     <string name="snackbar_pane_title" msgid="2792228137354697160">"മുന്നറിയിപ്പ്"</string>
-    <string name="androidx_compose_ui_autofill" msgid="9020470552698189270">"സ്വയമേവ പൂരിപ്പിക്കൽ"</string>
+    <!-- no translation found for androidx_compose_ui_autofill (1150566100598813236) -->
+    <skip />
 </resources>
diff --git a/compose/ui/ui/src/androidMain/res/values-mn/strings.xml b/compose/ui/ui/src/androidMain/res/values-mn/strings.xml
index 58e44d1..7790279 100644
--- a/compose/ui/ui/src/androidMain/res/values-mn/strings.xml
+++ b/compose/ui/ui/src/androidMain/res/values-mn/strings.xml
@@ -36,5 +36,6 @@
     <string name="range_start" msgid="7097486360902471446">"Мужийн эхлэл"</string>
     <string name="range_end" msgid="5941395253238309765">"Мужийн төгсгөл"</string>
     <string name="snackbar_pane_title" msgid="2792228137354697160">"Сэрэмжлүүлэг"</string>
-    <string name="androidx_compose_ui_autofill" msgid="9020470552698189270">"Автоматаар бөглөх"</string>
+    <!-- no translation found for androidx_compose_ui_autofill (1150566100598813236) -->
+    <skip />
 </resources>
diff --git a/compose/ui/ui/src/androidMain/res/values-mr/strings.xml b/compose/ui/ui/src/androidMain/res/values-mr/strings.xml
index fffcbf4..4d4d479 100644
--- a/compose/ui/ui/src/androidMain/res/values-mr/strings.xml
+++ b/compose/ui/ui/src/androidMain/res/values-mr/strings.xml
@@ -36,5 +36,6 @@
     <string name="range_start" msgid="7097486360902471446">"रेंजची सुरुवात"</string>
     <string name="range_end" msgid="5941395253238309765">"रेंजचा शेवट"</string>
     <string name="snackbar_pane_title" msgid="2792228137354697160">"सूचना"</string>
-    <string name="androidx_compose_ui_autofill" msgid="9020470552698189270">"ऑटोफिल"</string>
+    <!-- no translation found for androidx_compose_ui_autofill (1150566100598813236) -->
+    <skip />
 </resources>
diff --git a/compose/ui/ui/src/androidMain/res/values-ms/strings.xml b/compose/ui/ui/src/androidMain/res/values-ms/strings.xml
index 499ee78..80c456d 100644
--- a/compose/ui/ui/src/androidMain/res/values-ms/strings.xml
+++ b/compose/ui/ui/src/androidMain/res/values-ms/strings.xml
@@ -36,5 +36,6 @@
     <string name="range_start" msgid="7097486360902471446">"Permulaan julat"</string>
     <string name="range_end" msgid="5941395253238309765">"Penghujung julat"</string>
     <string name="snackbar_pane_title" msgid="2792228137354697160">"Makluman"</string>
-    <string name="androidx_compose_ui_autofill" msgid="9020470552698189270">"Autolengkap"</string>
+    <!-- no translation found for androidx_compose_ui_autofill (1150566100598813236) -->
+    <skip />
 </resources>
diff --git a/compose/ui/ui/src/androidMain/res/values-my/strings.xml b/compose/ui/ui/src/androidMain/res/values-my/strings.xml
index 55112c2..dba62c1 100644
--- a/compose/ui/ui/src/androidMain/res/values-my/strings.xml
+++ b/compose/ui/ui/src/androidMain/res/values-my/strings.xml
@@ -36,5 +36,6 @@
     <string name="range_start" msgid="7097486360902471446">"အပိုင်းအခြား အစ"</string>
     <string name="range_end" msgid="5941395253238309765">"အပိုင်းအခြား အဆုံး"</string>
     <string name="snackbar_pane_title" msgid="2792228137354697160">"သတိပေးချက်"</string>
-    <string name="androidx_compose_ui_autofill" msgid="9020470552698189270">"အော်တိုဖြည့်"</string>
+    <!-- no translation found for androidx_compose_ui_autofill (1150566100598813236) -->
+    <skip />
 </resources>
diff --git a/compose/ui/ui/src/androidMain/res/values-nb/strings.xml b/compose/ui/ui/src/androidMain/res/values-nb/strings.xml
index 4cf0b28..7fa0144 100644
--- a/compose/ui/ui/src/androidMain/res/values-nb/strings.xml
+++ b/compose/ui/ui/src/androidMain/res/values-nb/strings.xml
@@ -36,5 +36,6 @@
     <string name="range_start" msgid="7097486360902471446">"Områdestart"</string>
     <string name="range_end" msgid="5941395253238309765">"Områdeslutt"</string>
     <string name="snackbar_pane_title" msgid="2792228137354697160">"Varsel"</string>
-    <string name="androidx_compose_ui_autofill" msgid="9020470552698189270">"Autofyll"</string>
+    <!-- no translation found for androidx_compose_ui_autofill (1150566100598813236) -->
+    <skip />
 </resources>
diff --git a/compose/ui/ui/src/androidMain/res/values-ne/strings.xml b/compose/ui/ui/src/androidMain/res/values-ne/strings.xml
index 94efce9..ea629b5 100644
--- a/compose/ui/ui/src/androidMain/res/values-ne/strings.xml
+++ b/compose/ui/ui/src/androidMain/res/values-ne/strings.xml
@@ -36,5 +36,6 @@
     <string name="range_start" msgid="7097486360902471446">"दायराको सुरुवात बिन्दु"</string>
     <string name="range_end" msgid="5941395253238309765">"दायराको अन्तिम बिन्दु"</string>
     <string name="snackbar_pane_title" msgid="2792228137354697160">"अलर्ट"</string>
-    <string name="androidx_compose_ui_autofill" msgid="9020470552698189270">"अटोफिल"</string>
+    <!-- no translation found for androidx_compose_ui_autofill (1150566100598813236) -->
+    <skip />
 </resources>
diff --git a/compose/ui/ui/src/androidMain/res/values-nl/strings.xml b/compose/ui/ui/src/androidMain/res/values-nl/strings.xml
index 3af1077..b33b3e1 100644
--- a/compose/ui/ui/src/androidMain/res/values-nl/strings.xml
+++ b/compose/ui/ui/src/androidMain/res/values-nl/strings.xml
@@ -36,5 +36,6 @@
     <string name="range_start" msgid="7097486360902471446">"Start bereik"</string>
     <string name="range_end" msgid="5941395253238309765">"Einde bereik"</string>
     <string name="snackbar_pane_title" msgid="2792228137354697160">"Melding"</string>
-    <string name="androidx_compose_ui_autofill" msgid="9020470552698189270">"Automatisch invullen"</string>
+    <!-- no translation found for androidx_compose_ui_autofill (1150566100598813236) -->
+    <skip />
 </resources>
diff --git a/compose/ui/ui/src/androidMain/res/values-or/strings.xml b/compose/ui/ui/src/androidMain/res/values-or/strings.xml
index 47a4b26..331bd5d 100644
--- a/compose/ui/ui/src/androidMain/res/values-or/strings.xml
+++ b/compose/ui/ui/src/androidMain/res/values-or/strings.xml
@@ -36,5 +36,6 @@
     <string name="range_start" msgid="7097486360902471446">"ରେଞ୍ଜ ଆରମ୍ଭ"</string>
     <string name="range_end" msgid="5941395253238309765">"ରେଞ୍ଜ ଶେଷ"</string>
     <string name="snackbar_pane_title" msgid="2792228137354697160">"ଆଲର୍ଟ"</string>
-    <string name="androidx_compose_ui_autofill" msgid="9020470552698189270">"ଅଟୋଫିଲ"</string>
+    <!-- no translation found for androidx_compose_ui_autofill (1150566100598813236) -->
+    <skip />
 </resources>
diff --git a/compose/ui/ui/src/androidMain/res/values-pa/strings.xml b/compose/ui/ui/src/androidMain/res/values-pa/strings.xml
index b80fccf..abc1fa0 100644
--- a/compose/ui/ui/src/androidMain/res/values-pa/strings.xml
+++ b/compose/ui/ui/src/androidMain/res/values-pa/strings.xml
@@ -36,5 +36,6 @@
     <string name="range_start" msgid="7097486360902471446">"ਰੇਂਜ ਸ਼ੁਰੂ"</string>
     <string name="range_end" msgid="5941395253238309765">"ਰੇਂਜ ਸਮਾਪਤ"</string>
     <string name="snackbar_pane_title" msgid="2792228137354697160">"ਅਲਰਟ"</string>
-    <string name="androidx_compose_ui_autofill" msgid="9020470552698189270">"ਆਟੋਫਿਲ"</string>
+    <!-- no translation found for androidx_compose_ui_autofill (1150566100598813236) -->
+    <skip />
 </resources>
diff --git a/compose/ui/ui/src/androidMain/res/values-pl/strings.xml b/compose/ui/ui/src/androidMain/res/values-pl/strings.xml
index 10ddec6..e85769c 100644
--- a/compose/ui/ui/src/androidMain/res/values-pl/strings.xml
+++ b/compose/ui/ui/src/androidMain/res/values-pl/strings.xml
@@ -36,5 +36,6 @@
     <string name="range_start" msgid="7097486360902471446">"Początek zakresu"</string>
     <string name="range_end" msgid="5941395253238309765">"Koniec zakresu"</string>
     <string name="snackbar_pane_title" msgid="2792228137354697160">"Alert"</string>
-    <string name="androidx_compose_ui_autofill" msgid="9020470552698189270">"Autouzupełnianie"</string>
+    <!-- no translation found for androidx_compose_ui_autofill (1150566100598813236) -->
+    <skip />
 </resources>
diff --git a/compose/ui/ui/src/androidMain/res/values-pt-rBR/strings.xml b/compose/ui/ui/src/androidMain/res/values-pt-rBR/strings.xml
index 0f991e23..34ee155 100644
--- a/compose/ui/ui/src/androidMain/res/values-pt-rBR/strings.xml
+++ b/compose/ui/ui/src/androidMain/res/values-pt-rBR/strings.xml
@@ -36,5 +36,6 @@
     <string name="range_start" msgid="7097486360902471446">"Início do intervalo"</string>
     <string name="range_end" msgid="5941395253238309765">"Fim do intervalo"</string>
     <string name="snackbar_pane_title" msgid="2792228137354697160">"Alerta"</string>
-    <string name="androidx_compose_ui_autofill" msgid="9020470552698189270">"Preenchimento automático"</string>
+    <!-- no translation found for androidx_compose_ui_autofill (1150566100598813236) -->
+    <skip />
 </resources>
diff --git a/compose/ui/ui/src/androidMain/res/values-pt-rPT/strings.xml b/compose/ui/ui/src/androidMain/res/values-pt-rPT/strings.xml
index 24aa6ab..dae0f35 100644
--- a/compose/ui/ui/src/androidMain/res/values-pt-rPT/strings.xml
+++ b/compose/ui/ui/src/androidMain/res/values-pt-rPT/strings.xml
@@ -36,5 +36,6 @@
     <string name="range_start" msgid="7097486360902471446">"Início do intervalo"</string>
     <string name="range_end" msgid="5941395253238309765">"Fim do intervalo"</string>
     <string name="snackbar_pane_title" msgid="2792228137354697160">"Alerta"</string>
-    <string name="androidx_compose_ui_autofill" msgid="9020470552698189270">"Preencher automaticamente"</string>
+    <!-- no translation found for androidx_compose_ui_autofill (1150566100598813236) -->
+    <skip />
 </resources>
diff --git a/compose/ui/ui/src/androidMain/res/values-pt/strings.xml b/compose/ui/ui/src/androidMain/res/values-pt/strings.xml
index 0f991e23..34ee155 100644
--- a/compose/ui/ui/src/androidMain/res/values-pt/strings.xml
+++ b/compose/ui/ui/src/androidMain/res/values-pt/strings.xml
@@ -36,5 +36,6 @@
     <string name="range_start" msgid="7097486360902471446">"Início do intervalo"</string>
     <string name="range_end" msgid="5941395253238309765">"Fim do intervalo"</string>
     <string name="snackbar_pane_title" msgid="2792228137354697160">"Alerta"</string>
-    <string name="androidx_compose_ui_autofill" msgid="9020470552698189270">"Preenchimento automático"</string>
+    <!-- no translation found for androidx_compose_ui_autofill (1150566100598813236) -->
+    <skip />
 </resources>
diff --git a/compose/ui/ui/src/androidMain/res/values-ro/strings.xml b/compose/ui/ui/src/androidMain/res/values-ro/strings.xml
index 7931298..73172a98 100644
--- a/compose/ui/ui/src/androidMain/res/values-ro/strings.xml
+++ b/compose/ui/ui/src/androidMain/res/values-ro/strings.xml
@@ -36,5 +36,6 @@
     <string name="range_start" msgid="7097486360902471446">"Început de interval"</string>
     <string name="range_end" msgid="5941395253238309765">"Sfârșit de interval"</string>
     <string name="snackbar_pane_title" msgid="2792228137354697160">"Alertă"</string>
-    <string name="androidx_compose_ui_autofill" msgid="9020470552698189270">"Completare automată"</string>
+    <!-- no translation found for androidx_compose_ui_autofill (1150566100598813236) -->
+    <skip />
 </resources>
diff --git a/compose/ui/ui/src/androidMain/res/values-ru/strings.xml b/compose/ui/ui/src/androidMain/res/values-ru/strings.xml
index e26c046..4c82fab 100644
--- a/compose/ui/ui/src/androidMain/res/values-ru/strings.xml
+++ b/compose/ui/ui/src/androidMain/res/values-ru/strings.xml
@@ -36,5 +36,6 @@
     <string name="range_start" msgid="7097486360902471446">"Начало диапазона"</string>
     <string name="range_end" msgid="5941395253238309765">"Конец диапазона"</string>
     <string name="snackbar_pane_title" msgid="2792228137354697160">"Оповещение"</string>
-    <string name="androidx_compose_ui_autofill" msgid="9020470552698189270">"Заполнить автоматически"</string>
+    <!-- no translation found for androidx_compose_ui_autofill (1150566100598813236) -->
+    <skip />
 </resources>
diff --git a/compose/ui/ui/src/androidMain/res/values-si/strings.xml b/compose/ui/ui/src/androidMain/res/values-si/strings.xml
index b75f42c..8af2ff2 100644
--- a/compose/ui/ui/src/androidMain/res/values-si/strings.xml
+++ b/compose/ui/ui/src/androidMain/res/values-si/strings.xml
@@ -36,5 +36,6 @@
     <string name="range_start" msgid="7097486360902471446">"පරාස ආරම්භය"</string>
     <string name="range_end" msgid="5941395253238309765">"පරාස අන්තය"</string>
     <string name="snackbar_pane_title" msgid="2792228137354697160">"ඇඟවීම"</string>
-    <string name="androidx_compose_ui_autofill" msgid="9020470552698189270">"ස්වයං පිරවුම"</string>
+    <!-- no translation found for androidx_compose_ui_autofill (1150566100598813236) -->
+    <skip />
 </resources>
diff --git a/compose/ui/ui/src/androidMain/res/values-sk/strings.xml b/compose/ui/ui/src/androidMain/res/values-sk/strings.xml
index 2b67e31..1840f39 100644
--- a/compose/ui/ui/src/androidMain/res/values-sk/strings.xml
+++ b/compose/ui/ui/src/androidMain/res/values-sk/strings.xml
@@ -36,5 +36,6 @@
     <string name="range_start" msgid="7097486360902471446">"Začiatok rozsahu"</string>
     <string name="range_end" msgid="5941395253238309765">"Koniec rozsahu"</string>
     <string name="snackbar_pane_title" msgid="2792228137354697160">"Upozornenie"</string>
-    <string name="androidx_compose_ui_autofill" msgid="9020470552698189270">"Automatické dopĺňanie"</string>
+    <!-- no translation found for androidx_compose_ui_autofill (1150566100598813236) -->
+    <skip />
 </resources>
diff --git a/compose/ui/ui/src/androidMain/res/values-sl/strings.xml b/compose/ui/ui/src/androidMain/res/values-sl/strings.xml
index 556accc..8214de1 100644
--- a/compose/ui/ui/src/androidMain/res/values-sl/strings.xml
+++ b/compose/ui/ui/src/androidMain/res/values-sl/strings.xml
@@ -36,5 +36,6 @@
     <string name="range_start" msgid="7097486360902471446">"Začetek razpona"</string>
     <string name="range_end" msgid="5941395253238309765">"Konec razpona"</string>
     <string name="snackbar_pane_title" msgid="2792228137354697160">"Opozorilo"</string>
-    <string name="androidx_compose_ui_autofill" msgid="9020470552698189270">"Samodejno izpolnjevanje"</string>
+    <!-- no translation found for androidx_compose_ui_autofill (1150566100598813236) -->
+    <skip />
 </resources>
diff --git a/compose/ui/ui/src/androidMain/res/values-sq/strings.xml b/compose/ui/ui/src/androidMain/res/values-sq/strings.xml
index f3a893d..9dbcf86 100644
--- a/compose/ui/ui/src/androidMain/res/values-sq/strings.xml
+++ b/compose/ui/ui/src/androidMain/res/values-sq/strings.xml
@@ -36,5 +36,6 @@
     <string name="range_start" msgid="7097486360902471446">"Fillimi i diapazonit"</string>
     <string name="range_end" msgid="5941395253238309765">"Fundi i diapazonit"</string>
     <string name="snackbar_pane_title" msgid="2792228137354697160">"Sinjalizim"</string>
-    <string name="androidx_compose_ui_autofill" msgid="9020470552698189270">"Plotësimi automatik"</string>
+    <!-- no translation found for androidx_compose_ui_autofill (1150566100598813236) -->
+    <skip />
 </resources>
diff --git a/compose/ui/ui/src/androidMain/res/values-sr/strings.xml b/compose/ui/ui/src/androidMain/res/values-sr/strings.xml
index 664aaa4..1a96bf0 100644
--- a/compose/ui/ui/src/androidMain/res/values-sr/strings.xml
+++ b/compose/ui/ui/src/androidMain/res/values-sr/strings.xml
@@ -36,5 +36,6 @@
     <string name="range_start" msgid="7097486360902471446">"Почетак опсега"</string>
     <string name="range_end" msgid="5941395253238309765">"Крај опсега"</string>
     <string name="snackbar_pane_title" msgid="2792228137354697160">"Обавештење"</string>
-    <string name="androidx_compose_ui_autofill" msgid="9020470552698189270">"Аутоматско попуњавање"</string>
+    <!-- no translation found for androidx_compose_ui_autofill (1150566100598813236) -->
+    <skip />
 </resources>
diff --git a/compose/ui/ui/src/androidMain/res/values-sv/strings.xml b/compose/ui/ui/src/androidMain/res/values-sv/strings.xml
index 367b83e..e7cf810 100644
--- a/compose/ui/ui/src/androidMain/res/values-sv/strings.xml
+++ b/compose/ui/ui/src/androidMain/res/values-sv/strings.xml
@@ -36,5 +36,6 @@
     <string name="range_start" msgid="7097486360902471446">"Intervallets början"</string>
     <string name="range_end" msgid="5941395253238309765">"Intervallets slut"</string>
     <string name="snackbar_pane_title" msgid="2792228137354697160">"Varning"</string>
-    <string name="androidx_compose_ui_autofill" msgid="9020470552698189270">"Autofyll"</string>
+    <!-- no translation found for androidx_compose_ui_autofill (1150566100598813236) -->
+    <skip />
 </resources>
diff --git a/compose/ui/ui/src/androidMain/res/values-sw/strings.xml b/compose/ui/ui/src/androidMain/res/values-sw/strings.xml
index 8ae8d9e..1bbb041 100644
--- a/compose/ui/ui/src/androidMain/res/values-sw/strings.xml
+++ b/compose/ui/ui/src/androidMain/res/values-sw/strings.xml
@@ -36,5 +36,6 @@
     <string name="range_start" msgid="7097486360902471446">"Mwanzo wa masafa"</string>
     <string name="range_end" msgid="5941395253238309765">"Mwisho wa masafa"</string>
     <string name="snackbar_pane_title" msgid="2792228137354697160">"Arifa"</string>
-    <string name="androidx_compose_ui_autofill" msgid="9020470552698189270">"Jaza kiotomatiki"</string>
+    <!-- no translation found for androidx_compose_ui_autofill (1150566100598813236) -->
+    <skip />
 </resources>
diff --git a/compose/ui/ui/src/androidMain/res/values-ta/strings.xml b/compose/ui/ui/src/androidMain/res/values-ta/strings.xml
index 14d8905..fa9c2b3 100644
--- a/compose/ui/ui/src/androidMain/res/values-ta/strings.xml
+++ b/compose/ui/ui/src/androidMain/res/values-ta/strings.xml
@@ -36,5 +36,6 @@
     <string name="range_start" msgid="7097486360902471446">"வரம்பு தொடக்கம்"</string>
     <string name="range_end" msgid="5941395253238309765">"வரம்பு முடிவு"</string>
     <string name="snackbar_pane_title" msgid="2792228137354697160">"விழிப்பூட்டல்"</string>
-    <string name="androidx_compose_ui_autofill" msgid="9020470552698189270">"தன்னிரப்பி"</string>
+    <!-- no translation found for androidx_compose_ui_autofill (1150566100598813236) -->
+    <skip />
 </resources>
diff --git a/compose/ui/ui/src/androidMain/res/values-te/strings.xml b/compose/ui/ui/src/androidMain/res/values-te/strings.xml
index ab30f55..121160e 100644
--- a/compose/ui/ui/src/androidMain/res/values-te/strings.xml
+++ b/compose/ui/ui/src/androidMain/res/values-te/strings.xml
@@ -36,5 +36,6 @@
     <string name="range_start" msgid="7097486360902471446">"పరిధి ప్రారంభమయింది"</string>
     <string name="range_end" msgid="5941395253238309765">"పరిధి ముగిసింది"</string>
     <string name="snackbar_pane_title" msgid="2792228137354697160">"హెచ్చరిక"</string>
-    <string name="androidx_compose_ui_autofill" msgid="9020470552698189270">"ఆటోఫిల్"</string>
+    <!-- no translation found for androidx_compose_ui_autofill (1150566100598813236) -->
+    <skip />
 </resources>
diff --git a/compose/ui/ui/src/androidMain/res/values-th/strings.xml b/compose/ui/ui/src/androidMain/res/values-th/strings.xml
index 9bd3151..342eb71 100644
--- a/compose/ui/ui/src/androidMain/res/values-th/strings.xml
+++ b/compose/ui/ui/src/androidMain/res/values-th/strings.xml
@@ -36,5 +36,6 @@
     <string name="range_start" msgid="7097486360902471446">"จุดเริ่มต้นของช่วง"</string>
     <string name="range_end" msgid="5941395253238309765">"จุดสิ้นสุดของช่วง"</string>
     <string name="snackbar_pane_title" msgid="2792228137354697160">"การแจ้งเตือน"</string>
-    <string name="androidx_compose_ui_autofill" msgid="9020470552698189270">"ป้อนข้อความอัตโนมัติ"</string>
+    <!-- no translation found for androidx_compose_ui_autofill (1150566100598813236) -->
+    <skip />
 </resources>
diff --git a/compose/ui/ui/src/androidMain/res/values-tl/strings.xml b/compose/ui/ui/src/androidMain/res/values-tl/strings.xml
index a363dd9..ad14368 100644
--- a/compose/ui/ui/src/androidMain/res/values-tl/strings.xml
+++ b/compose/ui/ui/src/androidMain/res/values-tl/strings.xml
@@ -36,5 +36,6 @@
     <string name="range_start" msgid="7097486360902471446">"Simula ng range"</string>
     <string name="range_end" msgid="5941395253238309765">"Katapusan ng range"</string>
     <string name="snackbar_pane_title" msgid="2792228137354697160">"Alerto"</string>
-    <string name="androidx_compose_ui_autofill" msgid="9020470552698189270">"Autofill"</string>
+    <!-- no translation found for androidx_compose_ui_autofill (1150566100598813236) -->
+    <skip />
 </resources>
diff --git a/compose/ui/ui/src/androidMain/res/values-tr/strings.xml b/compose/ui/ui/src/androidMain/res/values-tr/strings.xml
index 211d42c..699e6a2 100644
--- a/compose/ui/ui/src/androidMain/res/values-tr/strings.xml
+++ b/compose/ui/ui/src/androidMain/res/values-tr/strings.xml
@@ -36,5 +36,6 @@
     <string name="range_start" msgid="7097486360902471446">"Aralık başlangıcı"</string>
     <string name="range_end" msgid="5941395253238309765">"Aralık sonu"</string>
     <string name="snackbar_pane_title" msgid="2792228137354697160">"Uyarı"</string>
-    <string name="androidx_compose_ui_autofill" msgid="9020470552698189270">"Otomatik doldurma"</string>
+    <!-- no translation found for androidx_compose_ui_autofill (1150566100598813236) -->
+    <skip />
 </resources>
diff --git a/compose/ui/ui/src/androidMain/res/values-uk/strings.xml b/compose/ui/ui/src/androidMain/res/values-uk/strings.xml
index 71c8ba9..3212a69 100644
--- a/compose/ui/ui/src/androidMain/res/values-uk/strings.xml
+++ b/compose/ui/ui/src/androidMain/res/values-uk/strings.xml
@@ -36,5 +36,6 @@
     <string name="range_start" msgid="7097486360902471446">"Початок діапазону"</string>
     <string name="range_end" msgid="5941395253238309765">"Кінець діапазону"</string>
     <string name="snackbar_pane_title" msgid="2792228137354697160">"Сповіщення"</string>
-    <string name="androidx_compose_ui_autofill" msgid="9020470552698189270">"Автозаповнення"</string>
+    <!-- no translation found for androidx_compose_ui_autofill (1150566100598813236) -->
+    <skip />
 </resources>
diff --git a/compose/ui/ui/src/androidMain/res/values-ur/strings.xml b/compose/ui/ui/src/androidMain/res/values-ur/strings.xml
index f5c592a..69dc9d0 100644
--- a/compose/ui/ui/src/androidMain/res/values-ur/strings.xml
+++ b/compose/ui/ui/src/androidMain/res/values-ur/strings.xml
@@ -36,5 +36,6 @@
     <string name="range_start" msgid="7097486360902471446">"رینج کی شروعات"</string>
     <string name="range_end" msgid="5941395253238309765">"رینج کا اختتام"</string>
     <string name="snackbar_pane_title" msgid="2792228137354697160">"الرٹ"</string>
-    <string name="androidx_compose_ui_autofill" msgid="9020470552698189270">"آٹو فل"</string>
+    <!-- no translation found for androidx_compose_ui_autofill (1150566100598813236) -->
+    <skip />
 </resources>
diff --git a/compose/ui/ui/src/androidMain/res/values-uz/strings.xml b/compose/ui/ui/src/androidMain/res/values-uz/strings.xml
index 396bc21..0abb52e 100644
--- a/compose/ui/ui/src/androidMain/res/values-uz/strings.xml
+++ b/compose/ui/ui/src/androidMain/res/values-uz/strings.xml
@@ -36,5 +36,6 @@
     <string name="range_start" msgid="7097486360902471446">"Oraliq boshi"</string>
     <string name="range_end" msgid="5941395253238309765">"Oraliq oxiri"</string>
     <string name="snackbar_pane_title" msgid="2792228137354697160">"Signal"</string>
-    <string name="androidx_compose_ui_autofill" msgid="9020470552698189270">"Avtomatik kiritish"</string>
+    <!-- no translation found for androidx_compose_ui_autofill (1150566100598813236) -->
+    <skip />
 </resources>
diff --git a/compose/ui/ui/src/androidMain/res/values-vi/strings.xml b/compose/ui/ui/src/androidMain/res/values-vi/strings.xml
index 9c20a09..beec58d 100644
--- a/compose/ui/ui/src/androidMain/res/values-vi/strings.xml
+++ b/compose/ui/ui/src/androidMain/res/values-vi/strings.xml
@@ -36,5 +36,6 @@
     <string name="range_start" msgid="7097486360902471446">"Điểm bắt đầu phạm vi"</string>
     <string name="range_end" msgid="5941395253238309765">"Điểm kết thúc phạm vi"</string>
     <string name="snackbar_pane_title" msgid="2792228137354697160">"Cảnh báo"</string>
-    <string name="androidx_compose_ui_autofill" msgid="9020470552698189270">"Tự động điền"</string>
+    <!-- no translation found for androidx_compose_ui_autofill (1150566100598813236) -->
+    <skip />
 </resources>
diff --git a/compose/ui/ui/src/androidMain/res/values-zh-rCN/strings.xml b/compose/ui/ui/src/androidMain/res/values-zh-rCN/strings.xml
index b0504ab..6c6ad05 100644
--- a/compose/ui/ui/src/androidMain/res/values-zh-rCN/strings.xml
+++ b/compose/ui/ui/src/androidMain/res/values-zh-rCN/strings.xml
@@ -36,5 +36,6 @@
     <string name="range_start" msgid="7097486360902471446">"范围起点"</string>
     <string name="range_end" msgid="5941395253238309765">"范围终点"</string>
     <string name="snackbar_pane_title" msgid="2792228137354697160">"提醒"</string>
-    <string name="androidx_compose_ui_autofill" msgid="9020470552698189270">"自动填充"</string>
+    <!-- no translation found for androidx_compose_ui_autofill (1150566100598813236) -->
+    <skip />
 </resources>
diff --git a/compose/ui/ui/src/androidMain/res/values-zh-rHK/strings.xml b/compose/ui/ui/src/androidMain/res/values-zh-rHK/strings.xml
index 73ff39f..85246e7 100644
--- a/compose/ui/ui/src/androidMain/res/values-zh-rHK/strings.xml
+++ b/compose/ui/ui/src/androidMain/res/values-zh-rHK/strings.xml
@@ -36,5 +36,6 @@
     <string name="range_start" msgid="7097486360902471446">"範圍開始"</string>
     <string name="range_end" msgid="5941395253238309765">"範圍結束"</string>
     <string name="snackbar_pane_title" msgid="2792228137354697160">"警示"</string>
-    <string name="androidx_compose_ui_autofill" msgid="9020470552698189270">"自動填入"</string>
+    <!-- no translation found for androidx_compose_ui_autofill (1150566100598813236) -->
+    <skip />
 </resources>
diff --git a/compose/ui/ui/src/androidMain/res/values-zh-rTW/strings.xml b/compose/ui/ui/src/androidMain/res/values-zh-rTW/strings.xml
index 02ce823..dca2814 100644
--- a/compose/ui/ui/src/androidMain/res/values-zh-rTW/strings.xml
+++ b/compose/ui/ui/src/androidMain/res/values-zh-rTW/strings.xml
@@ -36,5 +36,6 @@
     <string name="range_start" msgid="7097486360902471446">"範圍起點"</string>
     <string name="range_end" msgid="5941395253238309765">"範圍終點"</string>
     <string name="snackbar_pane_title" msgid="2792228137354697160">"快訊"</string>
-    <string name="androidx_compose_ui_autofill" msgid="9020470552698189270">"自動填入"</string>
+    <!-- no translation found for androidx_compose_ui_autofill (1150566100598813236) -->
+    <skip />
 </resources>
diff --git a/compose/ui/ui/src/androidMain/res/values-zu/strings.xml b/compose/ui/ui/src/androidMain/res/values-zu/strings.xml
index 5095133f..bead56c 100644
--- a/compose/ui/ui/src/androidMain/res/values-zu/strings.xml
+++ b/compose/ui/ui/src/androidMain/res/values-zu/strings.xml
@@ -36,5 +36,6 @@
     <string name="range_start" msgid="7097486360902471446">"Ukuqala kobubanzi"</string>
     <string name="range_end" msgid="5941395253238309765">"Umkhawulo wobubanzi"</string>
     <string name="snackbar_pane_title" msgid="2792228137354697160">"Isexwayiso"</string>
-    <string name="androidx_compose_ui_autofill" msgid="9020470552698189270">"Ukugcwalisa okuzenzakalelayo"</string>
+    <!-- no translation found for androidx_compose_ui_autofill (1150566100598813236) -->
+    <skip />
 </resources>
diff --git a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/node/LayoutTreeConsistencyChecker.kt b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/node/LayoutTreeConsistencyChecker.kt
index 8609d28..b4c01d6 100644
--- a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/node/LayoutTreeConsistencyChecker.kt
+++ b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/node/LayoutTreeConsistencyChecker.kt
@@ -84,7 +84,8 @@
                     parentLayoutState == LayoutNode.LayoutState.Measuring ||
                     parentLayoutState == LayoutNode.LayoutState.LayingOut ||
                     postponedMeasureRequests.fastAny { it.node == this } ||
-                    layoutState == LayoutNode.LayoutState.Measuring
+                    layoutState == LayoutNode.LayoutState.Measuring ||
+                    layoutState == LayoutNode.LayoutState.LayingOut
             }
         }
         if (isPlacedInLookahead == true) {
diff --git a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/node/NodeCoordinator.kt b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/node/NodeCoordinator.kt
index 6835884..551664d 100644
--- a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/node/NodeCoordinator.kt
+++ b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/node/NodeCoordinator.kt
@@ -557,14 +557,7 @@
                 layoutNode.innerLayerCoordinatorIsDirty = true
                 invalidateParentLayer()
             } else if (updateParameters) {
-                val positionalPropertiesChanged = updateLayerParameters()
-                if (positionalPropertiesChanged) {
-                    layoutNode.onCoordinatorPositionChanged()
-                    layoutNode
-                        .requireOwner()
-                        .rectManager
-                        .onLayoutLayerPositionalPropertiesChanged(layoutNode)
-                }
+                updateLayerParameters()
             }
         } else {
             this.layerBlock = null
@@ -585,10 +578,10 @@
     }
 
     /** returns true if some of the positional properties did change. */
-    private fun updateLayerParameters(invokeOnLayoutChange: Boolean = true): Boolean {
+    private fun updateLayerParameters(invokeOnLayoutChange: Boolean = true) {
         if (explicitLayer != null) {
             // the parameters of the explicit layers are configured differently.
-            return false
+            return
         }
         val layer = layer
         if (layer != null) {
@@ -633,10 +626,34 @@
             ) {
                 layoutNode.owner?.onLayoutChange(layoutNode)
             }
-            return positionalPropertiesChanged
+            if (positionalPropertiesChanged) {
+                val layoutNode = layoutNode
+                val layoutDelegate = layoutNode.layoutDelegate
+                if (layoutDelegate.childrenAccessingCoordinatesDuringPlacement > 0) {
+                    if (
+                        layoutDelegate.coordinatesAccessedDuringModifierPlacement ||
+                            layoutDelegate.coordinatesAccessedDuringPlacement
+                    ) {
+                        layoutNode.requestRelayout()
+                    }
+                    layoutDelegate.measurePassDelegate.notifyChildrenUsingCoordinatesWhilePlacing()
+                }
+                layoutNode.onCoordinatorPositionChanged()
+                val owner = layoutNode.requireOwner()
+                val rectManager = owner.rectManager
+                if (this === layoutNode.outerCoordinator) {
+                    // transformations on the outer coordinator define the layout position
+                    rectManager.onLayoutPositionChanged(layoutNode)
+                } else {
+                    // transformations on other coordinators invalidate outerToInnerOffset
+                    rectManager.onLayoutLayerPositionalPropertiesChanged(layoutNode)
+                }
+                if (layoutNode.globallyPositionedObservers > 0) {
+                    owner.requestOnPositionedCallback(layoutNode)
+                }
+            }
         } else {
             checkPrecondition(layerBlock == null) { "null layer with a non-null layerBlock" }
-            return false
         }
     }
 
@@ -1485,39 +1502,7 @@
         private val onCommitAffectingLayerParams: (NodeCoordinator) -> Unit = { coordinator ->
             withComposeStackTrace(coordinator.layoutNode) {
                 if (coordinator.isValidOwnerScope) {
-                    // coordinator.layerPositionalProperties should always be non-null here, but
-                    // we'll just be careful with a null check.
-                    val positionalPropertiesChanged = coordinator.updateLayerParameters()
-                    if (positionalPropertiesChanged) {
-                        val layoutNode = coordinator.layoutNode
-                        val layoutDelegate = layoutNode.layoutDelegate
-                        if (layoutDelegate.childrenAccessingCoordinatesDuringPlacement > 0) {
-                            if (
-                                layoutDelegate.coordinatesAccessedDuringModifierPlacement ||
-                                    layoutDelegate.coordinatesAccessedDuringPlacement
-                            ) {
-                                layoutNode.requestRelayout()
-                            }
-                            layoutDelegate.measurePassDelegate
-                                .notifyChildrenUsingCoordinatesWhilePlacing()
-                        }
-                        layoutNode.onCoordinatorPositionChanged()
-                        val owner = layoutNode.requireOwner()
-                        val rectManager = owner.rectManager
-                        if (coordinator === layoutNode.outerCoordinator) {
-                            // transformations on the outer coordinator define the layout position
-                            rectManager.onLayoutPositionChanged(layoutNode)
-                            // we need to manually trigger the callbacks as the state based layer
-                            // invalidations are processed outside of the measure pass.
-                            rectManager.invalidateCallbacksFor(layoutNode)
-                        } else {
-                            // transformations on other coordinators invalidate outerToInnerOffset
-                            rectManager.onLayoutLayerPositionalPropertiesChanged(layoutNode)
-                        }
-                        if (layoutNode.globallyPositionedObservers > 0) {
-                            owner.requestOnPositionedCallback(layoutNode)
-                        }
-                    }
+                    coordinator.updateLayerParameters()
                 }
             }
         }
diff --git a/constraintlayout/constraintlayout-compose/build.gradle b/constraintlayout/constraintlayout-compose/build.gradle
index adad415..1eab206 100644
--- a/constraintlayout/constraintlayout-compose/build.gradle
+++ b/constraintlayout/constraintlayout-compose/build.gradle
@@ -93,7 +93,7 @@
             }
         }
 
-        androidUnitTest {
+        androidHostTest {
             dependsOn(jvmCommonTest)
             dependencies {
                 implementation(libs.kotlinTest)
diff --git a/constraintlayout/constraintlayout-compose/src/androidUnitTest/kotlin/androidx/constraintlayout/compose/ConstraintSetStabilityTest.kt b/constraintlayout/constraintlayout-compose/src/androidHostTest/kotlin/androidx/constraintlayout/compose/ConstraintSetStabilityTest.kt
similarity index 100%
rename from constraintlayout/constraintlayout-compose/src/androidUnitTest/kotlin/androidx/constraintlayout/compose/ConstraintSetStabilityTest.kt
rename to constraintlayout/constraintlayout-compose/src/androidHostTest/kotlin/androidx/constraintlayout/compose/ConstraintSetStabilityTest.kt
diff --git a/constraintlayout/constraintlayout-compose/src/androidUnitTest/kotlin/androidx/constraintlayout/compose/DebugFlagsTest.kt b/constraintlayout/constraintlayout-compose/src/androidHostTest/kotlin/androidx/constraintlayout/compose/DebugFlagsTest.kt
similarity index 100%
rename from constraintlayout/constraintlayout-compose/src/androidUnitTest/kotlin/androidx/constraintlayout/compose/DebugFlagsTest.kt
rename to constraintlayout/constraintlayout-compose/src/androidHostTest/kotlin/androidx/constraintlayout/compose/DebugFlagsTest.kt
diff --git a/constraintlayout/constraintlayout-compose/src/androidUnitTest/kotlin/androidx/constraintlayout/compose/GridFlagTest.kt b/constraintlayout/constraintlayout-compose/src/androidHostTest/kotlin/androidx/constraintlayout/compose/GridFlagTest.kt
similarity index 100%
rename from constraintlayout/constraintlayout-compose/src/androidUnitTest/kotlin/androidx/constraintlayout/compose/GridFlagTest.kt
rename to constraintlayout/constraintlayout-compose/src/androidHostTest/kotlin/androidx/constraintlayout/compose/GridFlagTest.kt
diff --git a/constraintlayout/constraintlayout-compose/src/androidUnitTest/kotlin/androidx/constraintlayout/compose/MotionSceneStabilityTest.kt b/constraintlayout/constraintlayout-compose/src/androidHostTest/kotlin/androidx/constraintlayout/compose/MotionSceneStabilityTest.kt
similarity index 100%
rename from constraintlayout/constraintlayout-compose/src/androidUnitTest/kotlin/androidx/constraintlayout/compose/MotionSceneStabilityTest.kt
rename to constraintlayout/constraintlayout-compose/src/androidHostTest/kotlin/androidx/constraintlayout/compose/MotionSceneStabilityTest.kt
diff --git a/constraintlayout/constraintlayout-compose/src/androidUnitTest/kotlin/androidx/constraintlayout/compose/TransitionStabilityTest.kt b/constraintlayout/constraintlayout-compose/src/androidHostTest/kotlin/androidx/constraintlayout/compose/TransitionStabilityTest.kt
similarity index 100%
rename from constraintlayout/constraintlayout-compose/src/androidUnitTest/kotlin/androidx/constraintlayout/compose/TransitionStabilityTest.kt
rename to constraintlayout/constraintlayout-compose/src/androidHostTest/kotlin/androidx/constraintlayout/compose/TransitionStabilityTest.kt
diff --git a/core/core-telecom/api/current.txt b/core/core-telecom/api/current.txt
index 1fd0854..d56d4ed 100644
--- a/core/core-telecom/api/current.txt
+++ b/core/core-telecom/api/current.txt
@@ -123,6 +123,7 @@
     method @SuppressCompatibility @androidx.core.telecom.util.ExperimentalAppActions public suspend Object? addCallWithExtensions(androidx.core.telecom.CallAttributesCompat callAttributes, kotlin.jvm.functions.Function2<? super java.lang.Integer,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,? extends java.lang.Object?> onAnswer, kotlin.jvm.functions.Function2<? super android.telecom.DisconnectCause,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,? extends java.lang.Object?> onDisconnect, kotlin.jvm.functions.Function1<? super kotlin.coroutines.Continuation<? super kotlin.Unit>,? extends java.lang.Object?> onSetActive, kotlin.jvm.functions.Function1<? super kotlin.coroutines.Continuation<? super kotlin.Unit>,? extends java.lang.Object?> onSetInactive, kotlin.jvm.functions.Function2<? super androidx.core.telecom.extensions.ExtensionInitializationScope,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,? extends java.lang.Object?> init, kotlin.coroutines.Continuation<? super kotlin.Unit>);
     method public kotlinx.coroutines.flow.Flow<java.util.List<androidx.core.telecom.CallEndpointCompat>> getAvailableStartingCallEndpoints();
     method @RequiresPermission("android.permission.MANAGE_OWN_CALLS") public void registerAppWithTelecom(int capabilities);
+    method @RequiresPermission("android.permission.MANAGE_OWN_CALLS") public void registerAppWithTelecom(int capabilities, optional int backwardsCompatSdkLevel);
     field public static final int CAPABILITY_BASELINE = 1; // 0x1
     field public static final int CAPABILITY_SUPPORTS_CALL_STREAMING = 4; // 0x4
     field public static final int CAPABILITY_SUPPORTS_VIDEO_CALLING = 2; // 0x2
diff --git a/core/core-telecom/api/restricted_current.txt b/core/core-telecom/api/restricted_current.txt
index 1fd0854..d56d4ed 100644
--- a/core/core-telecom/api/restricted_current.txt
+++ b/core/core-telecom/api/restricted_current.txt
@@ -123,6 +123,7 @@
     method @SuppressCompatibility @androidx.core.telecom.util.ExperimentalAppActions public suspend Object? addCallWithExtensions(androidx.core.telecom.CallAttributesCompat callAttributes, kotlin.jvm.functions.Function2<? super java.lang.Integer,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,? extends java.lang.Object?> onAnswer, kotlin.jvm.functions.Function2<? super android.telecom.DisconnectCause,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,? extends java.lang.Object?> onDisconnect, kotlin.jvm.functions.Function1<? super kotlin.coroutines.Continuation<? super kotlin.Unit>,? extends java.lang.Object?> onSetActive, kotlin.jvm.functions.Function1<? super kotlin.coroutines.Continuation<? super kotlin.Unit>,? extends java.lang.Object?> onSetInactive, kotlin.jvm.functions.Function2<? super androidx.core.telecom.extensions.ExtensionInitializationScope,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,? extends java.lang.Object?> init, kotlin.coroutines.Continuation<? super kotlin.Unit>);
     method public kotlinx.coroutines.flow.Flow<java.util.List<androidx.core.telecom.CallEndpointCompat>> getAvailableStartingCallEndpoints();
     method @RequiresPermission("android.permission.MANAGE_OWN_CALLS") public void registerAppWithTelecom(int capabilities);
+    method @RequiresPermission("android.permission.MANAGE_OWN_CALLS") public void registerAppWithTelecom(int capabilities, optional int backwardsCompatSdkLevel);
     field public static final int CAPABILITY_BASELINE = 1; // 0x1
     field public static final int CAPABILITY_SUPPORTS_CALL_STREAMING = 4; // 0x4
     field public static final int CAPABILITY_SUPPORTS_VIDEO_CALLING = 2; // 0x2
diff --git a/core/core-telecom/src/androidTest/java/androidx/core/telecom/test/BasicCallControlCallbacksTest.kt b/core/core-telecom/src/androidTest/java/androidx/core/telecom/test/BasicCallControlCallbacksTest.kt
index 87dd237..7474754 100644
--- a/core/core-telecom/src/androidTest/java/androidx/core/telecom/test/BasicCallControlCallbacksTest.kt
+++ b/core/core-telecom/src/androidTest/java/androidx/core/telecom/test/BasicCallControlCallbacksTest.kt
@@ -74,7 +74,6 @@
     @LargeTest
     @Test(timeout = 10000)
     fun testBasicCallControlCallbackAnswerCall() {
-        setUpV2Test()
         verifyAnswerCall()
     }
 
@@ -88,7 +87,6 @@
     @LargeTest
     @Test(timeout = 10000)
     fun testRejectCallControlCallbackAnswerCall() {
-        setUpV2Test()
         verifyRejectAnswerCall()
     }
 
@@ -100,7 +98,6 @@
     @LargeTest
     @Test(timeout = 10000)
     fun testRejectCallControlCallbackHoldCall() {
-        setUpV2Test()
         verifyRejectHoldCall()
     }
 
@@ -112,7 +109,6 @@
     @LargeTest
     @Test(timeout = 10000)
     fun testRejectCallControlCallbackUnholdCall() {
-        setUpV2Test()
         verifyRejectUnholdCall()
     }
 
@@ -124,7 +120,6 @@
     @LargeTest
     @Test(timeout = 10000)
     fun testRejectCallControlCallbackDisconnectCall() {
-        setUpV2Test()
         verifyRejectDisconnectCall(true)
     }
 
@@ -136,7 +131,6 @@
     @LargeTest
     @Test(timeout = 10000)
     fun testRejectCallControlCallbackRejectCall() {
-        setUpV2Test()
         verifyRejectDisconnectCall(false)
     }
 
@@ -149,7 +143,6 @@
     @LargeTest
     @Test(timeout = 10000)
     fun testBasicCallControlCallbackDisconnectCall() {
-        setUpV2Test()
         verifyDisconnectCall()
     }
 
@@ -162,7 +155,6 @@
     @LargeTest
     @Test(timeout = 10000)
     fun testBasicCallControlCallbackHoldCall() {
-        setUpV2Test()
         verifyHoldCall()
     }
 
@@ -175,7 +167,6 @@
     @LargeTest
     @Test(timeout = 10000)
     fun testBasicCallControlCallbackUnholdCall() {
-        setUpV2Test()
         verifyUnholdCall()
     }
 
diff --git a/core/core-telecom/src/androidTest/java/androidx/core/telecom/test/BasicCallControlsTest.kt b/core/core-telecom/src/androidTest/java/androidx/core/telecom/test/BasicCallControlsTest.kt
index 9a7a2d6..78493eb 100644
--- a/core/core-telecom/src/androidTest/java/androidx/core/telecom/test/BasicCallControlsTest.kt
+++ b/core/core-telecom/src/androidTest/java/androidx/core/telecom/test/BasicCallControlsTest.kt
@@ -91,7 +91,6 @@
     @LargeTest
     @Test(timeout = 10000)
     fun testBasicOutgoingCall() {
-        setUpV2Test()
         runBlocking_addCallAndSetActive(TestUtils.OUTGOING_CALL_ATTRIBUTES)
     }
 
@@ -103,7 +102,6 @@
     @LargeTest
     @Test(timeout = 10000)
     fun testBasicIncomingCall() {
-        setUpV2Test()
         runBlocking_addCallAndSetActive(TestUtils.INCOMING_CALL_ATTRIBUTES)
     }
 
@@ -115,7 +113,6 @@
     @LargeTest
     @Test(timeout = 10000)
     fun testTogglingHoldOnActiveCall() {
-        setUpV2Test()
         runBlocking_ToggleCallAsserts(TestUtils.OUTGOING_CALL_ATTRIBUTES)
     }
 
@@ -128,7 +125,6 @@
     @LargeTest
     @Test(timeout = 10000)
     fun testTogglingHoldOnActiveCall_NoHoldCapabilities() {
-        setUpV2Test()
         assertFalse(
             TestUtils.OUTGOING_NO_HOLD_CAP_CALL_ATTRIBUTES.hasSupportsSetInactiveCapability()
         )
@@ -144,7 +140,6 @@
     @LargeTest
     @Test(timeout = 10000)
     fun testRequestEndpointChange() {
-        setUpV2Test()
         runBlocking_RequestEndpointChangeAsserts()
     }
 
@@ -157,7 +152,6 @@
     @LargeTest
     @Test(timeout = 10000)
     fun testIsMuted() {
-        setUpV2Test()
         verifyMuteStateChange()
     }
 
diff --git a/core/core-telecom/src/androidTest/java/androidx/core/telecom/test/CallControlScopeFlowsTest.kt b/core/core-telecom/src/androidTest/java/androidx/core/telecom/test/CallControlScopeFlowsTest.kt
index 3ee26e6..ccb40d4 100644
--- a/core/core-telecom/src/androidTest/java/androidx/core/telecom/test/CallControlScopeFlowsTest.kt
+++ b/core/core-telecom/src/androidTest/java/androidx/core/telecom/test/CallControlScopeFlowsTest.kt
@@ -53,7 +53,6 @@
     @SmallTest
     @Test
     fun testFlowsEchoValues_Transactional() {
-        setUpV2Test()
         runBlocking { assertFlowsEchoValues() }
     }
 
diff --git a/core/core-telecom/src/androidTest/java/androidx/core/telecom/test/CallSessionLegacyTest.kt b/core/core-telecom/src/androidTest/java/androidx/core/telecom/test/CallSessionLegacyTest.kt
index ec3506f..02a522d 100644
--- a/core/core-telecom/src/androidTest/java/androidx/core/telecom/test/CallSessionLegacyTest.kt
+++ b/core/core-telecom/src/androidTest/java/androidx/core/telecom/test/CallSessionLegacyTest.kt
@@ -64,7 +64,6 @@
     @SmallTest
     @Test
     fun testMatchingOnEndpointName() {
-        setUpBackwardsCompatTest()
         runBlocking {
             // Represent a BluetoothDevice since the object cannot be mocked
             val btDeviceName = "Pixel Buds"
@@ -96,7 +95,6 @@
     @SmallTest
     @Test
     fun testMatchingOnEndpointNameWithDifferentAddresses() {
-        setUpBackwardsCompatTest()
         runBlocking {
             // Represent a BluetoothDevice since the object cannot be mocked
             val btDeviceName = "Pixel Buds"
@@ -129,7 +127,6 @@
     @SmallTest
     @Test
     fun testRemovalOfEarpieceEndpointIfWiredEndpointIsPresent() {
-        setUpBackwardsCompatTest()
         runBlocking {
             val callSession = initCallSessionLegacy(coroutineContext, null)
             val supportedRouteMask = ROUTE_EARPIECE or ROUTE_WIRED_HEADSET
@@ -150,7 +147,6 @@
     @SmallTest
     @Test
     fun testPlatformEndpointsAreRemappedToExistingEndpoints() {
-        setUpBackwardsCompatTest()
         runBlocking {
             val callSession = initCallSessionLegacy(coroutineContext, null)
             val supportedRouteMask = CallAudioState.ROUTE_EARPIECE or CallAudioState.ROUTE_SPEAKER
@@ -184,7 +180,6 @@
     @SmallTest
     @Test
     fun testOnCallAudioStateChangedWithNullActiveDevice() {
-        setUpBackwardsCompatTest()
         runBlocking {
             val callSession = initCallSessionLegacy(coroutineContext, null)
 
diff --git a/core/core-telecom/src/androidTest/java/androidx/core/telecom/test/CallSessionTest.kt b/core/core-telecom/src/androidTest/java/androidx/core/telecom/test/CallSessionTest.kt
index 4e4b326..d316282 100644
--- a/core/core-telecom/src/androidTest/java/androidx/core/telecom/test/CallSessionTest.kt
+++ b/core/core-telecom/src/androidTest/java/androidx/core/telecom/test/CallSessionTest.kt
@@ -164,7 +164,6 @@
     @SmallTest
     @Test
     fun testRemovalOfEarpieceEndpointIfWiredEndpointIsPresent() {
-        setUpV2Test()
         val res =
             EndpointUtils.maybeRemoveEarpieceIfWiredEndpointPresent(
                 mWiredAndEarpieceEndpoints.toMutableList()
@@ -178,7 +177,6 @@
     @SmallTest
     @Test
     fun testCompletableDeferredObjectsComplete() {
-        setUpV2Test()
         runBlocking {
             val callChannels = CallChannels()
             val callSession = initCallSession(coroutineContext, callChannels)
@@ -203,7 +201,6 @@
     @SmallTest
     @Test
     fun testCallEventsEchoEndpoints() {
-        setUpV2Test()
         runBlocking {
             val callChannels = CallChannels()
             val callSession = initCallSession(coroutineContext, callChannels)
@@ -229,7 +226,6 @@
     @SmallTest
     @Test
     fun testPlatformEndpointsAreRemappedToExistingEndpoints() {
-        setUpV2Test()
         runBlocking {
             val callSession = initCallSession(coroutineContext, CallChannels())
 
diff --git a/core/core-telecom/src/androidTest/java/androidx/core/telecom/test/CallsManagerTest.kt b/core/core-telecom/src/androidTest/java/androidx/core/telecom/test/CallsManagerTest.kt
index 4ff74d7..42b06cb 100644
--- a/core/core-telecom/src/androidTest/java/androidx/core/telecom/test/CallsManagerTest.kt
+++ b/core/core-telecom/src/androidTest/java/androidx/core/telecom/test/CallsManagerTest.kt
@@ -19,6 +19,7 @@
 import android.os.Build.VERSION_CODES
 import android.telecom.CallException
 import android.telecom.DisconnectCause
+import android.telecom.PhoneAccount
 import android.telecom.PhoneAccount.CAPABILITY_SELF_MANAGED
 import android.telecom.PhoneAccount.CAPABILITY_SUPPORTS_CALL_STREAMING
 import android.telecom.PhoneAccount.CAPABILITY_SUPPORTS_TRANSACTIONAL_OPERATIONS
@@ -29,6 +30,7 @@
 import androidx.core.telecom.CallEndpointCompat
 import androidx.core.telecom.CallsManager
 import androidx.core.telecom.internal.AddCallResult
+import androidx.core.telecom.internal.utils.BuildVersionAdapter
 import androidx.core.telecom.internal.utils.Utils
 import androidx.core.telecom.test.utils.BaseTelecomTest
 import androidx.core.telecom.test.utils.TestPermissionUtils.createBluetoothPermissionRule
@@ -47,7 +49,9 @@
 import kotlinx.coroutines.flow.filter
 import kotlinx.coroutines.launch
 import kotlinx.coroutines.runBlocking
+import org.junit.After
 import org.junit.Assert.assertEquals
+import org.junit.Assert.assertFalse
 import org.junit.Assert.assertNotNull
 import org.junit.Assert.assertThrows
 import org.junit.Assert.assertTrue
@@ -67,11 +71,16 @@
         val TAG = CallsManagerTest::class.java.simpleName
     }
 
+    @After
+    fun tearDown() {
+        Utils.resetUtils()
+    }
+
     @SmallTest
     @Test
-    fun testGetPhoneAccountWithUBuild() {
+    fun testGetPhoneAccountWithUpsideDownCakePlusBuild() {
         try {
-            Utils.setUtils(TestUtils.mV2Build)
+            setTestBuildVersion(VERSION_CODES.UPSIDE_DOWN_CAKE)
             val account = mCallsManager.getPhoneAccountHandleForPackage()
             assertEquals(mTestClassName, account.componentName.className)
         } finally {
@@ -81,9 +90,9 @@
 
     @SmallTest
     @Test
-    fun testGetPhoneAccountWithUBuildWithTminusBuild() {
+    fun testGetPhoneAccountWithUBuildWithTiramisuMinusBuild() {
         try {
-            Utils.setUtils(TestUtils.mBackwardsCompatBuild)
+            setTestBuildVersion(VERSION_CODES.TIRAMISU)
             val account = mCallsManager.getPhoneAccountHandleForPackage()
             assertEquals(CallsManager.CONNECTION_SERVICE_CLASS, account.componentName.className)
         } finally {
@@ -95,7 +104,7 @@
     @Test
     fun testGetPhoneAccountWithInvalidBuild() {
         try {
-            Utils.setUtils(TestUtils.mInvalidBuild)
+            setTestBuildVersion(0)
             assertThrows(UnsupportedOperationException::class.java) {
                 mCallsManager.getPhoneAccountHandleForPackage()
             }
@@ -119,7 +128,7 @@
             val account = mCallsManager.getBuiltPhoneAccount()!!
             assertNotNull(account.extras)
             assertTrue(account.extras.getBoolean(CallsManager.PLACEHOLDER_VALUE_ACCOUNT_BUNDLE))
-            if (Utils.hasPlatformV2Apis()) {
+            if (!Utils.shouldUseBackwardsCompatImplementation()) {
                 assertTrue(
                     Utils.hasCapability(
                         CAPABILITY_SUPPORTS_TRANSACTIONAL_OPERATIONS,
@@ -142,7 +151,6 @@
     @SmallTest
     @Test
     fun testRegisterAllCapabilities() {
-        setUpV2Test()
         mCallsManager.registerAppWithTelecom(
             CallsManager.CAPABILITY_SUPPORTS_VIDEO_CALLING or
                 CallsManager.CAPABILITY_SUPPORTS_CALL_STREAMING
@@ -164,7 +172,6 @@
     @SmallTest
     @Test
     fun testRegisterVideoCapabilitiesOnly() {
-        setUpBackwardsCompatTest()
         mCallsManager.registerAppWithTelecom(CallsManager.CAPABILITY_SUPPORTS_VIDEO_CALLING)
 
         val phoneAccount = mCallsManager.getBuiltPhoneAccount()!!
@@ -182,7 +189,6 @@
     @SmallTest
     @Test
     fun testAddOutgoingVideoCall_CallEndpointShouldBeSpeaker_Transactional() {
-        setUpV2Test()
         runBlocking { assertVideoCallStartsWithSpeakerEndpoint() }
     }
 
@@ -204,7 +210,6 @@
     @SmallTest
     @Test
     fun testPauseExecutionOrThrow_Transactional() {
-        setUpV2Test()
         runBlocking {
             val cd = CompletableDeferred<AddCallResult>()
             cd.complete(AddCallResult.SuccessCallSession())
@@ -237,7 +242,6 @@
     @SmallTest
     @Test
     fun testEndToEndSelectingAStartingEndpointTransactional() {
-        setUpV2Test()
         runBlocking { assertStartingCallEndpoint(coroutineContext) }
     }
 
@@ -249,6 +253,173 @@
         runBlocking { assertStartingCallEndpoint(coroutineContext) }
     }
 
+    @SdkSuppress(minSdkVersion = VERSION_CODES.UPSIDE_DOWN_CAKE)
+    @SmallTest
+    @Test
+    fun testRegister_default_onModernSdk_usesModernPath() {
+        setTestBuildVersion(VERSION_CODES.UPSIDE_DOWN_CAKE) // SDK 34
+
+        // Use default parameter for backwardsCompatSdkLevel (33)
+        mCallsManager.registerAppWithTelecom(CallsManager.CAPABILITY_BASELINE)
+
+        val account = mCallsManager.getBuiltPhoneAccount()!!
+        val handle = mCallsManager.getPhoneAccountHandleForPackage()
+
+        // Should use modern path
+        assertEquals(VERSION_CODES.TIRAMISU, CallsManager.mBackwardsCompatUpperBound)
+        assertTrue(account.hasCapabilities(CAPABILITY_SUPPORTS_TRANSACTIONAL_OPERATIONS))
+        assertEquals(mContext.packageName, handle.componentName.className)
+    }
+
+    @SdkSuppress(minSdkVersion = VERSION_CODES.TIRAMISU)
+    @SmallTest
+    @Test
+    fun testRegister_default_onLegacySdk_usesLegacyPath() {
+        setTestBuildVersion(VERSION_CODES.TIRAMISU) // SDK 33
+
+        mCallsManager.registerAppWithTelecom(CallsManager.CAPABILITY_BASELINE)
+
+        val account = mCallsManager.getBuiltPhoneAccount()!!
+        val handle = mCallsManager.getPhoneAccountHandleForPackage()
+
+        // Should use legacy path
+        assertEquals(VERSION_CODES.TIRAMISU, CallsManager.mBackwardsCompatUpperBound)
+        assertFalse(account.hasCapabilities(CAPABILITY_SUPPORTS_TRANSACTIONAL_OPERATIONS))
+        assertEquals(CallsManager.CONNECTION_SERVICE_CLASS, handle.componentName.className)
+    }
+
+    @SdkSuppress(minSdkVersion = VERSION_CODES.UPSIDE_DOWN_CAKE)
+    @SmallTest
+    @Test
+    fun testRegister_override_forceLegacyPathOnModernSdk() {
+        setTestBuildVersion(35) // VanillaIceCream
+
+        // Force legacy path by setting the upper bound to the current SDK
+        mCallsManager.registerAppWithTelecom(
+            CallsManager.CAPABILITY_BASELINE,
+            backwardsCompatSdkLevel = 35,
+        )
+
+        val account = mCallsManager.getBuiltPhoneAccount()!!
+        val handle = mCallsManager.getPhoneAccountHandleForPackage()
+
+        // Should be forced to use legacy path
+        assertEquals(35, CallsManager.mBackwardsCompatUpperBound)
+        assertFalse(account.hasCapabilities(CAPABILITY_SUPPORTS_TRANSACTIONAL_OPERATIONS))
+        assertEquals(CallsManager.CONNECTION_SERVICE_CLASS, handle.componentName.className)
+    }
+
+    @SdkSuppress(minSdkVersion = VERSION_CODES.UPSIDE_DOWN_CAKE)
+    @SmallTest
+    @Test
+    fun testRegister_override_doesNotApplyOnNewerSdk() {
+        setTestBuildVersion(36) // Baklava
+
+        // Set the upper bound below the current SDK
+        mCallsManager.registerAppWithTelecom(
+            CallsManager.CAPABILITY_BASELINE,
+            backwardsCompatSdkLevel = 35,
+        )
+
+        val account = mCallsManager.getBuiltPhoneAccount()!!
+        val handle = mCallsManager.getPhoneAccountHandleForPackage()
+
+        // Should revert to modern path because current SDK (36) is > bound (35)
+        assertEquals(35, CallsManager.mBackwardsCompatUpperBound)
+        assertTrue(account.hasCapabilities(CAPABILITY_SUPPORTS_TRANSACTIONAL_OPERATIONS))
+        assertEquals(mContext.packageName, handle.componentName.className)
+    }
+
+    @SdkSuppress(minSdkVersion = VERSION_CODES.UPSIDE_DOWN_CAKE)
+    @SmallTest
+    @Test
+    fun testRegister_override_clampsValueTooHigh() {
+        setTestBuildVersion(35) // VanillaIceCream
+
+        // Pass an override value (40) that is higher than the current SDK (35)
+        mCallsManager.registerAppWithTelecom(
+            CallsManager.CAPABILITY_BASELINE,
+            backwardsCompatSdkLevel = 40,
+        )
+
+        val account = mCallsManager.getBuiltPhoneAccount()!!
+        val handle = mCallsManager.getPhoneAccountHandleForPackage()
+
+        // The value should be clamped to 35, forcing the legacy path
+        assertEquals(35, CallsManager.mBackwardsCompatUpperBound)
+        assertFalse(account.hasCapabilities(CAPABILITY_SUPPORTS_TRANSACTIONAL_OPERATIONS))
+        assertEquals(CallsManager.CONNECTION_SERVICE_CLASS, handle.componentName.className)
+    }
+
+    @SdkSuppress(minSdkVersion = VERSION_CODES.UPSIDE_DOWN_CAKE)
+    @SmallTest
+    @Test
+    fun testRegister_override_clampsValueTooLow() {
+        setTestBuildVersion(VERSION_CODES.UPSIDE_DOWN_CAKE) // SDK 34
+
+        // Pass an override value (32) lower than the minimum (33)
+        mCallsManager.registerAppWithTelecom(
+            CallsManager.CAPABILITY_BASELINE,
+            backwardsCompatSdkLevel = 32,
+        )
+
+        val account = mCallsManager.getBuiltPhoneAccount()!!
+        val handle = mCallsManager.getPhoneAccountHandleForPackage()
+
+        // The value is clamped to 33. Since current SDK (34) > 33, it should use the modern path.
+        assertEquals(VERSION_CODES.TIRAMISU, CallsManager.mBackwardsCompatUpperBound)
+        assertTrue(
+            account.hasCapabilities(PhoneAccount.CAPABILITY_SUPPORTS_TRANSACTIONAL_OPERATIONS)
+        )
+        assertEquals(mContext.packageName, handle.componentName.className)
+    }
+
+    @SdkSuppress(minSdkVersion = VERSION_CODES.UPSIDE_DOWN_CAKE)
+    @SmallTest
+    @Test
+    fun testRegister_reRegistration_updatesImplementationPath() {
+        setTestBuildVersion(35) // SDK 35
+
+        // Step 1: Register with default (modern path)
+        mCallsManager.registerAppWithTelecom(CallsManager.CAPABILITY_BASELINE)
+
+        var account = mCallsManager.getBuiltPhoneAccount()!!
+        var handle = mCallsManager.getPhoneAccountHandleForPackage()
+
+        // Verify modern path
+        assertEquals(33, CallsManager.mBackwardsCompatUpperBound)
+        assertTrue(account.hasCapabilities(CAPABILITY_SUPPORTS_TRANSACTIONAL_OPERATIONS))
+        assertEquals(mTestClassName, handle.componentName.className)
+
+        // Step 2: Re-register, forcing legacy path
+        mCallsManager.registerAppWithTelecom(
+            CallsManager.CAPABILITY_BASELINE,
+            backwardsCompatSdkLevel = 35,
+        )
+
+        account = mCallsManager.getBuiltPhoneAccount()!!
+        handle = mCallsManager.getPhoneAccountHandleForPackage()
+
+        // Verify legacy path
+        assertEquals(35, CallsManager.mBackwardsCompatUpperBound)
+        assertFalse(account.hasCapabilities(CAPABILITY_SUPPORTS_TRANSACTIONAL_OPERATIONS))
+        assertEquals(CallsManager.CONNECTION_SERVICE_CLASS, handle.componentName.className)
+
+        // Step 3: Re-register, reverting to modern path
+        mCallsManager.registerAppWithTelecom(
+            CallsManager.CAPABILITY_BASELINE,
+            backwardsCompatSdkLevel = 33, // Default
+        )
+
+        account = mCallsManager.getBuiltPhoneAccount()!!
+        handle = mCallsManager.getPhoneAccountHandleForPackage()
+
+        // Verify modern path again
+        assertEquals(33, CallsManager.mBackwardsCompatUpperBound)
+        assertTrue(account.hasCapabilities(CAPABILITY_SUPPORTS_TRANSACTIONAL_OPERATIONS))
+        assertEquals(mTestClassName, handle.componentName.className)
+    }
+
     private suspend fun assertStartingCallEndpoint(coroutineContext: CoroutineContext) {
         mCallsManager.registerAppWithTelecom(
             CallsManager.CAPABILITY_SUPPORTS_VIDEO_CALLING or
@@ -376,4 +547,14 @@
             }
         }
     }
+
+    private fun setTestBuildVersion(sdk: Int) {
+        val testAdapter =
+            object : BuildVersionAdapter {
+                override fun hasInvalidBuildVersion(): Boolean = sdk < VERSION_CODES.O
+
+                override fun getCurrentSdk(): Int = sdk
+            }
+        Utils.setUtils(testAdapter)
+    }
 }
diff --git a/core/core-telecom/src/androidTest/java/androidx/core/telecom/test/E2ECallExtensionExtrasTests.kt b/core/core-telecom/src/androidTest/java/androidx/core/telecom/test/E2ECallExtensionExtrasTests.kt
index a6c76c0..6f14b2bf 100644
--- a/core/core-telecom/src/androidTest/java/androidx/core/telecom/test/E2ECallExtensionExtrasTests.kt
+++ b/core/core-telecom/src/androidTest/java/androidx/core/telecom/test/E2ECallExtensionExtrasTests.kt
@@ -95,7 +95,6 @@
     @LargeTest
     @Test(timeout = 10000)
     fun testCapabilityExchangeIncoming_V2() {
-        setUpV2Test()
         addAndVerifyCallExtensionTypeE2E(TestUtils.INCOMING_CALL_ATTRIBUTES)
     }
 
@@ -108,7 +107,6 @@
     @LargeTest
     @Test(timeout = 10000)
     fun testCapabilityExchangeOutgoing_V2() {
-        setUpV2Test()
         addAndVerifyCallExtensionTypeE2E(TestUtils.OUTGOING_CALL_ATTRIBUTES)
     }
 
@@ -183,7 +181,7 @@
         // Assert the specifics of the extensions are correct. Note, resolveCallExtensionsType also
         // internally assures the details are set properly
         val callDetails = call.details!!
-        if (Utils.hasPlatformV2Apis()) {
+        if (!Utils.shouldUseBackwardsCompatImplementation()) {
             if (TestUtils.buildIsAtLeastV()) {
                 assertTrue(callDetails.hasProperty(CallsManager.PROPERTY_IS_TRANSACTIONAL))
             }
diff --git a/core/core-telecom/src/androidTest/java/androidx/core/telecom/test/E2EExtensionTests.kt b/core/core-telecom/src/androidTest/java/androidx/core/telecom/test/E2EExtensionTests.kt
index 5498987..7efbedb 100644
--- a/core/core-telecom/src/androidTest/java/androidx/core/telecom/test/E2EExtensionTests.kt
+++ b/core/core-telecom/src/androidTest/java/androidx/core/telecom/test/E2EExtensionTests.kt
@@ -28,6 +28,7 @@
 import android.util.Log
 import androidx.core.telecom.CallAttributesCompat
 import androidx.core.telecom.CallControlResult
+import androidx.core.telecom.CallsManager.Companion.CAPABILITY_BASELINE
 import androidx.core.telecom.InCallServiceCompat
 import androidx.core.telecom.extensions.CallExtensionScope
 import androidx.core.telecom.extensions.CallIconExtensionImpl
@@ -710,8 +711,15 @@
             )
         }
         when (parameters.serviceSource) {
-            SERVICE_SOURCE_V2 -> setUpV2Test()
-            SERVICE_SOURCE_CONNSRV -> setUpBackwardsCompatTest()
+            SERVICE_SOURCE_V2 -> {
+                Log.i(L_TAG, "setupParameterizedTest: [V2] APIs")
+                mCallsManager.registerAppWithTelecom(CAPABILITY_BASELINE)
+                logTelecomState()
+            }
+            SERVICE_SOURCE_CONNSRV -> {
+                Log.i(L_TAG, "setupParameterizedTest: [ConnectionService] APIs")
+                setUpBackwardsCompatTest()
+            }
         }
     }
 
diff --git a/core/core-telecom/src/androidTest/java/androidx/core/telecom/test/InCallAudioTest.kt b/core/core-telecom/src/androidTest/java/androidx/core/telecom/test/InCallAudioTest.kt
index 41c4aff..b3fa2d17 100644
--- a/core/core-telecom/src/androidTest/java/androidx/core/telecom/test/InCallAudioTest.kt
+++ b/core/core-telecom/src/androidTest/java/androidx/core/telecom/test/InCallAudioTest.kt
@@ -77,7 +77,6 @@
     @LargeTest
     @Test(timeout = 10000)
     fun testAddCallAssertModeInCommunication() {
-        setUpV2Test()
         runBlocking_addCall_assertAudioModeInCommunication()
     }
 
diff --git a/core/core-telecom/src/androidTest/java/androidx/core/telecom/test/utils/BaseTelecomTest.kt b/core/core-telecom/src/androidTest/java/androidx/core/telecom/test/utils/BaseTelecomTest.kt
index 772496c..a9ad4b8 100644
--- a/core/core-telecom/src/androidTest/java/androidx/core/telecom/test/utils/BaseTelecomTest.kt
+++ b/core/core-telecom/src/androidTest/java/androidx/core/telecom/test/utils/BaseTelecomTest.kt
@@ -51,6 +51,7 @@
 import kotlinx.coroutines.withTimeout
 import org.junit.After
 import org.junit.Assert
+import org.junit.Assert.assertFalse
 import org.junit.Assume
 import org.junit.Before
 import org.junit.Rule
@@ -105,17 +106,13 @@
         CallEndpointUuidTracker.endSession(mBaseSessionId)
     }
 
-    fun setUpV2Test() {
-        Log.i(L_TAG, "setUpV2Test: core-telecom w/ [V2] APIs")
-        Utils.setUtils(TestUtils.mV2Build)
-        mCallsManager.registerAppWithTelecom(CallsManager.CAPABILITY_SUPPORTS_VIDEO_CALLING)
-        logTelecomState()
-    }
-
+    /** NOTE: This should only be called on test devices running Oreo(26)+ */
     fun setUpBackwardsCompatTest() {
         Log.i(L_TAG, "setUpBackwardsCompatTest: core-telecom w/ [ConnectionService] APIs")
-        Utils.setUtils(TestUtils.mBackwardsCompatBuild)
-        mCallsManager.registerAppWithTelecom(CallsManager.CAPABILITY_SUPPORTS_VIDEO_CALLING)
+        mCallsManager.registerAppWithTelecom(
+            capabilities = CallsManager.CAPABILITY_SUPPORTS_VIDEO_CALLING,
+            backwardsCompatSdkLevel = Utils.getCurrentSdk(), /*override up to the DUTs currentSdk*/
+        )
         logTelecomState()
     }
 
@@ -164,7 +161,7 @@
         }
     }
 
-    private fun logTelecomState() {
+    fun logTelecomState() {
         val telecomDumpsysString = TestUtils.runShellCommand(TestUtils.COMMAND_DUMP_TELECOM)
         val isInCallXmCallsDump = isInCallFromTelDumpsys(telecomDumpsysString)
 
diff --git a/core/core-telecom/src/androidTest/java/androidx/core/telecom/test/utils/TestUtils.kt b/core/core-telecom/src/androidTest/java/androidx/core/telecom/test/utils/TestUtils.kt
index bb5b112..d415d20 100644
--- a/core/core-telecom/src/androidTest/java/androidx/core/telecom/test/utils/TestUtils.kt
+++ b/core/core-telecom/src/androidTest/java/androidx/core/telecom/test/utils/TestUtils.kt
@@ -34,7 +34,6 @@
 import androidx.core.telecom.extensions.Participant
 import androidx.core.telecom.extensions.ParticipantParcelable
 import androidx.core.telecom.extensions.toParticipant
-import androidx.core.telecom.internal.utils.BuildVersionAdapter
 import androidx.core.telecom.test.ITestAppControlCallback
 import androidx.core.telecom.util.ExperimentalAppActions
 import androidx.test.platform.app.InstrumentationRegistry
@@ -115,48 +114,6 @@
             ALL_CALL_CAPABILITIES,
         )
 
-    /**
-     * This build version should be set when the **V2 transactional APIs** are desired as the
-     * underlying call management.
-     */
-    internal val mV2Build =
-        object : BuildVersionAdapter {
-            override fun hasPlatformV2Apis(): Boolean {
-                return true
-            }
-
-            override fun hasInvalidBuildVersion(): Boolean {
-                return false
-            }
-        }
-
-    /**
-     * This build version should be set when the **ConnectionService and Connection APIs** are
-     * desired as the underlying call management.
-     */
-    internal val mBackwardsCompatBuild =
-        object : BuildVersionAdapter {
-            override fun hasPlatformV2Apis(): Boolean {
-                return false
-            }
-
-            override fun hasInvalidBuildVersion(): Boolean {
-                return false
-            }
-        }
-
-    /** This build version should be set when edge case testing on invalid builds */
-    internal val mInvalidBuild =
-        object : BuildVersionAdapter {
-            override fun hasPlatformV2Apis(): Boolean {
-                return false
-            }
-
-            override fun hasInvalidBuildVersion(): Boolean {
-                return true
-            }
-        }
-
     val mOnSetActiveLambda: suspend () -> Unit = {
         Log.i(LOG_TAG, "onSetActive: completing")
         mOnSetActiveCallbackCalled = true
diff --git a/core/core-telecom/src/main/java/androidx/core/telecom/CallsManager.kt b/core/core-telecom/src/main/java/androidx/core/telecom/CallsManager.kt
index a0efa26..c29aeb0 100644
--- a/core/core-telecom/src/main/java/androidx/core/telecom/CallsManager.kt
+++ b/core/core-telecom/src/main/java/androidx/core/telecom/CallsManager.kt
@@ -172,29 +172,68 @@
         internal const val ADD_CALL_TIMEOUT = 5000L
         internal const val SWITCH_TO_SPEAKER_TIMEOUT = 1000L
         private val TAG: String = CallsManager::class.java.simpleName.toString()
+
+        /**
+         * Stores the effective upper SDK bound for forcing the legacy implementation. This value is
+         * calculated and set during [registerAppWithTelecom].
+         */
+        @Volatile internal var mBackwardsCompatUpperBound: Int = VERSION_CODES.TIRAMISU // 33
     }
 
     /**
-     * VoIP applications should look at each [Capability] annotated above and call this API in order
-     * to start adding calls via [addCall]. Registering capabilities must be done before calling
-     * [addCall] or an exception will be thrown by [addCall]. The capabilities can be updated by
-     * re-registering.
+     * Registers the application with the Telecom framework.
      *
-     * Note: There is no need to unregister at any point. Telecom will handle unregistering once the
-     * application using core-telecom has been removed from the device.
+     * VoIP applications should call this API during application setup to register their
+     * capabilities (e.g., video) before adding calls via [addCall].The library automatically
+     * handles unregistering any previous configuration.
+     *
+     * **Note:** This method should not be called while there are active calls, as it may cause
+     * unexpected behavior or call disconnection.
+     *
+     * Core-telecom abstracts two platform implementations: the legacy `ConnectionService` APIs and
+     * the modern transactional APIs (introduced in SDK 34). The `backwardsCompatSdkLevel` parameter
+     * allows you to control which implementation is used.
+     *
+     * @param capabilities The set of capabilities your application supports, such as
+     *   [CAPABILITY_SUPPORTS_VIDEO_CALLING].
+     * @param backwardsCompatSdkLevel Sets the highest SDK version (inclusive) that should be forced
+     *   to use the legacy `ConnectionService` implementation.
+     * - **Default:** `VERSION_CODES.TIRAMISU` (33). This default ensures that all devices on SDK 34
+     *   and higher will use the modern transactional APIs.
+     * - **Behavior:** This parameter provides developers with the flexibility to prefer the
+     *   behavior of the legacy implementation on specific OS versions.
+     * - **Clamping:** The provided value is automatically clamped to a safe range: it cannot be
+     *   lower than `33` or higher than the current device's SDK version. For example, to force the
+     *   legacy path on a device running SDK 35, you would pass in `35`. Passing in `40` on an SDK
+     *   35 device would be clamped to `35`.
      *
      * @throws UnsupportedOperationException if the device is on an invalid build
      */
     @RequiresPermission(value = "android.permission.MANAGE_OWN_CALLS")
-    public fun registerAppWithTelecom(@Capability capabilities: Int) {
+    @JvmOverloads
+    public fun registerAppWithTelecom(
+        @Capability capabilities: Int,
+        backwardsCompatSdkLevel: Int = VERSION_CODES.TIRAMISU,
+    ) {
         // verify the build version supports this API and throw an exception if not
         Utils.verifyBuildVersion()
 
+        // unregister any old PhoneAccountHandle from this application because the
+        // handle can change based on the backwardsCompatSdkLevel value.
+        mTelecomManager.unregisterPhoneAccount(getPhoneAccountHandleForPackage())
+
+        setBackwardsCompatSdkUpperBound(backwardsCompatSdkLevel)
+
         val phoneAccountBuilder =
             PhoneAccount.builder(getPhoneAccountHandleForPackage(), PACKAGE_LABEL)
 
         // remap and set capabilities
-        phoneAccountBuilder.setCapabilities(remapJetpackCapsToPlatformCaps(capabilities))
+        phoneAccountBuilder.setCapabilities(
+            remapJetpackCapsToPlatformCaps(
+                clientBitmapSelection = capabilities,
+                useTransactionalApis = !Utils.shouldUseBackwardsCompatImplementation(),
+            )
+        )
         // see b/343674176. Some OEMs expect the PhoneAccount.getExtras() to be non-null
         // see b/352526256. The bundle must contain a placeholder value. otherwise, the bundle
         // empty bundle will be nulled out on reboot.
@@ -207,6 +246,17 @@
         mTelecomManager.registerPhoneAccount(mPhoneAccount)
     }
 
+    internal fun setBackwardsCompatSdkUpperBound(clientRequestedSdkLevel: Int) {
+        // Calculate the effective SDK level by clamping the input to a valid range.
+        val effectiveSdkLevel =
+            clientRequestedSdkLevel
+                .coerceAtMost(Utils.getCurrentSdk()) // upper is latest sdk released
+                .coerceAtLeast(VERSION_CODES.TIRAMISU) // DO NOT CHANGE. Allowing
+        // clients to set the upperbound to a below TIRAMISU like S_V2 would mean the library
+        // could use the transactional path when the APIs would not exist.
+        mBackwardsCompatUpperBound = effectiveSdkLevel
+    }
+
     /**
      * Adds a new call with the specified [CallAttributesCompat] to the telecom service. This method
      * can be used to add both incoming and outgoing calls. Once the call is ready to be
@@ -449,7 +499,7 @@
         // create a call session based off the build version
         @Suppress("WRONG_ANNOTATION_TARGET") // b/407926117
         @RequiresApi(34)
-        if (Utils.hasPlatformV2Apis()) {
+        if (!Utils.shouldUseBackwardsCompatImplementation()) {
             // CompletableDeferred pauses the execution of this method until the CallControl is
             // returned by the Platform.
             val openResult = CompletableDeferred<AddCallResult>(parent = coroutineContext.job)
@@ -613,10 +663,10 @@
         Utils.verifyBuildVersion()
 
         val className =
-            if (Utils.hasPlatformV2Apis()) {
-                mContext.packageName
-            } else {
+            if (Utils.shouldUseBackwardsCompatImplementation()) {
                 CONNECTION_SERVICE_CLASS
+            } else {
+                mContext.packageName
             }
         return PhoneAccountHandle(
             ComponentName(mContext.packageName, className),
diff --git a/core/core-telecom/src/main/java/androidx/core/telecom/extensions/CallExtensionScopeImpl.kt b/core/core-telecom/src/main/java/androidx/core/telecom/extensions/CallExtensionScopeImpl.kt
index 73dda1fc..0c030c0 100644
--- a/core/core-telecom/src/main/java/androidx/core/telecom/extensions/CallExtensionScopeImpl.kt
+++ b/core/core-telecom/src/main/java/androidx/core/telecom/extensions/CallExtensionScopeImpl.kt
@@ -283,7 +283,7 @@
     internal suspend fun resolveCallExtensionsType(): Int {
         var details = call.details
         var type = NONE
-        if (Utils.hasPlatformV2Apis()) {
+        if (!Utils.shouldUseBackwardsCompatImplementation()) {
             // Android CallsManager V+ check
             if (details.hasProperty(CallsManager.PROPERTY_IS_TRANSACTIONAL)) {
                 Log.d(TAG, "resolveCallExtensionsType: PROPERTY_IS_TRANSACTIONAL present")
@@ -396,7 +396,7 @@
      * does not support extensions at all.
      */
     private suspend fun performExchangeWithRemote(): CapabilityExchangeResult? {
-        if (Utils.hasPlatformV2Apis()) {
+        if (!Utils.shouldUseBackwardsCompatImplementation()) {
             Log.d(TAG, "performExchangeWithRemote: waiting for call ready signal...")
             withTimeoutOrNull(CALL_READY_TIMEOUT_MS) {
                 // On Android U/V, we must wait for the jetpack lib to send a call ready event to
diff --git a/core/core-telecom/src/main/java/androidx/core/telecom/internal/utils/BuildVersionAdapter.kt b/core/core-telecom/src/main/java/androidx/core/telecom/internal/utils/BuildVersionAdapter.kt
index 2b93899..cf5fcee 100644
--- a/core/core-telecom/src/main/java/androidx/core/telecom/internal/utils/BuildVersionAdapter.kt
+++ b/core/core-telecom/src/main/java/androidx/core/telecom/internal/utils/BuildVersionAdapter.kt
@@ -17,7 +17,7 @@
 package androidx.core.telecom.internal.utils
 
 internal interface BuildVersionAdapter {
-    fun hasPlatformV2Apis(): Boolean
-
     fun hasInvalidBuildVersion(): Boolean
+
+    fun getCurrentSdk(): Int
 }
diff --git a/core/core-telecom/src/main/java/androidx/core/telecom/internal/utils/Utils.kt b/core/core-telecom/src/main/java/androidx/core/telecom/internal/utils/Utils.kt
index cea7f45..79ad1c9 100644
--- a/core/core-telecom/src/main/java/androidx/core/telecom/internal/utils/Utils.kt
+++ b/core/core-telecom/src/main/java/androidx/core/telecom/internal/utils/Utils.kt
@@ -36,21 +36,14 @@
 
         private val defaultBuildAdapter =
             object : BuildVersionAdapter {
-                /**
-                 * Helper method that determines if the device has a build that contains the Telecom
-                 * V2 VoIP APIs. These include [TelecomManager#addCall],
-                 * android.telecom.CallControl, android.telecom.CallEventCallback but are not
-                 * limited to only those classes.
-                 */
-                override fun hasPlatformV2Apis(): Boolean {
-                    Log.i(TAG, "hasPlatformV2Apis: " + "versionSdkInt=[${VERSION.SDK_INT}]")
-                    return VERSION.SDK_INT >= 34 || VERSION.CODENAME == "UpsideDownCake"
-                }
-
                 override fun hasInvalidBuildVersion(): Boolean {
                     Log.i(TAG, "hasInvalidBuildVersion: " + "versionSdkInt=[${VERSION.SDK_INT}]")
                     return VERSION.SDK_INT < VERSION_CODES.O
                 }
+
+                override fun getCurrentSdk(): Int {
+                    return VERSION.SDK_INT
+                }
             }
         private var mBuildVersion: BuildVersionAdapter = defaultBuildAdapter
 
@@ -62,14 +55,23 @@
             mBuildVersion = defaultBuildAdapter
         }
 
-        fun hasPlatformV2Apis(): Boolean {
-            return mBuildVersion.hasPlatformV2Apis()
+        /**
+         * Determines if the library should use the legacy ConnectionService path based on the
+         * configuration set during [CallsManager.registerAppWithTelecom].
+         */
+        @RequiresApi(VERSION_CODES.O)
+        fun shouldUseBackwardsCompatImplementation(): Boolean {
+            return getCurrentSdk() <= CallsManager.mBackwardsCompatUpperBound
         }
 
         fun hasInvalidBuildVersion(): Boolean {
             return mBuildVersion.hasInvalidBuildVersion()
         }
 
+        fun getCurrentSdk(): Int {
+            return mBuildVersion.getCurrentSdk()
+        }
+
         fun verifyBuildVersion() {
             if (mBuildVersion.hasInvalidBuildVersion()) {
                 throw UnsupportedOperationException(
@@ -113,17 +115,17 @@
 
         @RequiresApi(VERSION_CODES.O)
         fun remapJetpackCapsToPlatformCaps(
-            @CallsManager.Companion.Capability clientBitmapSelection: Int
+            @CallsManager.Companion.Capability clientBitmapSelection: Int,
+            useTransactionalApis: Boolean,
         ): Int {
             // start to build the PhoneAccount that will be registered via the platform API
             var platformCapabilities: Int = PhoneAccount.CAPABILITY_SELF_MANAGED
-            // append additional capabilities if the device is on a U build or above
-            if (hasPlatformV2Apis()) {
+            // Add transactional capabilities ONLY if not using the backwards compat path.
+            if (useTransactionalApis) {
                 platformCapabilities =
                     PhoneAccount.CAPABILITY_SUPPORTS_TRANSACTIONAL_OPERATIONS or
                         platformCapabilities
             }
-
             if (hasJetpackVideoCallingCapability(clientBitmapSelection)) {
                 platformCapabilities =
                     PhoneAccount.CAPABILITY_VIDEO_CALLING or
diff --git a/datastore/datastore-core/build.gradle b/datastore/datastore-core/build.gradle
index 885d869a..ceb0739 100644
--- a/datastore/datastore-core/build.gradle
+++ b/datastore/datastore-core/build.gradle
@@ -157,7 +157,7 @@
             dependsOn(jvmAndroidTest)
         }
 
-        androidUnitTest {
+        androidHostTest {
             dependsOn(jvmAndroidTest)
             dependsOn(androidUnitAndInstrumentedTest)
             dependencies {
diff --git a/datastore/datastore-preferences/build.gradle b/datastore/datastore-preferences/build.gradle
index 1c8a3b8..80e7fad 100644
--- a/datastore/datastore-preferences/build.gradle
+++ b/datastore/datastore-preferences/build.gradle
@@ -77,7 +77,7 @@
         androidMain {
             dependsOn(commonJvmMain)
         }
-        androidUnitTest {
+        androidHostTest {
             dependsOn(commonJvmTest)
         }
         androidInstrumentedTest {
diff --git a/docs/api_guidelines/modules.md b/docs/api_guidelines/modules.md
index 64fe2a9..a23646e 100644
--- a/docs/api_guidelines/modules.md
+++ b/docs/api_guidelines/modules.md
@@ -324,14 +324,14 @@
 ### Choosing a `minSdkVersion` {#module-minsdkversion}
 
 The recommended minimum SDK version for new Jetpack libraries is currently
-**23** (Android 6.0, Marshmallow). This SDK was chosen to represent 99% of
-active devices based on Play Store check-ins (see Android Studio
+**24** (Android 7.0, Nougat). This SDK was chosen to represent 99% of active
+devices based on Play Store check-ins (see Android Studio
 [distribution metadata](https://dl.google.com/android/studio/metadata/distributions.json)
 for current statistics). This maximizes potential users for external developers
 while minimizing the amount of overhead necessary to support legacy versions.
 
 However, if no explicit minimum SDK version is specified for a library, the
-default is **21** (Android 5.0, Lollipop).
+default is **23** (Android 6.0, Marshmallow).
 
 Note that a library **must not** depend on another library with a higher
 `minSdkVersion` that its own, so it may be necessary for a new library to match
diff --git a/glance/wear/wear-core/api/current.txt b/glance/wear/wear-core/api/current.txt
index e6f50d0..15b7c56 100644
--- a/glance/wear/wear-core/api/current.txt
+++ b/glance/wear/wear-core/api/current.txt
@@ -1 +1,65 @@
 // Signature format: 4.0
+package androidx.glance.wear {
+
+  public final class ContainerInfo {
+    method @InaccessibleFromKotlin public String? getDescription();
+    method @InaccessibleFromKotlin public String? getLabel();
+    method @InaccessibleFromKotlin public int getPreviewImage();
+    method @InaccessibleFromKotlin public int getType();
+    property public String? description;
+    property public String? label;
+    property public int previewImage;
+    property public int type;
+    field public static final int CONTAINER_TYPE_FULLSCREEN = 0; // 0x0
+    field public static final int CONTAINER_TYPE_LARGE = 1; // 0x1
+    field public static final int CONTAINER_TYPE_SMALL = 2; // 0x2
+    field public static final androidx.glance.wear.ContainerInfo.Companion Companion;
+  }
+
+  public static final class ContainerInfo.Companion {
+    property public static int CONTAINER_TYPE_FULLSCREEN;
+    property public static int CONTAINER_TYPE_LARGE;
+    property public static int CONTAINER_TYPE_SMALL;
+  }
+
+  public final class SchemaVersion {
+    ctor public SchemaVersion(int major, int minor);
+    method @InaccessibleFromKotlin public int getMajor();
+    method @InaccessibleFromKotlin public int getMinor();
+    property public int major;
+    property public int minor;
+  }
+
+  public final class WearWidgetProviderInfo {
+    method @InaccessibleFromKotlin public String? getConfigIntentAction();
+    method @InaccessibleFromKotlin public java.util.List<androidx.glance.wear.ContainerInfo> getContainers();
+    method @InaccessibleFromKotlin public String getDescription();
+    method @InaccessibleFromKotlin public String getGroup();
+    method @InaccessibleFromKotlin public int getIcon();
+    method @InaccessibleFromKotlin public String getLabel();
+    method @InaccessibleFromKotlin public androidx.glance.wear.SchemaVersion? getMaxSchemaVersion();
+    method @InaccessibleFromKotlin public androidx.glance.wear.SchemaVersion? getMinSchemaVersion();
+    method @InaccessibleFromKotlin public int getPreferredContainerType();
+    method @InaccessibleFromKotlin public android.content.ComponentName getProviderService();
+    method @InaccessibleFromKotlin public boolean isMultiInstanceSupported();
+    method @kotlin.jvm.Throws(exceptionClasses=XmlPullParserException::class) public static androidx.glance.wear.WearWidgetProviderInfo parseFromService(android.content.Context context, android.content.ComponentName providerService) throws org.xmlpull.v1.XmlPullParserException;
+    property public String? configIntentAction;
+    property public java.util.List<androidx.glance.wear.ContainerInfo> containers;
+    property public String description;
+    property public String group;
+    property public int icon;
+    property public boolean isMultiInstanceSupported;
+    property public String label;
+    property public androidx.glance.wear.SchemaVersion? maxSchemaVersion;
+    property public androidx.glance.wear.SchemaVersion? minSchemaVersion;
+    property public int preferredContainerType;
+    property public android.content.ComponentName providerService;
+    field public static final androidx.glance.wear.WearWidgetProviderInfo.Companion Companion;
+  }
+
+  public static final class WearWidgetProviderInfo.Companion {
+    method @kotlin.jvm.Throws(exceptionClasses=XmlPullParserException::class) public androidx.glance.wear.WearWidgetProviderInfo parseFromService(android.content.Context context, android.content.ComponentName providerService) throws org.xmlpull.v1.XmlPullParserException;
+  }
+
+}
+
diff --git a/glance/wear/wear-core/api/restricted_current.txt b/glance/wear/wear-core/api/restricted_current.txt
index e6f50d0..15b7c56 100644
--- a/glance/wear/wear-core/api/restricted_current.txt
+++ b/glance/wear/wear-core/api/restricted_current.txt
@@ -1 +1,65 @@
 // Signature format: 4.0
+package androidx.glance.wear {
+
+  public final class ContainerInfo {
+    method @InaccessibleFromKotlin public String? getDescription();
+    method @InaccessibleFromKotlin public String? getLabel();
+    method @InaccessibleFromKotlin public int getPreviewImage();
+    method @InaccessibleFromKotlin public int getType();
+    property public String? description;
+    property public String? label;
+    property public int previewImage;
+    property public int type;
+    field public static final int CONTAINER_TYPE_FULLSCREEN = 0; // 0x0
+    field public static final int CONTAINER_TYPE_LARGE = 1; // 0x1
+    field public static final int CONTAINER_TYPE_SMALL = 2; // 0x2
+    field public static final androidx.glance.wear.ContainerInfo.Companion Companion;
+  }
+
+  public static final class ContainerInfo.Companion {
+    property public static int CONTAINER_TYPE_FULLSCREEN;
+    property public static int CONTAINER_TYPE_LARGE;
+    property public static int CONTAINER_TYPE_SMALL;
+  }
+
+  public final class SchemaVersion {
+    ctor public SchemaVersion(int major, int minor);
+    method @InaccessibleFromKotlin public int getMajor();
+    method @InaccessibleFromKotlin public int getMinor();
+    property public int major;
+    property public int minor;
+  }
+
+  public final class WearWidgetProviderInfo {
+    method @InaccessibleFromKotlin public String? getConfigIntentAction();
+    method @InaccessibleFromKotlin public java.util.List<androidx.glance.wear.ContainerInfo> getContainers();
+    method @InaccessibleFromKotlin public String getDescription();
+    method @InaccessibleFromKotlin public String getGroup();
+    method @InaccessibleFromKotlin public int getIcon();
+    method @InaccessibleFromKotlin public String getLabel();
+    method @InaccessibleFromKotlin public androidx.glance.wear.SchemaVersion? getMaxSchemaVersion();
+    method @InaccessibleFromKotlin public androidx.glance.wear.SchemaVersion? getMinSchemaVersion();
+    method @InaccessibleFromKotlin public int getPreferredContainerType();
+    method @InaccessibleFromKotlin public android.content.ComponentName getProviderService();
+    method @InaccessibleFromKotlin public boolean isMultiInstanceSupported();
+    method @kotlin.jvm.Throws(exceptionClasses=XmlPullParserException::class) public static androidx.glance.wear.WearWidgetProviderInfo parseFromService(android.content.Context context, android.content.ComponentName providerService) throws org.xmlpull.v1.XmlPullParserException;
+    property public String? configIntentAction;
+    property public java.util.List<androidx.glance.wear.ContainerInfo> containers;
+    property public String description;
+    property public String group;
+    property public int icon;
+    property public boolean isMultiInstanceSupported;
+    property public String label;
+    property public androidx.glance.wear.SchemaVersion? maxSchemaVersion;
+    property public androidx.glance.wear.SchemaVersion? minSchemaVersion;
+    property public int preferredContainerType;
+    property public android.content.ComponentName providerService;
+    field public static final androidx.glance.wear.WearWidgetProviderInfo.Companion Companion;
+  }
+
+  public static final class WearWidgetProviderInfo.Companion {
+    method @kotlin.jvm.Throws(exceptionClasses=XmlPullParserException::class) public androidx.glance.wear.WearWidgetProviderInfo parseFromService(android.content.Context context, android.content.ComponentName providerService) throws org.xmlpull.v1.XmlPullParserException;
+  }
+
+}
+
diff --git a/glance/wear/wear-core/build.gradle b/glance/wear/wear-core/build.gradle
index 641bb15..cf820cf 100644
--- a/glance/wear/wear-core/build.gradle
+++ b/glance/wear/wear-core/build.gradle
@@ -31,7 +31,13 @@
 
 dependencies {
     api(libs.kotlinStdlib)
-    // Add dependencies here
+    api("androidx.annotation:annotation:1.9.1")
+
+    testImplementation(libs.junit)
+    testImplementation(libs.mockitoKotlin4)
+    testImplementation(libs.testExtJunit)
+    testImplementation(libs.testRunner)
+    testImplementation(libs.truth)
 }
 
 android {
@@ -43,4 +49,5 @@
     type = SoftwareType.PUBLISHED_LIBRARY
     inceptionYear = "2025"
     description = "Core functionality for Glance Wear."
+    enableRobolectric()
 }
diff --git a/glance/wear/wear-core/src/main/java/androidx/glance/wear/WearWidgetProviderInfo.kt b/glance/wear/wear-core/src/main/java/androidx/glance/wear/WearWidgetProviderInfo.kt
new file mode 100644
index 0000000..e1c63e6
--- /dev/null
+++ b/glance/wear/wear-core/src/main/java/androidx/glance/wear/WearWidgetProviderInfo.kt
@@ -0,0 +1,208 @@
+/*
+ * Copyright 2025 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 androidx.glance.wear
+
+import android.content.ComponentName
+import android.content.Context
+import android.content.pm.PackageManager
+import androidx.annotation.DrawableRes
+import androidx.annotation.IntDef
+import androidx.annotation.RestrictTo
+import androidx.annotation.RestrictTo.Scope.LIBRARY
+import androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP
+import androidx.glance.wear.WearWidgetProviderInfoXmlParser.parseWearWidgetProviderInfo
+import java.util.Objects
+import org.xmlpull.v1.XmlPullParserException
+
+/**
+ * Describes the metadata for a Wear Widget provider.
+ *
+ * The fields in this class correspond to the fields in the `<wearwidget-provider>` xml tag.
+ *
+ * For example, the `AndroidManifest.xml` would contain:
+ * ```xml
+ * <service
+ *     android:name=".MyWidgetService"
+ *     android:exported="true">
+ *     <meta-data
+ *         android:name="androidx.glance.wear.widget.provider"
+ *         android:resource="@xml/my_widget_info" />
+ * </service>
+ * ```
+ *
+ * And `res/xml/my_widget_info.xml` would contain:
+ * ```xml
+ * <wearwidget-provider
+ *     label="@string/widget_label"
+ *     description="@string/widget_description"
+ *     icon="@drawable/widget_icon"
+ *     preferredType="@integer/glance_wear_container_type_small" >
+ *
+ *     <container
+ *         type="@integer/glance_wear_container_type_small"
+ *         previewImage="@drawable/small_preview"/>
+ *
+ *     <container
+ *         type="@integer/glance_wear_container_type_large"
+ *         previewImage="@drawable/large_preview"
+ *         label="@string/large_container_label_override" />
+ *
+ * </wearwidget-provider>
+ * ```
+ *
+ * @property providerService The [ComponentName] of this widget provider.
+ * @property label The label of this widget.
+ * @property description The description of this widget.
+ * @property icon The resource id of the icon for this widget.
+ * @property containers The list of [ContainerInfo] supported for this widget provider. Each element
+ *   represents a supported type.
+ * @property preferredContainerType The preferred Container Type to use for a widget instance when
+ *   type is not specified when adding a widget. This can be used when this provider is replacing a
+ *   legacy Wear Tile. This can be one of [ContainerInfo.CONTAINER_TYPE_LARGE] or
+ *   [ContainerInfo.CONTAINER_TYPE_SMALL].
+ * @property group The name of the group this widget provider is associated with. Defaults to the
+ *   fully qualified name of the provider service.
+ * @property isMultiInstanceSupported Whether this widget provider supports multiple instances.
+ * @property configIntentAction The intent action to launch an activity for configuring the widget
+ *   when [isMultiInstanceSupported] is set to true. This can be null if no configuration is needed.
+ * @property minSchemaVersion The minimum schema version supported by this widget provider.
+ * @property maxSchemaVersion The maximum schema version supported by this widget provider.
+ */
+// TODO: populate default min schema version for remote compose widgets.
+public class WearWidgetProviderInfo
+@RestrictTo(LIBRARY)
+public constructor(
+    public val providerService: ComponentName,
+    public val label: String,
+    public val description: String,
+    @DrawableRes public val icon: Int,
+    public val containers: List<ContainerInfo>,
+    @ContainerInfo.ContainerType public val preferredContainerType: Int,
+    public val group: String = providerService.className,
+    public val isMultiInstanceSupported: Boolean = false,
+    public val configIntentAction: String? = null,
+    public val minSchemaVersion: SchemaVersion? = null,
+    public val maxSchemaVersion: SchemaVersion? = null,
+) {
+    public companion object {
+        /** Name for the `meta-data` tag for the provider info. */
+        private const val META_DATA_WEAR_WIDGET_PROVIDER = "androidx.glance.wear.widget.provider"
+
+        /**
+         * Parses a [WearWidgetProviderInfo] from the metadata of a service.
+         *
+         * The metadata with name `androidx.glance.wear.widget.provider` should reference an XML
+         * resource with the provider info.
+         *
+         * @param context The [Context] to use for resolving resources and package manager.
+         * @param providerService The [ComponentName] of the widget provider service.
+         * @throws [PackageManager.NameNotFoundException] if the metadata is not found or the
+         *   resource is invalid.
+         * @throws [XmlPullParserException] if there is an error parsing the XML resource.
+         */
+        @Throws(XmlPullParserException::class)
+        @JvmStatic
+        public fun parseFromService(
+            context: Context,
+            providerService: ComponentName,
+        ): WearWidgetProviderInfo {
+            val serviceInfo =
+                context.packageManager.getServiceInfo(providerService, PackageManager.GET_META_DATA)
+            val xmlParser =
+                serviceInfo.loadXmlMetaData(context.packageManager, META_DATA_WEAR_WIDGET_PROVIDER)
+                    ?: throw PackageManager.NameNotFoundException(
+                        "Invalid meta-data name $META_DATA_WEAR_WIDGET_PROVIDER for service $providerService"
+                    )
+            return xmlParser.parseWearWidgetProviderInfo(
+                context.resources,
+                providerService,
+                defaultPreferredContainerType = ContainerInfo.CONTAINER_TYPE_SMALL,
+                defaultGroup = providerService.className,
+            )
+        }
+    }
+}
+
+/**
+ * Describes a container supported by a widget provider.
+ *
+ * A container is one representation of a widget, with a given size and shape.
+ *
+ * The fields in this class correspond to the fields in the `<container>` xml tag.
+ *
+ * For example:
+ * ```xml
+ * <container
+ *     android:type="@integer/glance_wear_container_type_large"
+ *     android:previewImage="@drawable/large_preview"
+ *     android:label="@string/large_label" />
+ * ```
+ *
+ * @property type The type of this widget container.
+ * @property previewImage The resource id of the preview image for this widget container.
+ * @property label The override label for this widget container.
+ * @property description The override description for this widget container.
+ */
+public class ContainerInfo
+@RestrictTo(LIBRARY)
+public constructor(
+    @ContainerType public val type: Int,
+    @DrawableRes public val previewImage: Int,
+    public val label: String? = null,
+    public val description: String? = null,
+) {
+    override fun equals(other: Any?): Boolean {
+        if (this === other) return true
+        if (other !is ContainerInfo) return false
+        return type == other.type &&
+            previewImage == other.previewImage &&
+            label == other.label &&
+            description == other.description
+    }
+
+    override fun hashCode(): Int {
+        return Objects.hash(type, previewImage, label, description)
+    }
+
+    /** The container type of a widget. It defines the size and shape of the container. */
+    @IntDef(CONTAINER_TYPE_FULLSCREEN, CONTAINER_TYPE_LARGE, CONTAINER_TYPE_SMALL)
+    @RestrictTo(LIBRARY_GROUP)
+    @Retention(AnnotationRetention.SOURCE)
+    public annotation class ContainerType
+
+    public companion object {
+        /** Represents a fullscreen widget container, equivalent to a Wear Tile. */
+        public const val CONTAINER_TYPE_FULLSCREEN: Int = 0
+
+        /**
+         * Represents a large widget container. Support for this container type is device dependent.
+         */
+        public const val CONTAINER_TYPE_LARGE: Int = 1
+        /**
+         * Represents a small widget container. Support for this container type is device dependent.
+         */
+        public const val CONTAINER_TYPE_SMALL: Int = 2
+    }
+}
+
+/**
+ * The schema version of the widget renderer.
+ *
+ * @property major The major version of the schema.
+ * @property minor The minor version of the schema.
+ */
+public class SchemaVersion(public val major: Int, public val minor: Int)
diff --git a/glance/wear/wear-core/src/main/java/androidx/glance/wear/WearWidgetProviderInfoXmlParser.kt b/glance/wear/wear-core/src/main/java/androidx/glance/wear/WearWidgetProviderInfoXmlParser.kt
new file mode 100644
index 0000000..297e47d
--- /dev/null
+++ b/glance/wear/wear-core/src/main/java/androidx/glance/wear/WearWidgetProviderInfoXmlParser.kt
@@ -0,0 +1,163 @@
+/*
+ * Copyright 2025 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 androidx.glance.wear
+
+import android.content.ComponentName
+import android.content.res.Resources
+import android.content.res.XmlResourceParser
+import org.xmlpull.v1.XmlPullParser
+import org.xmlpull.v1.XmlPullParserException
+
+internal object WearWidgetProviderInfoXmlParser {
+    private const val TAG_PROVIDER = "wearwidget-provider"
+    private const val TAG_CONTAINER = "container"
+    private const val ATTR_LABEL = "label"
+    private const val ATTR_DESCRIPTION = "description"
+    private const val ATTR_ICON = "icon"
+    private const val ATTR_PREFERRED_TYPE = "preferredType"
+    private const val ATTR_GROUP = "group"
+    private const val ATTR_IS_MULTI_INSTANCE_SUPPORTED = "isMultiInstanceSupported"
+    private const val ATTR_CONFIG_INTENT_ACTION = "configIntentAction"
+    private const val ATTR_MIN_SCHEMA_VERSION = "minSchemaVersion"
+    private const val ATTR_MAX_SCHEMA_VERSION = "maxSchemaVersion"
+    private const val ATTR_TYPE = "type"
+    private const val ATTR_PREVIEW_IMAGE = "previewImage"
+
+    private val NAMESPACE_DISABLED: String? = null
+
+    @Throws(XmlPullParserException::class)
+    internal fun XmlResourceParser.parseWearWidgetProviderInfo(
+        resources: Resources,
+        providerService: ComponentName,
+        @ContainerInfo.ContainerType defaultPreferredContainerType: Int,
+        defaultGroup: String,
+    ): WearWidgetProviderInfo {
+        while (this.next() != XmlPullParser.END_DOCUMENT) {
+            if (this.eventType == XmlPullParser.START_TAG && this.name == TAG_PROVIDER) {
+                return this.parseWearWidgetProviderTag(
+                    resources,
+                    providerService,
+                    defaultPreferredContainerType,
+                    defaultGroup,
+                )
+            }
+        }
+        throw XmlPullParserException("No <$TAG_PROVIDER> tag found in XML")
+    }
+
+    @Throws(XmlPullParserException::class)
+    internal fun XmlResourceParser.parseWearWidgetProviderTag(
+        resources: Resources,
+        providerService: ComponentName,
+        @ContainerInfo.ContainerType defaultPreferredContainerType: Int,
+        defaultGroup: String,
+    ): WearWidgetProviderInfo {
+        // TODO(b/429979908): handle string resources for label and description. This should be done
+        // similar to PackageItemInfo.loadLabel().
+        // TODO(b/429979908): If not present, take label, description and icon from service tag.
+        val label = getAttributeValue(NAMESPACE_DISABLED, ATTR_LABEL) ?: ""
+        val description = getAttributeValue(NAMESPACE_DISABLED, ATTR_DESCRIPTION) ?: ""
+        val icon = getAttributeResourceValue(NAMESPACE_DISABLED, ATTR_ICON, Resources.ID_NULL)
+        val preferredContainerType =
+            parseContainerTypeAttr(resources, ATTR_PREFERRED_TYPE, defaultPreferredContainerType)
+        val group = getAttributeValue(NAMESPACE_DISABLED, ATTR_GROUP) ?: defaultGroup
+        val isMultiInstanceSupported =
+            getAttributeBooleanValue(NAMESPACE_DISABLED, ATTR_IS_MULTI_INSTANCE_SUPPORTED, false)
+        val configIntentAction = getAttributeValue(NAMESPACE_DISABLED, ATTR_CONFIG_INTENT_ACTION)
+        val minSchemaVersion =
+            getAttributeValue(NAMESPACE_DISABLED, ATTR_MIN_SCHEMA_VERSION)?.let {
+                parseSchemaVersion(it)
+            }
+        val maxSchemaVersion =
+            getAttributeValue(NAMESPACE_DISABLED, ATTR_MAX_SCHEMA_VERSION)?.let {
+                parseSchemaVersion(it)
+            }
+
+        val containers = mutableListOf<ContainerInfo>()
+        val providerDepth = depth
+        while (next() != XmlPullParser.END_TAG || depth > providerDepth) {
+            if (eventType != XmlPullParser.START_TAG) {
+                continue
+            }
+            if (name == TAG_CONTAINER) {
+                containers.add(parseContainerInfo(resources))
+            }
+        }
+
+        return WearWidgetProviderInfo(
+            providerService = providerService,
+            label = label,
+            description = description,
+            icon = icon,
+            containers = containers,
+            preferredContainerType = preferredContainerType,
+            group = group,
+            isMultiInstanceSupported = isMultiInstanceSupported,
+            configIntentAction = configIntentAction,
+            minSchemaVersion = minSchemaVersion,
+            maxSchemaVersion = maxSchemaVersion,
+        )
+    }
+
+    @Throws(XmlPullParserException::class)
+    private fun XmlResourceParser.parseContainerInfo(resources: Resources): ContainerInfo {
+        val type = parseContainerTypeAttr(resources, ATTR_TYPE)
+        val previewImage =
+            getAttributeResourceValue(NAMESPACE_DISABLED, ATTR_PREVIEW_IMAGE, Resources.ID_NULL)
+        // TODO: handle string resources for label and description
+        val label = getAttributeValue(NAMESPACE_DISABLED, ATTR_LABEL)
+        val description = getAttributeValue(NAMESPACE_DISABLED, ATTR_DESCRIPTION)
+        return ContainerInfo(
+            type = type,
+            previewImage = previewImage,
+            label = label,
+            description = description,
+        )
+    }
+
+    internal fun parseSchemaVersion(value: String): SchemaVersion {
+        val parts = value.split('.')
+        if (parts.size != 2) {
+            throw IllegalArgumentException("Invalid schema version format: $value")
+        }
+        return try {
+            val minor = parts[1].padEnd(3, '0').toInt()
+            SchemaVersion(parts[0].toInt(), minor)
+        } catch (e: NumberFormatException) {
+            throw IllegalArgumentException("Invalid schema version format: $value", e)
+        }
+    }
+
+    @Throws(XmlPullParserException::class)
+    private fun XmlResourceParser.parseContainerTypeAttr(
+        resources: Resources,
+        attrName: String,
+        @ContainerInfo.ContainerType defaultValue: Int? = null,
+    ): Int {
+        val attrResId = getAttributeResourceValue(NAMESPACE_DISABLED, attrName, Resources.ID_NULL)
+        if (attrResId != Resources.ID_NULL) {
+            try {
+                return resources.getInteger(attrResId)
+            } catch (e: Resources.NotFoundException) {
+                throw XmlPullParserException("Invalid container type resource", this, e)
+            }
+        }
+        return getAttributeValue(NAMESPACE_DISABLED, attrName)?.toIntOrNull()
+            ?: defaultValue
+            ?: throw XmlPullParserException("Failed to parse Container Type for $attrName")
+    }
+}
diff --git a/glance/wear/wear-core/src/main/res/values/integers.xml b/glance/wear/wear-core/src/main/res/values/integers.xml
new file mode 100644
index 0000000..b36cc6f
--- /dev/null
+++ b/glance/wear/wear-core/src/main/res/values/integers.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright 2025 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.
+  -->
+
+<resources>
+    <!-- Integer representation of the large container type. -->
+    <integer name="glance_wear_container_type_large">1</integer>
+
+    <!-- Integer representation of the small container type. -->
+    <integer name="glance_wear_container_type_small">2</integer>
+</resources>
diff --git a/glance/wear/wear-core/src/test/AndroidManifest.xml b/glance/wear/wear-core/src/test/AndroidManifest.xml
new file mode 100644
index 0000000..1811ab5
--- /dev/null
+++ b/glance/wear/wear-core/src/test/AndroidManifest.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+  Copyright 2025 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.
+  -->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android">
+    <application>
+        <service android:name="androidx.glance.wear.test.TestGlanceWearWidgetServiceInvalidMetadata" >
+            <meta-data android:name="androidx.glance.wear.widget.provider"
+                android:value="17" />
+        </service>
+        <service android:name="androidx.glance.wear.test.TestGlanceWearWidgetServiceNoMetadata" />
+        <service android:name="androidx.glance.wear.test.TestGlanceWearWidgetService" >
+            <meta-data android:name="androidx.glance.wear.widget.provider"
+                android:resource="@xml/wear_widget_provider_info_test" />
+        </service>
+    </application>
+</manifest>
\ No newline at end of file
diff --git a/glance/wear/wear-core/src/test/java/androidx/glance/wear/WearWidgetProviderInfoTest.kt b/glance/wear/wear-core/src/test/java/androidx/glance/wear/WearWidgetProviderInfoTest.kt
new file mode 100644
index 0000000..45f78a5
--- /dev/null
+++ b/glance/wear/wear-core/src/test/java/androidx/glance/wear/WearWidgetProviderInfoTest.kt
@@ -0,0 +1,179 @@
+/*
+ * Copyright 2025 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 androidx.glance.wear
+
+import android.content.ComponentName
+import android.content.Context
+import android.content.pm.PackageManager
+import android.content.res.XmlResourceParser
+import androidx.glance.wear.WearWidgetProviderInfoXmlParser.parseWearWidgetProviderInfo
+import androidx.glance.wear.core.test.R
+import androidx.test.core.app.ApplicationProvider.getApplicationContext
+import com.google.common.truth.Truth.assertThat
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.robolectric.RobolectricTestRunner
+import org.xmlpull.v1.XmlPullParserException
+
+@RunWith(RobolectricTestRunner::class)
+class WearWidgetProviderInfoTest {
+    private val context: Context = getApplicationContext()
+    private val service = ComponentName(context, "test.class")
+
+    @Test
+    fun parseFromResource_parseProviderInfo() {
+        val info =
+            getXml(R.xml.wear_widget_provider_info_test)
+                .parseWearWidgetProviderInfo(
+                    context.resources,
+                    service,
+                    defaultPreferredContainerType = ContainerInfo.CONTAINER_TYPE_FULLSCREEN,
+                    defaultGroup = "default.group",
+                )
+        assertThat(info.providerService).isEqualTo(service)
+        assertThat(info.label).isEqualTo("test label")
+        assertThat(info.description).isEqualTo("test description")
+        assertThat(info.icon).isEqualTo(android.R.drawable.ic_delete)
+        assertThat(info.preferredContainerType).isEqualTo(ContainerInfo.CONTAINER_TYPE_SMALL)
+        assertThat(info.group).isEqualTo("test.group")
+        assertThat(info.isMultiInstanceSupported).isTrue()
+        assertThat(info.configIntentAction).isEqualTo("test.action")
+        assertThat(info.minSchemaVersion?.major).isEqualTo(1)
+        assertThat(info.minSchemaVersion?.minor).isEqualTo(200)
+        assertThat(info.maxSchemaVersion?.major).isEqualTo(2)
+        assertThat(info.maxSchemaVersion?.minor).isEqualTo(340)
+        assertThat(info.containers).hasSize(2)
+        assertThat(info.containers)
+            .containsExactlyElementsIn(
+                listOf(
+                    ContainerInfo(
+                        ContainerInfo.CONTAINER_TYPE_SMALL,
+                        android.R.drawable.ic_dialog_alert,
+                    ),
+                    ContainerInfo(
+                        ContainerInfo.CONTAINER_TYPE_LARGE,
+                        android.R.drawable.ic_dialog_dialer,
+                        label = "test label override for large",
+                    ),
+                )
+            )
+    }
+
+    @Test
+    fun parseFromService_validProviderInfo() {
+        val serviceComponent =
+            ComponentName(context, "androidx.glance.wear.test.TestGlanceWearWidgetService")
+        val info = WearWidgetProviderInfo.parseFromService(context, serviceComponent)
+
+        assertThat(info.providerService).isEqualTo(serviceComponent)
+        assertThat(info.label).isEqualTo("test label")
+        assertThat(info.description).isEqualTo("test description")
+        assertThat(info.icon).isEqualTo(android.R.drawable.ic_delete)
+        assertThat(info.preferredContainerType).isEqualTo(ContainerInfo.CONTAINER_TYPE_SMALL)
+        assertThat(info.group).isEqualTo("test.group")
+        assertThat(info.isMultiInstanceSupported).isTrue()
+        assertThat(info.configIntentAction).isEqualTo("test.action")
+        assertThat(info.minSchemaVersion?.major).isEqualTo(1)
+        assertThat(info.minSchemaVersion?.minor).isEqualTo(200)
+        assertThat(info.maxSchemaVersion?.major).isEqualTo(2)
+        assertThat(info.maxSchemaVersion?.minor).isEqualTo(340)
+        assertThat(info.containers).hasSize(2)
+        assertThat(info.containers)
+            .containsExactlyElementsIn(
+                listOf(
+                    ContainerInfo(
+                        ContainerInfo.CONTAINER_TYPE_SMALL,
+                        android.R.drawable.ic_dialog_alert,
+                    ),
+                    ContainerInfo(
+                        ContainerInfo.CONTAINER_TYPE_LARGE,
+                        android.R.drawable.ic_dialog_dialer,
+                        label = "test label override for large",
+                    ),
+                )
+            )
+    }
+
+    @Test(expected = PackageManager.NameNotFoundException::class)
+    fun parseFromService_invalidMetaDataResource() {
+        val serviceComponent =
+            ComponentName(
+                context,
+                "androidx.glance.wear.test.TestGlanceWearWidgetServiceInvalidMetadata",
+            )
+
+        WearWidgetProviderInfo.parseFromService(context, serviceComponent)
+    }
+
+    @Test(expected = PackageManager.NameNotFoundException::class)
+    fun parseFromService_noMetaData() {
+        val serviceComponent =
+            ComponentName(
+                context,
+                "androidx.glance.wear.test.TestGlanceWearWidgetServiceNoMetadata",
+            )
+
+        WearWidgetProviderInfo.parseFromService(context, serviceComponent)
+    }
+
+    @Test(expected = PackageManager.NameNotFoundException::class)
+    fun parseFromService_invalidService() {
+        val serviceComponent =
+            ComponentName(context, "androidx.glance.wear.test.NonExistingService")
+
+        WearWidgetProviderInfo.parseFromService(context, serviceComponent)
+    }
+
+    @Test
+    fun parseFromResource_minimalProviderInfo() {
+        val defaultPreferredContainerType = ContainerInfo.CONTAINER_TYPE_SMALL
+        val defaultGroup = "some_group"
+        val info =
+            getXml(R.xml.wear_widget_provider_info_minimal)
+                .parseWearWidgetProviderInfo(
+                    context.resources,
+                    service,
+                    defaultPreferredContainerType,
+                    defaultGroup,
+                )
+
+        assertThat(info.providerService).isEqualTo(service)
+        assertThat(info.label).isEqualTo("")
+        assertThat(info.description).isEqualTo("")
+        assertThat(info.icon).isEqualTo(0)
+        assertThat(info.preferredContainerType).isEqualTo(defaultPreferredContainerType)
+        assertThat(info.group).isEqualTo(defaultGroup)
+        assertThat(info.isMultiInstanceSupported).isFalse()
+        assertThat(info.configIntentAction).isNull()
+        assertThat(info.minSchemaVersion).isNull()
+        assertThat(info.maxSchemaVersion).isNull()
+        assertThat(info.containers).isEmpty()
+    }
+
+    @Test(expected = XmlPullParserException::class)
+    fun parseWearWidgetProviderInfo_missingType() {
+        getXml(R.xml.wear_widget_provider_info_missing_type)
+            .parseWearWidgetProviderInfo(
+                context.resources,
+                service,
+                defaultPreferredContainerType = ContainerInfo.CONTAINER_TYPE_SMALL,
+                defaultGroup = "default.group",
+            )
+    }
+
+    private fun getXml(resourceId: Int): XmlResourceParser = context.resources.getXml(resourceId)
+}
diff --git a/glance/wear/wear-core/src/test/res/xml/wear_widget_provider_info_minimal.xml b/glance/wear/wear-core/src/test/res/xml/wear_widget_provider_info_minimal.xml
new file mode 100644
index 0000000..a24cc87
--- /dev/null
+++ b/glance/wear/wear-core/src/test/res/xml/wear_widget_provider_info_minimal.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright 2025 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.
+  -->
+
+<wearwidget-provider />
diff --git a/glance/wear/wear-core/src/test/res/xml/wear_widget_provider_info_missing_type.xml b/glance/wear/wear-core/src/test/res/xml/wear_widget_provider_info_missing_type.xml
new file mode 100644
index 0000000..34fb128
--- /dev/null
+++ b/glance/wear/wear-core/src/test/res/xml/wear_widget_provider_info_missing_type.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright 2025 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.
+  -->
+
+<wearwidget-provider
+    label="My widget label">
+    <container />
+</wearwidget-provider>
diff --git a/glance/wear/wear-core/src/test/res/xml/wear_widget_provider_info_test.xml b/glance/wear/wear-core/src/test/res/xml/wear_widget_provider_info_test.xml
new file mode 100644
index 0000000..0c2947f
--- /dev/null
+++ b/glance/wear/wear-core/src/test/res/xml/wear_widget_provider_info_test.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Copyright 2025 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.
+  -->
+
+<wearwidget-provider
+    label="test label"
+    description="test description"
+    icon="@android:drawable/ic_delete"
+    preferredType="@integer/glance_wear_container_type_small"
+    group="test.group"
+    isMultiInstanceSupported="true"
+    configIntentAction="test.action"
+    minSchemaVersion="1.2"
+    maxSchemaVersion="2.34">
+
+    <container
+        type="@integer/glance_wear_container_type_small"
+        previewImage="@android:drawable/ic_dialog_alert" />
+
+    <container
+        type="@integer/glance_wear_container_type_large"
+        previewImage="@android:drawable/ic_dialog_dialer"
+        label="test label override for large" />
+
+</wearwidget-provider>
diff --git a/glance/wear/wear/api/current.txt b/glance/wear/wear/api/current.txt
index a2549fc..88a53f6 100644
--- a/glance/wear/wear/api/current.txt
+++ b/glance/wear/wear/api/current.txt
@@ -2,42 +2,15 @@
 package androidx.glance.wear {
 
   public final class ActiveWearWidgetHandle {
-    ctor @KotlinOnly public ActiveWearWidgetHandle(android.content.ComponentName provider, int instanceId, androidx.glance.wear.ContainerType containerType);
-    ctor @BytecodeOnly public ActiveWearWidgetHandle(android.content.ComponentName!, int, int, kotlin.jvm.internal.DefaultConstructorMarker!);
-    method @BytecodeOnly public int getContainerType-fdHHBOo();
+    ctor public ActiveWearWidgetHandle(android.content.ComponentName provider, int instanceId, int containerType);
+    method @InaccessibleFromKotlin public int getContainerType();
     method @InaccessibleFromKotlin public int getInstanceId();
     method @InaccessibleFromKotlin public android.content.ComponentName getProvider();
-    property public androidx.glance.wear.ContainerType containerType;
+    property public int containerType;
     property public int instanceId;
     property public android.content.ComponentName provider;
   }
 
-  public final class ContainerInfo {
-    method @InaccessibleFromKotlin public String? getDescription();
-    method @InaccessibleFromKotlin public String? getLabel();
-    method @InaccessibleFromKotlin public int getPreviewImage();
-    method @BytecodeOnly public int getType-fdHHBOo();
-    property public String? description;
-    property public String? label;
-    property public int previewImage;
-    property public androidx.glance.wear.ContainerType type;
-  }
-
-  @kotlin.jvm.JvmInline public final value class ContainerType {
-    method @BytecodeOnly public static androidx.glance.wear.ContainerType! box-impl(int);
-    method @BytecodeOnly public int unbox-impl();
-    field public static final androidx.glance.wear.ContainerType.Companion Companion;
-  }
-
-  public static final class ContainerType.Companion {
-    method @BytecodeOnly public int getFullscreen-fdHHBOo();
-    method @BytecodeOnly public int getLarge-fdHHBOo();
-    method @BytecodeOnly public int getSmall-fdHHBOo();
-    property public androidx.glance.wear.ContainerType Fullscreen;
-    property public androidx.glance.wear.ContainerType Large;
-    property public androidx.glance.wear.ContainerType Small;
-  }
-
   public abstract class GlanceWearWidget {
     ctor public GlanceWearWidget();
     method @MainThread public suspend Object? onActivated(android.content.Context context, androidx.glance.wear.ActiveWearWidgetHandle widgetHandle, kotlin.coroutines.Continuation<? super kotlin.Unit>);
@@ -59,14 +32,6 @@
     property public static String ACTION_BIND_WIDGET_PROVIDER;
   }
 
-  public final class SchemaVersion {
-    ctor public SchemaVersion(int major, int minor);
-    method @InaccessibleFromKotlin public int getMajor();
-    method @InaccessibleFromKotlin public int getMinor();
-    property public int major;
-    property public int minor;
-  }
-
   public final class WearWidgetContent {
     ctor public WearWidgetContent(kotlin.jvm.functions.Function0<kotlin.Unit> content);
     ctor @BytecodeOnly public WearWidgetContent(kotlin.jvm.functions.Function2<? super androidx.compose.runtime.Composer!,? super java.lang.Integer!,kotlin.Unit!>);
@@ -74,31 +39,6 @@
     property public kotlin.jvm.functions.Function0<kotlin.Unit> content;
   }
 
-  public final class WearWidgetProviderInfo {
-    method @InaccessibleFromKotlin public String? getConfigIntentAction();
-    method @InaccessibleFromKotlin public java.util.List<androidx.glance.wear.ContainerInfo> getContainers();
-    method @InaccessibleFromKotlin public String getDescription();
-    method @InaccessibleFromKotlin public String getGroup();
-    method @InaccessibleFromKotlin public int getIcon();
-    method @InaccessibleFromKotlin public String getLabel();
-    method @InaccessibleFromKotlin public androidx.glance.wear.SchemaVersion? getMaxSchemaVersion();
-    method @InaccessibleFromKotlin public androidx.glance.wear.SchemaVersion? getMinSchemaVersion();
-    method @BytecodeOnly public int getPreferredType-fdHHBOo();
-    method @InaccessibleFromKotlin public android.content.ComponentName getProviderService();
-    method @InaccessibleFromKotlin public boolean isMultiInstanceSupported();
-    property public String? configIntentAction;
-    property public java.util.List<androidx.glance.wear.ContainerInfo> containers;
-    property public String description;
-    property public String group;
-    property public int icon;
-    property public boolean isMultiInstanceSupported;
-    property public String label;
-    property public androidx.glance.wear.SchemaVersion? maxSchemaVersion;
-    property public androidx.glance.wear.SchemaVersion? minSchemaVersion;
-    property public androidx.glance.wear.ContainerType preferredType;
-    property public android.content.ComponentName providerService;
-  }
-
   public final class WearWidgetRequest {
     method @InaccessibleFromKotlin public float getHeightDp();
     method @InaccessibleFromKotlin public int getInstanceId();
diff --git a/glance/wear/wear/api/restricted_current.txt b/glance/wear/wear/api/restricted_current.txt
index a2549fc..88a53f6 100644
--- a/glance/wear/wear/api/restricted_current.txt
+++ b/glance/wear/wear/api/restricted_current.txt
@@ -2,42 +2,15 @@
 package androidx.glance.wear {
 
   public final class ActiveWearWidgetHandle {
-    ctor @KotlinOnly public ActiveWearWidgetHandle(android.content.ComponentName provider, int instanceId, androidx.glance.wear.ContainerType containerType);
-    ctor @BytecodeOnly public ActiveWearWidgetHandle(android.content.ComponentName!, int, int, kotlin.jvm.internal.DefaultConstructorMarker!);
-    method @BytecodeOnly public int getContainerType-fdHHBOo();
+    ctor public ActiveWearWidgetHandle(android.content.ComponentName provider, int instanceId, int containerType);
+    method @InaccessibleFromKotlin public int getContainerType();
     method @InaccessibleFromKotlin public int getInstanceId();
     method @InaccessibleFromKotlin public android.content.ComponentName getProvider();
-    property public androidx.glance.wear.ContainerType containerType;
+    property public int containerType;
     property public int instanceId;
     property public android.content.ComponentName provider;
   }
 
-  public final class ContainerInfo {
-    method @InaccessibleFromKotlin public String? getDescription();
-    method @InaccessibleFromKotlin public String? getLabel();
-    method @InaccessibleFromKotlin public int getPreviewImage();
-    method @BytecodeOnly public int getType-fdHHBOo();
-    property public String? description;
-    property public String? label;
-    property public int previewImage;
-    property public androidx.glance.wear.ContainerType type;
-  }
-
-  @kotlin.jvm.JvmInline public final value class ContainerType {
-    method @BytecodeOnly public static androidx.glance.wear.ContainerType! box-impl(int);
-    method @BytecodeOnly public int unbox-impl();
-    field public static final androidx.glance.wear.ContainerType.Companion Companion;
-  }
-
-  public static final class ContainerType.Companion {
-    method @BytecodeOnly public int getFullscreen-fdHHBOo();
-    method @BytecodeOnly public int getLarge-fdHHBOo();
-    method @BytecodeOnly public int getSmall-fdHHBOo();
-    property public androidx.glance.wear.ContainerType Fullscreen;
-    property public androidx.glance.wear.ContainerType Large;
-    property public androidx.glance.wear.ContainerType Small;
-  }
-
   public abstract class GlanceWearWidget {
     ctor public GlanceWearWidget();
     method @MainThread public suspend Object? onActivated(android.content.Context context, androidx.glance.wear.ActiveWearWidgetHandle widgetHandle, kotlin.coroutines.Continuation<? super kotlin.Unit>);
@@ -59,14 +32,6 @@
     property public static String ACTION_BIND_WIDGET_PROVIDER;
   }
 
-  public final class SchemaVersion {
-    ctor public SchemaVersion(int major, int minor);
-    method @InaccessibleFromKotlin public int getMajor();
-    method @InaccessibleFromKotlin public int getMinor();
-    property public int major;
-    property public int minor;
-  }
-
   public final class WearWidgetContent {
     ctor public WearWidgetContent(kotlin.jvm.functions.Function0<kotlin.Unit> content);
     ctor @BytecodeOnly public WearWidgetContent(kotlin.jvm.functions.Function2<? super androidx.compose.runtime.Composer!,? super java.lang.Integer!,kotlin.Unit!>);
@@ -74,31 +39,6 @@
     property public kotlin.jvm.functions.Function0<kotlin.Unit> content;
   }
 
-  public final class WearWidgetProviderInfo {
-    method @InaccessibleFromKotlin public String? getConfigIntentAction();
-    method @InaccessibleFromKotlin public java.util.List<androidx.glance.wear.ContainerInfo> getContainers();
-    method @InaccessibleFromKotlin public String getDescription();
-    method @InaccessibleFromKotlin public String getGroup();
-    method @InaccessibleFromKotlin public int getIcon();
-    method @InaccessibleFromKotlin public String getLabel();
-    method @InaccessibleFromKotlin public androidx.glance.wear.SchemaVersion? getMaxSchemaVersion();
-    method @InaccessibleFromKotlin public androidx.glance.wear.SchemaVersion? getMinSchemaVersion();
-    method @BytecodeOnly public int getPreferredType-fdHHBOo();
-    method @InaccessibleFromKotlin public android.content.ComponentName getProviderService();
-    method @InaccessibleFromKotlin public boolean isMultiInstanceSupported();
-    property public String? configIntentAction;
-    property public java.util.List<androidx.glance.wear.ContainerInfo> containers;
-    property public String description;
-    property public String group;
-    property public int icon;
-    property public boolean isMultiInstanceSupported;
-    property public String label;
-    property public androidx.glance.wear.SchemaVersion? maxSchemaVersion;
-    property public androidx.glance.wear.SchemaVersion? minSchemaVersion;
-    property public androidx.glance.wear.ContainerType preferredType;
-    property public android.content.ComponentName providerService;
-  }
-
   public final class WearWidgetRequest {
     method @InaccessibleFromKotlin public float getHeightDp();
     method @InaccessibleFromKotlin public int getInstanceId();
diff --git a/glance/wear/wear/build.gradle b/glance/wear/wear/build.gradle
index 58344b2..ab6f949 100644
--- a/glance/wear/wear/build.gradle
+++ b/glance/wear/wear/build.gradle
@@ -43,6 +43,7 @@
 
     implementation(project(":compose:remote:remote-creation"))
     implementation(project(":compose:remote:remote-creation-compose"))
+    implementation(project(":glance:wear:wear-core"))
 
     testImplementation("androidx.core:core-ktx:1.17.0")
     testImplementation(libs.kotlinCoroutinesTest)
diff --git a/glance/wear/wear/src/androidTest/java/androidx/glance/wear/parcel/WearWidgetProviderImplTest.kt b/glance/wear/wear/src/androidTest/java/androidx/glance/wear/parcel/WearWidgetProviderImplTest.kt
index 3c7b078..6898b2c 100644
--- a/glance/wear/wear/src/androidTest/java/androidx/glance/wear/parcel/WearWidgetProviderImplTest.kt
+++ b/glance/wear/wear/src/androidTest/java/androidx/glance/wear/parcel/WearWidgetProviderImplTest.kt
@@ -22,7 +22,8 @@
 import androidx.compose.remote.player.core.RemoteComposeDocument
 import androidx.compose.runtime.Composable
 import androidx.glance.wear.ActiveWearWidgetHandle
-import androidx.glance.wear.ContainerType
+import androidx.glance.wear.ContainerInfo.Companion.CONTAINER_TYPE_LARGE
+import androidx.glance.wear.ContainerInfo.Companion.CONTAINER_TYPE_SMALL
 import androidx.glance.wear.GlanceWearWidget
 import androidx.glance.wear.WearWidgetContent
 import androidx.glance.wear.WearWidgetRequest
@@ -105,7 +106,7 @@
 
     @Test
     fun onActivated_callsWidgetAndCallback() = runTest {
-        val handle = ActiveWearWidgetHandle(testName, 12, ContainerType.Large)
+        val handle = ActiveWearWidgetHandle(testName, 12, CONTAINER_TYPE_LARGE)
         val provider = WearWidgetProviderImpl(context, testName, this, testWidget)
 
         provider.onActivated(handle.toParcel(), fakeExecutionCallback)
@@ -117,7 +118,7 @@
 
     @Test
     fun onActivated_throws_callsCallbackOnError() = runTest {
-        val handle = ActiveWearWidgetHandle(testName, 12, ContainerType.Large)
+        val handle = ActiveWearWidgetHandle(testName, 12, CONTAINER_TYPE_LARGE)
         val exceptionHandlerScope =
             CoroutineScope(
                 coroutineContext + SupervisorJob() + CoroutineExceptionHandler { _, _ -> }
@@ -134,7 +135,7 @@
 
     @Test
     fun onDeactivated_callsWidgetAndCallback() = runTest {
-        val handle = ActiveWearWidgetHandle(testName, 12, ContainerType.Small)
+        val handle = ActiveWearWidgetHandle(testName, 12, CONTAINER_TYPE_SMALL)
         val provider = WearWidgetProviderImpl(context, testName, this, testWidget)
 
         provider.onDeactivated(handle.toParcel(), fakeExecutionCallback)
@@ -146,7 +147,7 @@
 
     @Test
     fun onDeactivated_throws_callsCallbackOnError() = runTest {
-        val handle = ActiveWearWidgetHandle(testName, 12, ContainerType.Large)
+        val handle = ActiveWearWidgetHandle(testName, 12, CONTAINER_TYPE_LARGE)
         val exceptionHandlerScope =
             CoroutineScope(
                 coroutineContext + SupervisorJob() + CoroutineExceptionHandler { _, _ -> }
diff --git a/glance/wear/wear/src/main/java/androidx/glance/wear/ActiveWearWidgetHandle.kt b/glance/wear/wear/src/main/java/androidx/glance/wear/ActiveWearWidgetHandle.kt
index fb0583d..6582f2b 100644
--- a/glance/wear/wear/src/main/java/androidx/glance/wear/ActiveWearWidgetHandle.kt
+++ b/glance/wear/wear/src/main/java/androidx/glance/wear/ActiveWearWidgetHandle.kt
@@ -17,8 +17,10 @@
 package androidx.glance.wear
 
 import android.content.ComponentName
+import androidx.glance.wear.ContainerInfo.ContainerType
 import androidx.glance.wear.parcel.ActiveWearWidgetHandleParcel
 import androidx.glance.wear.proto.ActiveWearWidgetHandleProto
+import androidx.glance.wear.proto.ContainerTypeProto
 import java.util.Objects
 
 /**
@@ -33,7 +35,7 @@
 public class ActiveWearWidgetHandle(
     public val provider: ComponentName,
     public val instanceId: Int,
-    public val containerType: ContainerType,
+    @ContainerType public val containerType: Int,
 ) {
     override fun equals(other: Any?): Boolean =
         when {
@@ -48,7 +50,7 @@
     override fun hashCode(): Int = Objects.hash(provider, instanceId, containerType)
 
     internal fun toParcel(): ActiveWearWidgetHandleParcel {
-        val containerTypeProto = containerType.toProto()
+        val containerTypeProto = containerTypeToProto(containerType)
         val handleProto =
             ActiveWearWidgetHandleProto(
                 instance_id = instanceId,
@@ -63,12 +65,28 @@
             provider: ComponentName,
         ): ActiveWearWidgetHandle {
             val handleProto = ActiveWearWidgetHandleProto.ADAPTER.decode(handleParcel.payload)
-            val containerType = ContainerType.fromProto(handleProto.container_type)
+            val containerType = containerTypeFromProto(handleProto.container_type)
             return ActiveWearWidgetHandle(
                 provider = provider,
                 instanceId = handleProto.instance_id,
                 containerType = containerType,
             )
         }
+
+        internal fun containerTypeToProto(@ContainerType type: Int): ContainerTypeProto =
+            when (type) {
+                ContainerInfo.CONTAINER_TYPE_FULLSCREEN -> ContainerTypeProto.FULLSCREEN
+                ContainerInfo.CONTAINER_TYPE_LARGE -> ContainerTypeProto.LARGE
+                ContainerInfo.CONTAINER_TYPE_SMALL -> ContainerTypeProto.SMALL
+                else -> throw IllegalArgumentException("Invalid container type: $this")
+            }
+
+        @ContainerType
+        internal fun containerTypeFromProto(typeProto: ContainerTypeProto): Int =
+            when (typeProto) {
+                ContainerTypeProto.FULLSCREEN -> ContainerInfo.CONTAINER_TYPE_FULLSCREEN
+                ContainerTypeProto.LARGE -> ContainerInfo.CONTAINER_TYPE_LARGE
+                ContainerTypeProto.SMALL -> ContainerInfo.CONTAINER_TYPE_SMALL
+            }
     }
 }
diff --git a/glance/wear/wear/src/main/java/androidx/glance/wear/WearWidgetProviderInfo.kt b/glance/wear/wear/src/main/java/androidx/glance/wear/WearWidgetProviderInfo.kt
deleted file mode 100644
index be912e6..0000000
--- a/glance/wear/wear/src/main/java/androidx/glance/wear/WearWidgetProviderInfo.kt
+++ /dev/null
@@ -1,165 +0,0 @@
-/*
- * Copyright 2025 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 androidx.glance.wear
-
-import android.content.ComponentName
-import androidx.annotation.DrawableRes
-import androidx.annotation.RestrictTo
-import androidx.annotation.RestrictTo.Scope.LIBRARY
-import androidx.glance.wear.proto.ContainerTypeProto
-
-/**
- * Describes the metadata for a Wear Widget provider.
- *
- * The fields in this class correspond to the fields in the `<wearwidget-provider>` xml tag.
- *
- * For example, the `AndroidManifest.xml` would contain:
- * ```xml
- * <service
- *     android:name=".MyWidgetService"
- *     android:exported="true">
- *     <meta-data
- *         android:name="androidx.glance.wear.widget.provider"
- *         android:resource="@xml/my_widget_info" />
- * </service>
- * ```
- *
- * And `res/xml/my_widget_info.xml` would contain:
- * ```xml
- * <wearwidget-provider
- *     label="@string/widget_label"
- *     description="@string/widget_description"
- *     icon="@drawable/widget_icon"
- *     preferredType="small" >
- *
- *     <container
- *         type="small"
- *         previewImage="@drawable/small_preview"/>
- *
- *     <container
- *         type="large"
- *         previewImage="@drawable/large_preview"
- *         label="@string/large_container_label_override" />
- *
- * </wearwidget-provider>
- * ```
- *
- * @property providerService The [ComponentName] of this widget provider.
- * @property label The label of this widget.
- * @property description The description of this widget.
- * @property icon The resource id of the icon for this widget.
- * @property containers The list of [ContainerInfo] supported for this widget provider. Each element
- *   represents a supported type.
- * @property preferredType The preferred [ContainerType] to use for a widget instance when type is
- *   not specified when adding a widget. This can be used when this provider is replacing a legacy
- *   Wear Tile.
- * @property group The name of the group this widget provider is associated with. Defaults to the
- *   fully qualified name of the provider service.
- * @property isMultiInstanceSupported Whether this widget provider supports multiple instances.
- * @property configIntentAction The intent action to launch an activity for configuring the widget
- *   when [isMultiInstanceSupported] is set to true. This can be null if no configuration is needed.
- * @property minSchemaVersion The minimum schema version supported by this widget provider.
- * @property maxSchemaVersion The maximum schema version supported by this widget provider.
- */
-// TODO: populate default min schema version for remote compose widgets.
-public class WearWidgetProviderInfo
-@RestrictTo(LIBRARY)
-public constructor(
-    public val providerService: ComponentName,
-    public val label: String,
-    public val description: String,
-    @DrawableRes public val icon: Int,
-    public val containers: List<ContainerInfo>,
-    public val preferredType: ContainerType,
-    public val group: String = providerService.className,
-    public val isMultiInstanceSupported: Boolean = false,
-    public val configIntentAction: String? = null,
-    public val minSchemaVersion: SchemaVersion? = null,
-    public val maxSchemaVersion: SchemaVersion? = null,
-)
-
-/**
- * Describes a container supported by a widget provider.
- *
- * A container is one representation of a widget, with a given size and shape.
- *
- * The fields in this class correspond to the fields in the `<container>` xml tag.
- *
- * For example:
- * ```xml
- * <container
- *     android:type="fullscreen"
- *     android:previewImage="@drawable/fullscreen_preview"
- *     android:label="@string/fullscreen_label" />
- * ```
- *
- * @property type The type of this widget container.
- * @property previewImage The resource id of the preview image for this widget container.
- * @property label The override label for this widget container.
- * @property description The override description for this widget container.
- */
-public class ContainerInfo
-@RestrictTo(LIBRARY)
-public constructor(
-    public val type: ContainerType,
-    @DrawableRes public val previewImage: Int,
-    public val label: String? = null,
-    public val description: String? = null,
-)
-
-/** The container type of a widget. It defines the size and shape of the container. */
-@JvmInline
-public value class ContainerType private constructor(private val value: Int) {
-
-    internal fun toProto(): ContainerTypeProto =
-        when (this) {
-            Fullscreen -> ContainerTypeProto.FULLSCREEN
-            Large -> ContainerTypeProto.LARGE
-            Small -> ContainerTypeProto.SMALL
-            else -> throw IllegalArgumentException("Invalid container type: $value")
-        }
-
-    public companion object {
-        /** Represents a fullscreen widget container, equivalent to a Wear Tile. */
-        public val Fullscreen: ContainerType = ContainerType(0)
-
-        /**
-         * Represents a large widget container. Support for this container type is device dependent.
-         */
-        public val Large: ContainerType = ContainerType(1)
-
-        /**
-         * Represents a small widget container. Support for this container type is device dependent.
-         */
-        public val Small: ContainerType = ContainerType(2)
-
-        internal fun fromProto(typeProto: ContainerTypeProto): ContainerType =
-            when (typeProto) {
-                ContainerTypeProto.FULLSCREEN -> Fullscreen
-                ContainerTypeProto.LARGE -> Large
-                ContainerTypeProto.SMALL -> Small
-            }
-    }
-}
-
-/**
- * The schema version of the widget renderer.
- *
- * @property major The major version of the schema.
- * @property minor The minor version of the schema.
- */
-public class SchemaVersion(public val major: Int, public val minor: Int)
diff --git a/glance/wear/wear/src/main/java/androidx/glance/wear/parcel/LegacyTileProviderImpl.kt b/glance/wear/wear/src/main/java/androidx/glance/wear/parcel/LegacyTileProviderImpl.kt
index a1049b2..28d29a9 100644
--- a/glance/wear/wear/src/main/java/androidx/glance/wear/parcel/LegacyTileProviderImpl.kt
+++ b/glance/wear/wear/src/main/java/androidx/glance/wear/parcel/LegacyTileProviderImpl.kt
@@ -20,7 +20,7 @@
 import android.content.Context
 import android.util.Log
 import androidx.glance.wear.ActiveWearWidgetHandle
-import androidx.glance.wear.ContainerType
+import androidx.glance.wear.ContainerInfo.Companion.CONTAINER_TYPE_FULLSCREEN
 import androidx.glance.wear.GlanceWearWidget
 import androidx.glance.wear.parcel.legacy.TileAddEventData
 import androidx.glance.wear.parcel.legacy.TileProvider
@@ -47,7 +47,11 @@
             try {
                 val addEvent = TileAddEvent.ADAPTER.decode(eventData.contents)
                 val widgetId =
-                    ActiveWearWidgetHandle(providerName, addEvent.tile_id, ContainerType.Fullscreen)
+                    ActiveWearWidgetHandle(
+                        providerName,
+                        addEvent.tile_id,
+                        CONTAINER_TYPE_FULLSCREEN,
+                    )
                 widget.onActivated(context, widgetId)
             } catch (ex: IOException) {
                 Log.e(TAG, "Error deserializing TileAddEvent payload.", ex)
@@ -66,7 +70,7 @@
                     ActiveWearWidgetHandle(
                         providerName,
                         removeEvent.tile_id,
-                        ContainerType.Fullscreen,
+                        CONTAINER_TYPE_FULLSCREEN,
                     )
                 widget.onDeactivated(context, widgetId)
             } catch (ex: IOException) {
diff --git a/glance/wear/wear/src/test/java/androidx/glance/wear/ActiveWearWidgetHandleTest.kt b/glance/wear/wear/src/test/java/androidx/glance/wear/ActiveWearWidgetHandleTest.kt
index 0072475..28fcb3f 100644
--- a/glance/wear/wear/src/test/java/androidx/glance/wear/ActiveWearWidgetHandleTest.kt
+++ b/glance/wear/wear/src/test/java/androidx/glance/wear/ActiveWearWidgetHandleTest.kt
@@ -30,85 +30,85 @@
 
     @Test
     fun equals_sameInstance() {
-        val id = ActiveWearWidgetHandle(provider1, 17, ContainerType.Large)
+        val id = ActiveWearWidgetHandle(provider1, 17, ContainerInfo.CONTAINER_TYPE_LARGE)
 
         assertThat(id).isEqualTo(id)
     }
 
     @Test
     fun equals_SameValues() {
-        val id1 = ActiveWearWidgetHandle(provider1, 17, ContainerType.Large)
-        val id2 = ActiveWearWidgetHandle(provider1, 17, ContainerType.Large)
+        val id1 = ActiveWearWidgetHandle(provider1, 17, ContainerInfo.CONTAINER_TYPE_LARGE)
+        val id2 = ActiveWearWidgetHandle(provider1, 17, ContainerInfo.CONTAINER_TYPE_LARGE)
 
         assertThat(id1).isEqualTo(id2)
     }
 
     @Test
     fun equals_differentProvider() {
-        val id1 = ActiveWearWidgetHandle(provider1, 17, ContainerType.Large)
-        val id2 = ActiveWearWidgetHandle(provider2, 17, ContainerType.Large)
+        val id1 = ActiveWearWidgetHandle(provider1, 17, ContainerInfo.CONTAINER_TYPE_LARGE)
+        val id2 = ActiveWearWidgetHandle(provider2, 17, ContainerInfo.CONTAINER_TYPE_LARGE)
 
         assertThat(id1).isNotEqualTo(id2)
     }
 
     @Test
     fun equals_differentInstanceId() {
-        val id1 = ActiveWearWidgetHandle(provider1, 17, ContainerType.Large)
-        val id2 = ActiveWearWidgetHandle(provider1, 123, ContainerType.Large)
+        val id1 = ActiveWearWidgetHandle(provider1, 17, ContainerInfo.CONTAINER_TYPE_LARGE)
+        val id2 = ActiveWearWidgetHandle(provider1, 123, ContainerInfo.CONTAINER_TYPE_LARGE)
 
         assertThat(id1).isNotEqualTo(id2)
     }
 
     @Test
     fun equals_differentContainerType() {
-        val id1 = ActiveWearWidgetHandle(provider1, 17, ContainerType.Large)
-        val id2 = ActiveWearWidgetHandle(provider1, 17, ContainerType.Small)
+        val id1 = ActiveWearWidgetHandle(provider1, 17, ContainerInfo.CONTAINER_TYPE_LARGE)
+        val id2 = ActiveWearWidgetHandle(provider1, 17, ContainerInfo.CONTAINER_TYPE_SMALL)
 
         assertThat(id1).isNotEqualTo(id2)
     }
 
     @Test
     fun equals_differentType() {
-        val id = ActiveWearWidgetHandle(provider1, 17, ContainerType.Large)
+        val id = ActiveWearWidgetHandle(provider1, 17, ContainerInfo.CONTAINER_TYPE_LARGE)
 
-        assertThat(id).isNotEqualTo(ContainerType.Large)
+        assertThat(id).isNotEqualTo(ContainerInfo.CONTAINER_TYPE_LARGE)
     }
 
     @Test
     fun equals_null() {
-        val id = ActiveWearWidgetHandle(provider1, 17, ContainerType.Large)
+        val id = ActiveWearWidgetHandle(provider1, 17, ContainerInfo.CONTAINER_TYPE_LARGE)
 
         assertThat(id).isNotEqualTo(null)
     }
 
     @Test
     fun hashCode_sameForEqualObjects() {
-        val id1 = ActiveWearWidgetHandle(provider1, 17, ContainerType.Large)
-        val id2 = ActiveWearWidgetHandle(provider1, 17, ContainerType.Large)
+        val id1 = ActiveWearWidgetHandle(provider1, 17, ContainerInfo.CONTAINER_TYPE_LARGE)
+        val id2 = ActiveWearWidgetHandle(provider1, 17, ContainerInfo.CONTAINER_TYPE_LARGE)
 
         assertThat(id1.hashCode()).isEqualTo(id2.hashCode())
     }
 
     @Test
     fun hashCode_differentForDifferentProvider() {
-        val id1 = ActiveWearWidgetHandle(provider1, 17, ContainerType.Large)
-        val id2 = ActiveWearWidgetHandle(provider2, 17, ContainerType.Large)
+        val id1 = ActiveWearWidgetHandle(provider1, 17, ContainerInfo.CONTAINER_TYPE_LARGE)
+        val id2 = ActiveWearWidgetHandle(provider2, 17, ContainerInfo.CONTAINER_TYPE_LARGE)
 
         assertThat(id1.hashCode()).isNotEqualTo(id2.hashCode())
     }
 
     @Test
     fun hashCode_differentForDifferentInstanceId() {
-        val id1 = ActiveWearWidgetHandle(provider1, 17, ContainerType.Large)
-        val id2 = ActiveWearWidgetHandle(provider1, 123, ContainerType.Large)
+        val id1 = ActiveWearWidgetHandle(provider1, 17, ContainerInfo.CONTAINER_TYPE_LARGE)
+        val id2 = ActiveWearWidgetHandle(provider1, 123, ContainerInfo.CONTAINER_TYPE_LARGE)
 
         assertThat(id1.hashCode()).isNotEqualTo(id2.hashCode())
     }
 
     @Test
     fun hashCode_differentForDifferentContainerType() {
-        val id1 = ActiveWearWidgetHandle(provider1, 17, ContainerType.Large)
-        val id2 = ActiveWearWidgetHandle(provider1, 17, ContainerType.Small)
+        val id1 = ActiveWearWidgetHandle(provider1, 17, ContainerInfo.CONTAINER_TYPE_LARGE)
+        val id2 = ActiveWearWidgetHandle(provider1, 17, ContainerInfo.CONTAINER_TYPE_SMALL)
 
         assertThat(id1.hashCode()).isNotEqualTo(id2.hashCode())
     }
diff --git a/glance/wear/wear/src/test/java/androidx/glance/wear/parcel/LegacyTileProviderImplTest.kt b/glance/wear/wear/src/test/java/androidx/glance/wear/parcel/LegacyTileProviderImplTest.kt
index 6d0f2c4..7465e23 100644
--- a/glance/wear/wear/src/test/java/androidx/glance/wear/parcel/LegacyTileProviderImplTest.kt
+++ b/glance/wear/wear/src/test/java/androidx/glance/wear/parcel/LegacyTileProviderImplTest.kt
@@ -19,7 +19,7 @@
 import android.content.ComponentName
 import android.content.Context
 import androidx.glance.wear.ActiveWearWidgetHandle
-import androidx.glance.wear.ContainerType
+import androidx.glance.wear.ContainerInfo.Companion.CONTAINER_TYPE_FULLSCREEN
 import androidx.glance.wear.GlanceWearWidget
 import androidx.glance.wear.parcel.legacy.TileAddEventData
 import androidx.glance.wear.parcel.legacy.TileRemoveEventData
@@ -52,7 +52,7 @@
         val addEvent = TileAddEvent(tile_id = tileId)
         val eventData = TileAddEventData(addEvent.encode(), TileAddEventData.VERSION_PROTOBUF)
         val expectedWidgetId =
-            ActiveWearWidgetHandle(providerName, tileId, ContainerType.Fullscreen)
+            ActiveWearWidgetHandle(providerName, tileId, CONTAINER_TYPE_FULLSCREEN)
 
         legacyTileProvider.onTileAddEvent(eventData)
         testScope.advanceUntilIdle()
@@ -67,7 +67,7 @@
         val eventData =
             TileRemoveEventData(removeEvent.encode(), TileRemoveEventData.VERSION_PROTOBUF)
         val expectedWidgetId =
-            ActiveWearWidgetHandle(providerName, tileId, ContainerType.Fullscreen)
+            ActiveWearWidgetHandle(providerName, tileId, CONTAINER_TYPE_FULLSCREEN)
 
         legacyTileProvider.onTileRemoveEvent(eventData)
         testScope.advanceUntilIdle()
diff --git a/health/connect/connect-client/samples/src/main/java/androidx/health/connect/client/samples/MedicalDataSourceSamples.kt b/health/connect/connect-client/samples/src/main/java/androidx/health/connect/client/samples/MedicalDataSourceSamples.kt
index 3c40450..7647045 100644
--- a/health/connect/connect-client/samples/src/main/java/androidx/health/connect/client/samples/MedicalDataSourceSamples.kt
+++ b/health/connect/connect-client/samples/src/main/java/androidx/health/connect/client/samples/MedicalDataSourceSamples.kt
@@ -19,6 +19,7 @@
 package androidx.health.connect.client.samples
 
 import android.net.Uri
+import androidx.annotation.RequiresPermission
 import androidx.annotation.Sampled
 import androidx.health.connect.client.HealthConnectClient
 import androidx.health.connect.client.HealthConnectFeatures.Companion.FEATURE_PERSONAL_HEALTH_RECORD
@@ -29,6 +30,7 @@
 import androidx.health.connect.client.request.CreateMedicalDataSourceRequest
 import androidx.health.connect.client.request.GetMedicalDataSourcesRequest
 
+@RequiresPermission("android.permission.health.WRITE_MEDICAL_DATA")
 @OptIn(ExperimentalPersonalHealthRecordApi::class)
 @Sampled
 suspend fun CreateMedicalDataSourceSample(healthConnectClient: HealthConnectClient) {
@@ -52,6 +54,7 @@
         )
 }
 
+@RequiresPermission("android.permission.health.WRITE_MEDICAL_DATA")
 @OptIn(ExperimentalPersonalHealthRecordApi::class)
 @Sampled
 suspend fun DeleteMedicalDataSourceWithDataSample(healthConnectClient: HealthConnectClient) {
@@ -78,6 +81,7 @@
     healthConnectClient.deleteMedicalDataSourceWithData(medicalDataSource.id)
 }
 
+@RequiresPermission("android.permission.health.WRITE_MEDICAL_DATA")
 @OptIn(ExperimentalPersonalHealthRecordApi::class)
 @Sampled
 suspend fun GetMedicalDataSourcesByRequestSample(
@@ -111,6 +115,7 @@
         )
 }
 
+@RequiresPermission("android.permission.health.WRITE_MEDICAL_DATA")
 @OptIn(ExperimentalPersonalHealthRecordApi::class)
 @Sampled
 suspend fun GetMedicalDataSourcesByIdsSample(
diff --git a/health/connect/connect-client/samples/src/main/java/androidx/health/connect/client/samples/MedicalResourceSamples.kt b/health/connect/connect-client/samples/src/main/java/androidx/health/connect/client/samples/MedicalResourceSamples.kt
index 7e6534f..db50244 100644
--- a/health/connect/connect-client/samples/src/main/java/androidx/health/connect/client/samples/MedicalResourceSamples.kt
+++ b/health/connect/connect-client/samples/src/main/java/androidx/health/connect/client/samples/MedicalResourceSamples.kt
@@ -19,6 +19,7 @@
 package androidx.health.connect.client.samples
 
 import android.net.Uri
+import androidx.annotation.RequiresPermission
 import androidx.annotation.Sampled
 import androidx.health.connect.client.HealthConnectClient
 import androidx.health.connect.client.HealthConnectFeatures.Companion.FEATURE_PERSONAL_HEALTH_RECORD
@@ -38,6 +39,7 @@
 import androidx.health.connect.client.request.UpsertMedicalResourceRequest
 import androidx.health.connect.client.response.ReadMedicalResourcesResponse
 
+@RequiresPermission("android.permission.health.WRITE_MEDICAL_DATA")
 @OptIn(ExperimentalPersonalHealthRecordApi::class)
 @Sampled
 suspend fun UpsertMedicalResourcesSample(
@@ -92,6 +94,7 @@
         )
 }
 
+@RequiresPermission("android.permission.health.WRITE_MEDICAL_DATA")
 @OptIn(ExperimentalPersonalHealthRecordApi::class)
 @Sampled
 suspend fun ReadMedicalResourcesByRequestSample(
@@ -148,6 +151,7 @@
     } while (pageToken != null)
 }
 
+@RequiresPermission("android.permission.health.WRITE_MEDICAL_DATA")
 @OptIn(ExperimentalPersonalHealthRecordApi::class)
 @Sampled
 suspend fun ReadMedicalResourcesByIdsSample(
@@ -198,6 +202,7 @@
         )
 }
 
+@RequiresPermission("android.permission.health.WRITE_MEDICAL_DATA")
 @OptIn(ExperimentalPersonalHealthRecordApi::class)
 @Sampled
 suspend fun DeleteMedicalResourcesSample(
@@ -246,6 +251,7 @@
     )
 }
 
+@RequiresPermission("android.permission.health.WRITE_MEDICAL_DATA")
 @OptIn(ExperimentalPersonalHealthRecordApi::class)
 @Sampled
 suspend fun DeleteMedicalResourcesByRequestSample(
diff --git a/libraryversions.toml b/libraryversions.toml
index f4d86c1..1d0f588 100644
--- a/libraryversions.toml
+++ b/libraryversions.toml
@@ -23,11 +23,11 @@
 CARDVIEW = "1.1.0-alpha01"
 CAR_APP = "1.8.0-alpha02"
 COLLECTION = "1.6.0-alpha01"
-COMPOSE = "1.10.0-alpha04"
+COMPOSE = "1.10.0-alpha05"
 COMPOSE_MATERIAL3 = "1.5.0-alpha06"
 COMPOSE_MATERIAL3_ADAPTIVE = "1.3.0-alpha01"
 COMPOSE_MATERIAL3_XR = "1.0.0-alpha12"
-COMPOSE_RUNTIME = "1.10.0-alpha04"
+COMPOSE_RUNTIME = "1.10.0-alpha05"
 CONSTRAINTLAYOUT = "2.3.0-alpha01"
 CONSTRAINTLAYOUT_COMPOSE = "1.2.0-alpha01"
 CONSTRAINTLAYOUT_CORE = "1.2.0-alpha01"
@@ -94,7 +94,7 @@
 LEANBACK_PREFERENCE = "1.2.0-rc01"
 LEANBACK_TAB = "1.1.0-rc01"
 LIBYUV = "0.1.0-dev01"
-LIFECYCLE = "2.10.0-alpha04"
+LIFECYCLE = "2.10.0-alpha05"
 LIFECYCLE_EXTENSIONS = "2.2.0"
 LINT = "1.0.0-alpha05"
 LOADER = "1.2.0-alpha01"
@@ -102,7 +102,7 @@
 MEDIAROUTER = "1.8.0-rc01"
 METRICS = "1.0.0-rc01"
 NAVIGATION = "2.10.0-alpha01"
-NAVIGATION3 = "1.0.0-alpha10"
+NAVIGATION3 = "1.0.0-alpha11"
 NAVIGATIONEVENT = "1.0.0-beta01"
 PAGING = "3.4.0-alpha04"
 PALETTE = "1.1.0-alpha01"
@@ -182,7 +182,7 @@
 WEAR_WATCHFACEPUSH = "1.0.0-alpha01"
 WEBKIT = "1.15.0-alpha03"
 # Adding a comment to prevent merge conflicts for Window artifact
-WINDOW = "1.5.0-rc01"
+WINDOW = "1.6.0-alpha01"
 WINDOW_EXTENSIONS = "1.5.0"
 WINDOW_EXTENSIONS_CORE = "1.1.0-alpha01"
 WINDOW_SIDECAR = "1.0.0-rc01"
diff --git a/lifecycle/lifecycle-runtime-testing/build.gradle b/lifecycle/lifecycle-runtime-testing/build.gradle
index 958c4af..a8530b3 100644
--- a/lifecycle/lifecycle-runtime-testing/build.gradle
+++ b/lifecycle/lifecycle-runtime-testing/build.gradle
@@ -74,7 +74,7 @@
             dependsOn(jvmMain)
         }
 
-        androidUnitTest {
+        androidHostTest {
             dependsOn(jvmTest)
         }
 
diff --git a/lifecycle/lifecycle-runtime/build.gradle b/lifecycle/lifecycle-runtime/build.gradle
index daa3d94..4e42c53 100644
--- a/lifecycle/lifecycle-runtime/build.gradle
+++ b/lifecycle/lifecycle-runtime/build.gradle
@@ -94,7 +94,7 @@
             }
         }
 
-        androidUnitTest {
+        androidHostTest {
             dependsOn(jvmTest)
             dependencies {
                 implementation(libs.junit)
diff --git a/lifecycle/lifecycle-runtime/src/androidUnitTest/kotlin/NoPackageObserver.kt b/lifecycle/lifecycle-runtime/src/androidHostTest/kotlin/NoPackageObserver.kt
similarity index 100%
rename from lifecycle/lifecycle-runtime/src/androidUnitTest/kotlin/NoPackageObserver.kt
rename to lifecycle/lifecycle-runtime/src/androidHostTest/kotlin/NoPackageObserver.kt
diff --git a/lifecycle/lifecycle-runtime/src/androidUnitTest/kotlin/NoPackageTest.kt b/lifecycle/lifecycle-runtime/src/androidHostTest/kotlin/NoPackageTest.kt
similarity index 100%
rename from lifecycle/lifecycle-runtime/src/androidUnitTest/kotlin/NoPackageTest.kt
rename to lifecycle/lifecycle-runtime/src/androidHostTest/kotlin/NoPackageTest.kt
diff --git a/lifecycle/lifecycle-runtime/src/androidUnitTest/kotlin/androidx/lifecycle/LifecycleRegistryTest.java b/lifecycle/lifecycle-runtime/src/androidHostTest/kotlin/androidx/lifecycle/LifecycleRegistryTest.java
similarity index 100%
rename from lifecycle/lifecycle-runtime/src/androidUnitTest/kotlin/androidx/lifecycle/LifecycleRegistryTest.java
rename to lifecycle/lifecycle-runtime/src/androidHostTest/kotlin/androidx/lifecycle/LifecycleRegistryTest.java
diff --git a/lifecycle/lifecycle-runtime/src/androidUnitTest/kotlin/androidx/lifecycle/runLifecycleTest.android.kt b/lifecycle/lifecycle-runtime/src/androidHostTest/kotlin/androidx/lifecycle/runLifecycleTest.android.kt
similarity index 100%
rename from lifecycle/lifecycle-runtime/src/androidUnitTest/kotlin/androidx/lifecycle/runLifecycleTest.android.kt
rename to lifecycle/lifecycle-runtime/src/androidHostTest/kotlin/androidx/lifecycle/runLifecycleTest.android.kt
diff --git a/lifecycle/lifecycle-viewmodel-navigation3/api/current.txt b/lifecycle/lifecycle-viewmodel-navigation3/api/current.txt
index 98d4f0b..6c5c0da 100644
--- a/lifecycle/lifecycle-viewmodel-navigation3/api/current.txt
+++ b/lifecycle/lifecycle-viewmodel-navigation3/api/current.txt
@@ -6,8 +6,8 @@
   }
 
   public final class ViewModelStoreNavEntryDecoratorKt {
-    method @KotlinOnly @androidx.compose.runtime.Composable public static <T> androidx.navigation3.runtime.NavEntryDecorator<T> rememberViewModelStoreNavEntryDecorator(optional androidx.lifecycle.ViewModelStoreOwner viewModelStoreOwner, optional kotlin.jvm.functions.Function0<java.lang.Boolean> removeViewModelStoreOnPop);
-    method @BytecodeOnly @androidx.compose.runtime.Composable public static <T> androidx.navigation3.runtime.NavEntryDecorator<T!> rememberViewModelStoreNavEntryDecorator(androidx.lifecycle.ViewModelStoreOwner?, kotlin.jvm.functions.Function0<java.lang.Boolean!>?, androidx.compose.runtime.Composer?, int, int);
+    method @KotlinOnly @androidx.compose.runtime.Composable public static <T> androidx.lifecycle.viewmodel.navigation3.ViewModelStoreNavEntryDecorator<T> rememberViewModelStoreNavEntryDecorator(optional androidx.lifecycle.ViewModelStoreOwner viewModelStoreOwner, optional kotlin.jvm.functions.Function0<java.lang.Boolean> removeViewModelStoreOnPop);
+    method @BytecodeOnly @androidx.compose.runtime.Composable public static <T> androidx.lifecycle.viewmodel.navigation3.ViewModelStoreNavEntryDecorator<T!> rememberViewModelStoreNavEntryDecorator(androidx.lifecycle.ViewModelStoreOwner?, kotlin.jvm.functions.Function0<java.lang.Boolean!>?, androidx.compose.runtime.Composer?, int, int);
     method @KotlinOnly @androidx.compose.runtime.Composable public static kotlin.jvm.functions.Function0<java.lang.Boolean> removeViewModelStoreOnPopCallback();
     method @BytecodeOnly @androidx.compose.runtime.Composable public static kotlin.jvm.functions.Function0<java.lang.Boolean!> removeViewModelStoreOnPopCallback(androidx.compose.runtime.Composer?, int);
   }
diff --git a/lifecycle/lifecycle-viewmodel-navigation3/api/restricted_current.txt b/lifecycle/lifecycle-viewmodel-navigation3/api/restricted_current.txt
index 98d4f0b..6c5c0da 100644
--- a/lifecycle/lifecycle-viewmodel-navigation3/api/restricted_current.txt
+++ b/lifecycle/lifecycle-viewmodel-navigation3/api/restricted_current.txt
@@ -6,8 +6,8 @@
   }
 
   public final class ViewModelStoreNavEntryDecoratorKt {
-    method @KotlinOnly @androidx.compose.runtime.Composable public static <T> androidx.navigation3.runtime.NavEntryDecorator<T> rememberViewModelStoreNavEntryDecorator(optional androidx.lifecycle.ViewModelStoreOwner viewModelStoreOwner, optional kotlin.jvm.functions.Function0<java.lang.Boolean> removeViewModelStoreOnPop);
-    method @BytecodeOnly @androidx.compose.runtime.Composable public static <T> androidx.navigation3.runtime.NavEntryDecorator<T!> rememberViewModelStoreNavEntryDecorator(androidx.lifecycle.ViewModelStoreOwner?, kotlin.jvm.functions.Function0<java.lang.Boolean!>?, androidx.compose.runtime.Composer?, int, int);
+    method @KotlinOnly @androidx.compose.runtime.Composable public static <T> androidx.lifecycle.viewmodel.navigation3.ViewModelStoreNavEntryDecorator<T> rememberViewModelStoreNavEntryDecorator(optional androidx.lifecycle.ViewModelStoreOwner viewModelStoreOwner, optional kotlin.jvm.functions.Function0<java.lang.Boolean> removeViewModelStoreOnPop);
+    method @BytecodeOnly @androidx.compose.runtime.Composable public static <T> androidx.lifecycle.viewmodel.navigation3.ViewModelStoreNavEntryDecorator<T!> rememberViewModelStoreNavEntryDecorator(androidx.lifecycle.ViewModelStoreOwner?, kotlin.jvm.functions.Function0<java.lang.Boolean!>?, androidx.compose.runtime.Composer?, int, int);
     method @KotlinOnly @androidx.compose.runtime.Composable public static kotlin.jvm.functions.Function0<java.lang.Boolean> removeViewModelStoreOnPopCallback();
     method @BytecodeOnly @androidx.compose.runtime.Composable public static kotlin.jvm.functions.Function0<java.lang.Boolean!> removeViewModelStoreOnPopCallback(androidx.compose.runtime.Composer?, int);
   }
diff --git a/lifecycle/lifecycle-viewmodel-navigation3/bcv/native/current.txt b/lifecycle/lifecycle-viewmodel-navigation3/bcv/native/current.txt
index f260b19..a661352 100644
--- a/lifecycle/lifecycle-viewmodel-navigation3/bcv/native/current.txt
+++ b/lifecycle/lifecycle-viewmodel-navigation3/bcv/native/current.txt
@@ -12,6 +12,6 @@
 
 final val androidx.lifecycle.viewmodel.navigation3/androidx_lifecycle_viewmodel_navigation3_ViewModelStoreNavEntryDecorator$stableprop // androidx.lifecycle.viewmodel.navigation3/androidx_lifecycle_viewmodel_navigation3_ViewModelStoreNavEntryDecorator$stableprop|#static{}androidx_lifecycle_viewmodel_navigation3_ViewModelStoreNavEntryDecorator$stableprop[0]
 
-final fun <#A: kotlin/Any> androidx.lifecycle.viewmodel.navigation3/rememberViewModelStoreNavEntryDecorator(androidx.lifecycle/ViewModelStoreOwner?, kotlin/Function0<kotlin/Boolean>?, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int): androidx.navigation3.runtime/NavEntryDecorator<#A> // androidx.lifecycle.viewmodel.navigation3/rememberViewModelStoreNavEntryDecorator|rememberViewModelStoreNavEntryDecorator(androidx.lifecycle.ViewModelStoreOwner?;kotlin.Function0<kotlin.Boolean>?;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int){0§<kotlin.Any>}[0]
+final fun <#A: kotlin/Any> androidx.lifecycle.viewmodel.navigation3/rememberViewModelStoreNavEntryDecorator(androidx.lifecycle/ViewModelStoreOwner?, kotlin/Function0<kotlin/Boolean>?, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int): androidx.lifecycle.viewmodel.navigation3/ViewModelStoreNavEntryDecorator<#A> // androidx.lifecycle.viewmodel.navigation3/rememberViewModelStoreNavEntryDecorator|rememberViewModelStoreNavEntryDecorator(androidx.lifecycle.ViewModelStoreOwner?;kotlin.Function0<kotlin.Boolean>?;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int){0§<kotlin.Any>}[0]
 final fun androidx.lifecycle.viewmodel.navigation3/androidx_lifecycle_viewmodel_navigation3_ViewModelStoreNavEntryDecorator$stableprop_getter(): kotlin/Int // androidx.lifecycle.viewmodel.navigation3/androidx_lifecycle_viewmodel_navigation3_ViewModelStoreNavEntryDecorator$stableprop_getter|androidx_lifecycle_viewmodel_navigation3_ViewModelStoreNavEntryDecorator$stableprop_getter(){}[0]
 final fun androidx.lifecycle.viewmodel.navigation3/removeViewModelStoreOnPopCallback(androidx.compose.runtime/Composer?, kotlin/Int): kotlin/Function0<kotlin/Boolean> // androidx.lifecycle.viewmodel.navigation3/removeViewModelStoreOnPopCallback|removeViewModelStoreOnPopCallback(androidx.compose.runtime.Composer?;kotlin.Int){}[0]
diff --git a/lifecycle/lifecycle-viewmodel-navigation3/src/commonMain/kotlin/androidx/lifecycle/viewmodel/navigation3/ViewModelStoreNavEntryDecorator.kt b/lifecycle/lifecycle-viewmodel-navigation3/src/commonMain/kotlin/androidx/lifecycle/viewmodel/navigation3/ViewModelStoreNavEntryDecorator.kt
index 3628eca..b4f5fd3 100644
--- a/lifecycle/lifecycle-viewmodel-navigation3/src/commonMain/kotlin/androidx/lifecycle/viewmodel/navigation3/ViewModelStoreNavEntryDecorator.kt
+++ b/lifecycle/lifecycle-viewmodel-navigation3/src/commonMain/kotlin/androidx/lifecycle/viewmodel/navigation3/ViewModelStoreNavEntryDecorator.kt
@@ -22,6 +22,7 @@
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.CompositionLocalProvider
 import androidx.compose.runtime.remember
+import androidx.compose.runtime.rememberUpdatedState
 import androidx.lifecycle.HasDefaultViewModelProviderFactory
 import androidx.lifecycle.Lifecycle
 import androidx.lifecycle.SAVED_STATE_REGISTRY_OWNER_KEY
@@ -60,8 +61,14 @@
             "No ViewModelStoreOwner was provided via LocalViewModelStoreOwner"
         },
     removeViewModelStoreOnPop: () -> Boolean = removeViewModelStoreOnPopCallback(),
-): NavEntryDecorator<T> = remember {
-    ViewModelStoreNavEntryDecorator(viewModelStoreOwner.viewModelStore, removeViewModelStoreOnPop)
+): ViewModelStoreNavEntryDecorator<T> {
+    val currentRemoveViewModelStoreOnPop = rememberUpdatedState(removeViewModelStoreOnPop)
+    return remember(viewModelStoreOwner, currentRemoveViewModelStoreOnPop) {
+        ViewModelStoreNavEntryDecorator(
+            viewModelStoreOwner.viewModelStore,
+            removeViewModelStoreOnPop,
+        )
+    }
 }
 
 /**
diff --git a/lifecycle/lifecycle-viewmodel-savedstate/build.gradle b/lifecycle/lifecycle-viewmodel-savedstate/build.gradle
index a39ec24..df17d46 100644
--- a/lifecycle/lifecycle-viewmodel-savedstate/build.gradle
+++ b/lifecycle/lifecycle-viewmodel-savedstate/build.gradle
@@ -89,7 +89,7 @@
             }
         }
 
-        androidUnitTest {
+        androidHostTest {
             dependsOn(jvmTest)
         }
 
diff --git a/lifecycle/lifecycle-viewmodel-testing/build.gradle b/lifecycle/lifecycle-viewmodel-testing/build.gradle
index 86b8630..c5c1843 100644
--- a/lifecycle/lifecycle-viewmodel-testing/build.gradle
+++ b/lifecycle/lifecycle-viewmodel-testing/build.gradle
@@ -81,7 +81,7 @@
             dependsOn(jvmMain)
         }
 
-        androidUnitTest {
+        androidHostTest {
             dependsOn(commonTest)
             dependsOn(jvmTest)
             dependencies {
diff --git a/lifecycle/lifecycle-viewmodel-testing/src/androidUnitTest/kotlin/androidx/lifecycle/viewmodel/testing/AndroidViewModelScenarioTest.kt b/lifecycle/lifecycle-viewmodel-testing/src/androidHostTest/kotlin/androidx/lifecycle/viewmodel/testing/AndroidViewModelScenarioTest.kt
similarity index 100%
rename from lifecycle/lifecycle-viewmodel-testing/src/androidUnitTest/kotlin/androidx/lifecycle/viewmodel/testing/AndroidViewModelScenarioTest.kt
rename to lifecycle/lifecycle-viewmodel-testing/src/androidHostTest/kotlin/androidx/lifecycle/viewmodel/testing/AndroidViewModelScenarioTest.kt
diff --git a/lifecycle/lifecycle-viewmodel-testing/src/androidUnitTest/kotlin/androidx/lifecycle/viewmodel/testing/RobolectricTest.android.kt b/lifecycle/lifecycle-viewmodel-testing/src/androidHostTest/kotlin/androidx/lifecycle/viewmodel/testing/RobolectricTest.android.kt
similarity index 100%
rename from lifecycle/lifecycle-viewmodel-testing/src/androidUnitTest/kotlin/androidx/lifecycle/viewmodel/testing/RobolectricTest.android.kt
rename to lifecycle/lifecycle-viewmodel-testing/src/androidHostTest/kotlin/androidx/lifecycle/viewmodel/testing/RobolectricTest.android.kt
diff --git a/lifecycle/lifecycle-viewmodel/build.gradle b/lifecycle/lifecycle-viewmodel/build.gradle
index 3f78c26..8bda2c5 100644
--- a/lifecycle/lifecycle-viewmodel/build.gradle
+++ b/lifecycle/lifecycle-viewmodel/build.gradle
@@ -92,7 +92,7 @@
             }
         }
 
-        androidUnitTest {
+        androidHostTest {
             dependsOn(jvmTest)
             dependencies {
                 implementation(libs.mockitoCore4)
diff --git a/lifecycle/lifecycle-viewmodel/src/androidUnitTest/kotlin/androidx/lifecycle/MockViewModelStoreTest.kt b/lifecycle/lifecycle-viewmodel/src/androidHostTest/kotlin/androidx/lifecycle/MockViewModelStoreTest.kt
similarity index 100%
rename from lifecycle/lifecycle-viewmodel/src/androidUnitTest/kotlin/androidx/lifecycle/MockViewModelStoreTest.kt
rename to lifecycle/lifecycle-viewmodel/src/androidHostTest/kotlin/androidx/lifecycle/MockViewModelStoreTest.kt
diff --git a/lifecycle/lifecycle-viewmodel/src/androidUnitTest/kotlin/androidx/lifecycle/MockViewModelTest.kt b/lifecycle/lifecycle-viewmodel/src/androidHostTest/kotlin/androidx/lifecycle/MockViewModelTest.kt
similarity index 100%
rename from lifecycle/lifecycle-viewmodel/src/androidUnitTest/kotlin/androidx/lifecycle/MockViewModelTest.kt
rename to lifecycle/lifecycle-viewmodel/src/androidHostTest/kotlin/androidx/lifecycle/MockViewModelTest.kt
diff --git a/lifecycle/lifecycle-viewmodel/src/androidUnitTest/kotlin/androidx/lifecycle/NewInstanceFactoryTest.kt b/lifecycle/lifecycle-viewmodel/src/androidHostTest/kotlin/androidx/lifecycle/NewInstanceFactoryTest.kt
similarity index 100%
rename from lifecycle/lifecycle-viewmodel/src/androidUnitTest/kotlin/androidx/lifecycle/NewInstanceFactoryTest.kt
rename to lifecycle/lifecycle-viewmodel/src/androidHostTest/kotlin/androidx/lifecycle/NewInstanceFactoryTest.kt
diff --git a/media/media/api/current.txt b/media/media/api/current.txt
index b1a84c6..202f1b7 100644
--- a/media/media/api/current.txt
+++ b/media/media/api/current.txt
@@ -304,10 +304,13 @@
     ctor @Deprecated public MediaSessionCompat(android.content.Context, String, android.content.ComponentName?, android.app.PendingIntent?, android.os.Bundle?);
     method @Deprecated public void addOnActiveChangeListener(android.support.v4.media.session.MediaSessionCompat.OnActiveChangeListener!);
     method @Deprecated public static android.support.v4.media.session.MediaSessionCompat! fromMediaSession(android.content.Context!, Object!);
+    method @Deprecated public static int getBitmapDimensionLimit();
     method @Deprecated public android.support.v4.media.session.MediaControllerCompat! getController();
     method @Deprecated public final androidx.media.MediaSessionManager.RemoteUserInfo getCurrentControllerInfo();
     method @Deprecated public Object! getMediaSession();
     method @Deprecated public Object! getRemoteControlClient();
+    method @Deprecated public static android.graphics.Bitmap! getScaledBitmap(android.graphics.Bitmap!);
+    method @Deprecated public static android.graphics.Bitmap! getScaledBitmap(android.graphics.Bitmap!, int);
     method @Deprecated public android.support.v4.media.session.MediaSessionCompat.Token! getSessionToken();
     method @Deprecated public boolean isActive();
     method @Deprecated public void release();
diff --git a/media/media/api/restricted_current.txt b/media/media/api/restricted_current.txt
index 3bcd527..cb1e9ca8 100644
--- a/media/media/api/restricted_current.txt
+++ b/media/media/api/restricted_current.txt
@@ -310,10 +310,13 @@
     ctor @Deprecated @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public MediaSessionCompat(android.content.Context, String, android.content.ComponentName?, android.app.PendingIntent?, android.os.Bundle?, androidx.versionedparcelable.VersionedParcelable?);
     method @Deprecated public void addOnActiveChangeListener(android.support.v4.media.session.MediaSessionCompat.OnActiveChangeListener!);
     method @Deprecated public static android.support.v4.media.session.MediaSessionCompat! fromMediaSession(android.content.Context!, Object!);
+    method @Deprecated public static int getBitmapDimensionLimit();
     method @Deprecated public android.support.v4.media.session.MediaControllerCompat! getController();
     method @Deprecated public final androidx.media.MediaSessionManager.RemoteUserInfo getCurrentControllerInfo();
     method @Deprecated public Object! getMediaSession();
     method @Deprecated public Object! getRemoteControlClient();
+    method @Deprecated public static android.graphics.Bitmap! getScaledBitmap(android.graphics.Bitmap!);
+    method @Deprecated public static android.graphics.Bitmap! getScaledBitmap(android.graphics.Bitmap!, int);
     method @Deprecated public android.support.v4.media.session.MediaSessionCompat.Token! getSessionToken();
     method @Deprecated public boolean isActive();
     method @Deprecated public void release();
diff --git a/media/media/src/main/java/android/support/v4/media/session/MediaSessionCompat.java b/media/media/src/main/java/android/support/v4/media/session/MediaSessionCompat.java
index 664c253..1f79ffb 100644
--- a/media/media/src/main/java/android/support/v4/media/session/MediaSessionCompat.java
+++ b/media/media/src/main/java/android/support/v4/media/session/MediaSessionCompat.java
@@ -29,6 +29,8 @@
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
+import android.content.res.Resources;
+import android.graphics.Bitmap;
 import android.media.AudioAttributes;
 import android.media.AudioManager;
 import android.media.MediaDescription;
@@ -414,11 +416,94 @@
     public static final String KEY_SESSION2_TOKEN =
             "android.support.v4.media.session.SESSION_TOKEN2";
 
-    // Maximum size of the bitmap in dp.
-    private static final int MAX_BITMAP_SIZE_IN_DP = 320;
+    // Bitmap dimension limit in pixels
+    private static class MediaMetadataBitmapMaxSizeHolder {
+        static final int value = getMediaMetadataBitmapMaxSize();
+    }
 
-    // Maximum size of the bitmap in px. It shouldn't be changed.
-    static int sMaxBitmapSize;
+    @SuppressWarnings("DiscouragedApi") // Using Resources.getIdentifier() is less efficient
+    private static int getMediaMetadataBitmapMaxSize() {
+        Resources res = Resources.getSystem();
+        int limit = res.getDisplayMetrics().widthPixels;
+        try {
+            int id = res.getIdentifier("config_mediaMetadataBitmapMaxSize", "dimen", "android");
+            limit = res.getDimensionPixelSize(id);
+        } catch (Resources.NotFoundException e) {
+            // do nothing
+        }
+        return limit;
+    }
+
+    /**
+     * Gets the bitmap dimension limit in pixels. Bitmaps with width or height larger than this
+     * will be scaled down to fit within the limit.
+     *
+     * Apps are recommended to use bitmaps whose width or height is no larger than this limit.
+     * Otherwise, for example, when setting a bitmap in MediaSession metadata {@link
+     * MediaSession.setMetadata()}, a downscaling will be performed, which incurs performance
+     * cost as well as an intermediate scaled down bitmap.
+     *
+     * Example usage:
+     *
+     * <pre>{@code
+     *   int width = calculateRequestBitmapWidthPx();
+     *   int height = calculateRequestBitmapHeightPx();
+     *   final int limit = mediaSession.getBitmapDimensionLimit();
+     *   if (width >= limit || height >= limit) {
+     *     float scale = Math.max((float)(width) / limit,
+     *                            (float)(height) / limit);
+     *     if (scale < THRESHOLD) {
+     *       width = (int)(width * scale);
+     *       height = (int)(height * scale);
+     *     }
+     *   }
+     *
+     *   Bitmap bitmap = BitmapLoader.load(uri, width, height);
+     * }</pre>
+     */
+    public static int getBitmapDimensionLimit() {
+        return MediaMetadataBitmapMaxSizeHolder.value;
+    }
+
+    /**
+     * Scales down the given bitmap if its width or height exceeds the limit returned by
+     * {@link #getBitmapDimensionLimit()}. The bitmap will be scaled to fit within the limit
+     * while maintaining its aspect ratio. On API 31+, the returned bitmap will be a shared
+     * bitmap.
+     *
+     * @param bitmap The bitmap to potentially scale.
+     * @return The original bitmap if it's within the dimension limit, or a scaled-down version.
+     * @see #getBitmapDimensionLimit()
+     */
+    public static Bitmap getScaledBitmap(Bitmap bitmap) {
+        return getScaledBitmap(bitmap, getBitmapDimensionLimit());
+    }
+
+    /**
+     * Scales down the given bitmap if its width or height exceeds either the provided
+     * {@code dimensionLimit} or the limit returned by {@link #getBitmapDimensionLimit()}.
+     * The bitmap will be scaled to fit within that limit while maintaining its aspect ratio.
+     * On API 31+, the returned bitmap will be a shared bitmap.
+     *
+     * @param bitmap The bitmap to potentially scale.
+     * @param dimensionLimit The maximum allowed width or height for the bitmap.
+     * @return The original bitmap if it's within the dimension limit, or a scaled-down version.
+     */
+    public static Bitmap getScaledBitmap(Bitmap bitmap, int dimensionLimit) {
+        int limit = Math.min(getBitmapDimensionLimit(), dimensionLimit);
+        int width = bitmap.getWidth();
+        int height = bitmap.getHeight();
+        if (width > limit || height > limit) {
+            float scale = Math.min((float) limit / width, (float) limit / height);
+            width = (int)(width * scale);
+            height = (int)(height * scale);
+            bitmap = Bitmap.createScaledBitmap(bitmap, width, height, /* filter= */ true);
+        }
+        if (Build.VERSION.SDK_INT >= 31) {
+            return bitmap.asShared();
+        }
+        return bitmap;
+    }
 
     /**
      * Creates a new session. You must call {@link #release()} when finished with the session.
@@ -545,11 +630,6 @@
         setCallback(new Callback() {}, handler);
         mImpl.setMediaButtonReceiver(mbrIntent);
         mController = new MediaControllerCompat(context, this);
-
-        if (sMaxBitmapSize == 0) {
-            sMaxBitmapSize = (int) (TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
-                    MAX_BITMAP_SIZE_IN_DP, context.getResources().getDisplayMetrics()) + 0.5f);
-        }
     }
 
     private MediaSessionCompat(Context context, MediaSessionImpl impl) {
diff --git a/navigation/navigation-common/build.gradle b/navigation/navigation-common/build.gradle
index cc72458..6364fa9 100644
--- a/navigation/navigation-common/build.gradle
+++ b/navigation/navigation-common/build.gradle
@@ -114,7 +114,7 @@
             }
         }
 
-        androidUnitTest {
+        androidHostTest {
             dependsOn(commonTest)
             dependencies {
                 implementation(project(":navigation:navigation-testing"))
diff --git a/navigation/navigation-common/src/androidUnitTest/kotlin/androidx/navigation/ActionOnlyNavDirectionsTest.kt b/navigation/navigation-common/src/androidHostTest/kotlin/androidx/navigation/ActionOnlyNavDirectionsTest.kt
similarity index 100%
rename from navigation/navigation-common/src/androidUnitTest/kotlin/androidx/navigation/ActionOnlyNavDirectionsTest.kt
rename to navigation/navigation-common/src/androidHostTest/kotlin/androidx/navigation/ActionOnlyNavDirectionsTest.kt
diff --git a/navigation/navigation-common/src/androidUnitTest/kotlin/androidx/navigation/NavActionTest.kt b/navigation/navigation-common/src/androidHostTest/kotlin/androidx/navigation/NavActionTest.kt
similarity index 100%
rename from navigation/navigation-common/src/androidUnitTest/kotlin/androidx/navigation/NavActionTest.kt
rename to navigation/navigation-common/src/androidHostTest/kotlin/androidx/navigation/NavActionTest.kt
diff --git a/navigation/navigation-common/src/androidUnitTest/kotlin/androidx/navigation/NavDestinationTest.kt b/navigation/navigation-common/src/androidHostTest/kotlin/androidx/navigation/NavDestinationTest.kt
similarity index 100%
rename from navigation/navigation-common/src/androidUnitTest/kotlin/androidx/navigation/NavDestinationTest.kt
rename to navigation/navigation-common/src/androidHostTest/kotlin/androidx/navigation/NavDestinationTest.kt
diff --git a/navigation/navigation-common/src/androidUnitTest/kotlin/androidx/navigation/NavGraphNavigatorTest.kt b/navigation/navigation-common/src/androidHostTest/kotlin/androidx/navigation/NavGraphNavigatorTest.kt
similarity index 100%
rename from navigation/navigation-common/src/androidUnitTest/kotlin/androidx/navigation/NavGraphNavigatorTest.kt
rename to navigation/navigation-common/src/androidHostTest/kotlin/androidx/navigation/NavGraphNavigatorTest.kt
diff --git a/navigation/navigation-common/src/androidUnitTest/kotlin/androidx/navigation/NavGraphTest.kt b/navigation/navigation-common/src/androidHostTest/kotlin/androidx/navigation/NavGraphTest.kt
similarity index 100%
rename from navigation/navigation-common/src/androidUnitTest/kotlin/androidx/navigation/NavGraphTest.kt
rename to navigation/navigation-common/src/androidHostTest/kotlin/androidx/navigation/NavGraphTest.kt
diff --git a/navigation/navigation-common/src/androidUnitTest/kotlin/androidx/navigation/NavigatorProviderTest.kt b/navigation/navigation-common/src/androidHostTest/kotlin/androidx/navigation/NavigatorProviderTest.kt
similarity index 100%
rename from navigation/navigation-common/src/androidUnitTest/kotlin/androidx/navigation/NavigatorProviderTest.kt
rename to navigation/navigation-common/src/androidHostTest/kotlin/androidx/navigation/NavigatorProviderTest.kt
diff --git a/navigation/navigation-common/src/androidUnitTest/kotlin/androidx/navigation/serialization/NavArgumentGeneratorTest.kt b/navigation/navigation-common/src/androidHostTest/kotlin/androidx/navigation/serialization/NavArgumentGeneratorTest.kt
similarity index 100%
rename from navigation/navigation-common/src/androidUnitTest/kotlin/androidx/navigation/serialization/NavArgumentGeneratorTest.kt
rename to navigation/navigation-common/src/androidHostTest/kotlin/androidx/navigation/serialization/NavArgumentGeneratorTest.kt
diff --git a/navigation/navigation-common/src/androidUnitTest/kotlin/androidx/navigation/serialization/NavTypeConverterTest.kt b/navigation/navigation-common/src/androidHostTest/kotlin/androidx/navigation/serialization/NavTypeConverterTest.kt
similarity index 100%
rename from navigation/navigation-common/src/androidUnitTest/kotlin/androidx/navigation/serialization/NavTypeConverterTest.kt
rename to navigation/navigation-common/src/androidHostTest/kotlin/androidx/navigation/serialization/NavTypeConverterTest.kt
diff --git a/navigation/navigation-common/src/androidUnitTest/kotlin/androidx/navigation/serialization/RoutePatternTest.kt b/navigation/navigation-common/src/androidHostTest/kotlin/androidx/navigation/serialization/RoutePatternTest.kt
similarity index 100%
rename from navigation/navigation-common/src/androidUnitTest/kotlin/androidx/navigation/serialization/RoutePatternTest.kt
rename to navigation/navigation-common/src/androidHostTest/kotlin/androidx/navigation/serialization/RoutePatternTest.kt
diff --git a/navigation/navigation-compose/build.gradle b/navigation/navigation-compose/build.gradle
index 5048088..638c543 100644
--- a/navigation/navigation-compose/build.gradle
+++ b/navigation/navigation-compose/build.gradle
@@ -94,7 +94,7 @@
                 implementation("androidx.activity:activity:1.8.0")
             }
         }
-        androidUnitTest {
+        androidHostTest {
             dependsOn(jvmCommonTest)
         }
         androidInstrumentedTest {
diff --git a/navigation/navigation-runtime/build.gradle b/navigation/navigation-runtime/build.gradle
index d735c50..5617381 100644
--- a/navigation/navigation-runtime/build.gradle
+++ b/navigation/navigation-runtime/build.gradle
@@ -108,7 +108,7 @@
                 api("androidx.annotation:annotation-experimental:1.4.1")
             }
         }
-        androidUnitTest {
+        androidHostTest {
             dependsOn(commonTest)
         }
         androidInstrumentedTest {
diff --git a/navigation/navigation-testing/build.gradle b/navigation/navigation-testing/build.gradle
index 0e1bff9..710d459 100644
--- a/navigation/navigation-testing/build.gradle
+++ b/navigation/navigation-testing/build.gradle
@@ -118,7 +118,7 @@
             }
         }
 
-        androidUnitTest {
+        androidHostTest {
             dependsOn(commonTest)
             dependencies {
                 runtimeOnly(libs.testCore)
diff --git a/navigation/navigation-testing/src/androidUnitTest/kotlin/androidx/navigation/testing/RobolectricTest.android.kt b/navigation/navigation-testing/src/androidHostTest/kotlin/androidx/navigation/testing/RobolectricTest.android.kt
similarity index 100%
rename from navigation/navigation-testing/src/androidUnitTest/kotlin/androidx/navigation/testing/RobolectricTest.android.kt
rename to navigation/navigation-testing/src/androidHostTest/kotlin/androidx/navigation/testing/RobolectricTest.android.kt
diff --git a/navigation/navigation-testing/src/androidUnitTest/kotlin/androidx/navigation/testing/TestSavedStateHandleFactory.kt b/navigation/navigation-testing/src/androidHostTest/kotlin/androidx/navigation/testing/TestSavedStateHandleFactory.kt
similarity index 100%
rename from navigation/navigation-testing/src/androidUnitTest/kotlin/androidx/navigation/testing/TestSavedStateHandleFactory.kt
rename to navigation/navigation-testing/src/androidHostTest/kotlin/androidx/navigation/testing/TestSavedStateHandleFactory.kt
diff --git a/navigation3/navigation3-runtime/api/current.txt b/navigation3/navigation3-runtime/api/current.txt
index fbce5a0..35d8417 100644
--- a/navigation3/navigation3-runtime/api/current.txt
+++ b/navigation3/navigation3-runtime/api/current.txt
@@ -2,9 +2,9 @@
 package androidx.navigation3.runtime {
 
   public final class DecoratedNavEntriesKt {
-    method @BytecodeOnly @androidx.compose.runtime.Composable public static <T> java.util.List<androidx.navigation3.runtime.NavEntry<T!>!> rememberDecoratedNavEntries(java.util.List<? extends androidx.navigation3.runtime.NavEntry<T!>!>, java.util.List<androidx.navigation3.runtime.NavEntryDecorator<T!>!>?, androidx.compose.runtime.Composer?, int, int);
-    method @BytecodeOnly @androidx.compose.runtime.Composable public static <T> java.util.List<androidx.navigation3.runtime.NavEntry<T!>!> rememberDecoratedNavEntries(java.util.List<? extends T!>, java.util.List<androidx.navigation3.runtime.NavEntryDecorator<T!>!>?, kotlin.jvm.functions.Function1<? super T!,? extends androidx.navigation3.runtime.NavEntry<T!>!>, androidx.compose.runtime.Composer?, int, int);
+    method @BytecodeOnly @androidx.compose.runtime.Composable public static <T> java.util.List<androidx.navigation3.runtime.NavEntry<T!>!> rememberDecoratedNavEntries(java.util.List<? extends T!>, java.util.List<androidx.navigation3.runtime.NavEntryDecorator<T!>!>?, kotlin.jvm.functions.Function1<? super T!,androidx.navigation3.runtime.NavEntry<T!>!>, androidx.compose.runtime.Composer?, int, int);
     method @KotlinOnly @androidx.compose.runtime.Composable public static <T> java.util.List<androidx.navigation3.runtime.NavEntry<T>> rememberDecoratedNavEntries(java.util.List<androidx.navigation3.runtime.NavEntry<T>> entries, optional java.util.List<androidx.navigation3.runtime.NavEntryDecorator<T>> entryDecorators);
+    method @BytecodeOnly @androidx.compose.runtime.Composable public static <T> java.util.List<androidx.navigation3.runtime.NavEntry<T!>!> rememberDecoratedNavEntries(java.util.List<androidx.navigation3.runtime.NavEntry<T!>!>, java.util.List<androidx.navigation3.runtime.NavEntryDecorator<T!>!>?, androidx.compose.runtime.Composer?, int, int);
     method @KotlinOnly @androidx.compose.runtime.Composable public static <T> java.util.List<androidx.navigation3.runtime.NavEntry<T>> rememberDecoratedNavEntries(java.util.List<T> backStack, optional java.util.List<androidx.navigation3.runtime.NavEntryDecorator<T>> entryDecorators, kotlin.jvm.functions.Function1<T,androidx.navigation3.runtime.NavEntry<T>> entryProvider);
   }
 
@@ -12,11 +12,11 @@
   }
 
   public final class EntryProviderKt {
-    method public static inline <T> kotlin.jvm.functions.Function1<T,androidx.navigation3.runtime.NavEntry<T>> entryProvider(optional kotlin.jvm.functions.Function1<? super T,? extends androidx.navigation3.runtime.NavEntry<T>> fallback, kotlin.jvm.functions.Function1<? super androidx.navigation3.runtime.EntryProviderScope<T>,kotlin.Unit> builder);
+    method public static inline <T> kotlin.jvm.functions.Function1<T,androidx.navigation3.runtime.NavEntry<T>> entryProvider(optional kotlin.jvm.functions.Function1<? super T,androidx.navigation3.runtime.NavEntry<T>> fallback, kotlin.jvm.functions.Function1<? super androidx.navigation3.runtime.EntryProviderScope<T>,kotlin.Unit> builder);
   }
 
   @androidx.navigation3.runtime.EntryDsl public final class EntryProviderScope<T> {
-    ctor public EntryProviderScope(kotlin.jvm.functions.Function1<? super T,? extends androidx.navigation3.runtime.NavEntry<T>> fallback);
+    ctor public EntryProviderScope(kotlin.jvm.functions.Function1<? super T,androidx.navigation3.runtime.NavEntry<T>> fallback);
     method public <K extends T> void addEntryProvider(K key, optional Object contentKey, optional java.util.Map<java.lang.String,?> metadata, kotlin.jvm.functions.Function1<? super K,kotlin.Unit> content);
     method @BytecodeOnly public <K extends T> void addEntryProvider(K, Object, java.util.Map<java.lang.String!,? extends java.lang.Object!>, kotlin.jvm.functions.Function3<? super K!,? super androidx.compose.runtime.Composer!,? super java.lang.Integer!,kotlin.Unit!>);
     method public <K extends T> void addEntryProvider(kotlin.reflect.KClass<? extends K> clazz, optional kotlin.jvm.functions.Function1<K,?> clazzContentKey, optional java.util.Map<java.lang.String,?> metadata, kotlin.jvm.functions.Function1<? super K,kotlin.Unit> content);
@@ -65,14 +65,16 @@
     property public int size;
   }
 
-  public class NavEntry<T> {
+  public final class NavEntry<T> {
+    ctor public NavEntry(androidx.navigation3.runtime.NavEntry<T> navEntry, kotlin.jvm.functions.Function1<? super T,kotlin.Unit> content);
+    ctor @BytecodeOnly public NavEntry(androidx.navigation3.runtime.NavEntry<T!>, kotlin.jvm.functions.Function3<? super T!,? super androidx.compose.runtime.Composer!,? super java.lang.Integer!,kotlin.Unit!>);
     ctor public NavEntry(T key, optional Object contentKey, optional java.util.Map<java.lang.String,?> metadata, kotlin.jvm.functions.Function1<? super T,kotlin.Unit> content);
     ctor @BytecodeOnly public NavEntry(T, Object, java.util.Map<java.lang.String!,? extends java.lang.Object!>, kotlin.jvm.functions.Function3<? super T!,? super androidx.compose.runtime.Composer!,? super java.lang.Integer!,kotlin.Unit!>);
     method @KotlinOnly @androidx.compose.runtime.Composable public void Content();
     method @BytecodeOnly @androidx.compose.runtime.Composable public void Content(androidx.compose.runtime.Composer?, int);
-    method @InaccessibleFromKotlin public final Object getContentKey();
+    method @InaccessibleFromKotlin public Object getContentKey();
     method @InaccessibleFromKotlin public java.util.Map<java.lang.String,java.lang.Object> getMetadata();
-    property public final Object contentKey;
+    property public Object contentKey;
     property public java.util.Map<java.lang.String,java.lang.Object> metadata;
   }
 
@@ -81,12 +83,6 @@
     ctor @BytecodeOnly public NavEntryDecorator(kotlin.jvm.functions.Function1<java.lang.Object!,kotlin.Unit!>, kotlin.jvm.functions.Function3<? super androidx.navigation3.runtime.NavEntry<T!>!,? super androidx.compose.runtime.Composer!,? super java.lang.Integer!,kotlin.Unit!>);
   }
 
-  public class NavEntryWrapper<T> extends androidx.navigation3.runtime.NavEntry<T> {
-    ctor public NavEntryWrapper(androidx.navigation3.runtime.NavEntry<T> navEntry);
-    method @InaccessibleFromKotlin public final androidx.navigation3.runtime.NavEntry<T> getNavEntry();
-    property public final androidx.navigation3.runtime.NavEntry<T> navEntry;
-  }
-
   public interface NavKey {
   }
 
@@ -102,8 +98,8 @@
   }
 
   public final class SaveableStateHolderNavEntryDecoratorKt {
-    method @KotlinOnly @androidx.compose.runtime.Composable public static <T> androidx.navigation3.runtime.NavEntryDecorator<T> rememberSaveableStateHolderNavEntryDecorator(optional androidx.compose.runtime.saveable.SaveableStateHolder saveableStateHolder);
-    method @BytecodeOnly @androidx.compose.runtime.Composable public static <T> androidx.navigation3.runtime.NavEntryDecorator<T!> rememberSaveableStateHolderNavEntryDecorator(androidx.compose.runtime.saveable.SaveableStateHolder?, androidx.compose.runtime.Composer?, int, int);
+    method @KotlinOnly @androidx.compose.runtime.Composable public static <T> androidx.navigation3.runtime.SaveableStateHolderNavEntryDecorator<T> rememberSaveableStateHolderNavEntryDecorator(optional androidx.compose.runtime.saveable.SaveableStateHolder saveableStateHolder);
+    method @BytecodeOnly @androidx.compose.runtime.Composable public static <T> androidx.navigation3.runtime.SaveableStateHolderNavEntryDecorator<T!> rememberSaveableStateHolderNavEntryDecorator(androidx.compose.runtime.saveable.SaveableStateHolder?, androidx.compose.runtime.Composer?, int, int);
   }
 
 }
diff --git a/navigation3/navigation3-runtime/api/restricted_current.txt b/navigation3/navigation3-runtime/api/restricted_current.txt
index b0ec8a9..e241a08 100644
--- a/navigation3/navigation3-runtime/api/restricted_current.txt
+++ b/navigation3/navigation3-runtime/api/restricted_current.txt
@@ -2,9 +2,9 @@
 package androidx.navigation3.runtime {
 
   public final class DecoratedNavEntriesKt {
-    method @BytecodeOnly @androidx.compose.runtime.Composable public static <T> java.util.List<androidx.navigation3.runtime.NavEntry<T!>!> rememberDecoratedNavEntries(java.util.List<? extends androidx.navigation3.runtime.NavEntry<T!>!>, java.util.List<androidx.navigation3.runtime.NavEntryDecorator<T!>!>?, androidx.compose.runtime.Composer?, int, int);
-    method @BytecodeOnly @androidx.compose.runtime.Composable public static <T> java.util.List<androidx.navigation3.runtime.NavEntry<T!>!> rememberDecoratedNavEntries(java.util.List<? extends T!>, java.util.List<androidx.navigation3.runtime.NavEntryDecorator<T!>!>?, kotlin.jvm.functions.Function1<? super T!,? extends androidx.navigation3.runtime.NavEntry<T!>!>, androidx.compose.runtime.Composer?, int, int);
+    method @BytecodeOnly @androidx.compose.runtime.Composable public static <T> java.util.List<androidx.navigation3.runtime.NavEntry<T!>!> rememberDecoratedNavEntries(java.util.List<? extends T!>, java.util.List<androidx.navigation3.runtime.NavEntryDecorator<T!>!>?, kotlin.jvm.functions.Function1<? super T!,androidx.navigation3.runtime.NavEntry<T!>!>, androidx.compose.runtime.Composer?, int, int);
     method @KotlinOnly @androidx.compose.runtime.Composable public static <T> java.util.List<androidx.navigation3.runtime.NavEntry<T>> rememberDecoratedNavEntries(java.util.List<androidx.navigation3.runtime.NavEntry<T>> entries, optional java.util.List<androidx.navigation3.runtime.NavEntryDecorator<T>> entryDecorators);
+    method @BytecodeOnly @androidx.compose.runtime.Composable public static <T> java.util.List<androidx.navigation3.runtime.NavEntry<T!>!> rememberDecoratedNavEntries(java.util.List<androidx.navigation3.runtime.NavEntry<T!>!>, java.util.List<androidx.navigation3.runtime.NavEntryDecorator<T!>!>?, androidx.compose.runtime.Composer?, int, int);
     method @KotlinOnly @androidx.compose.runtime.Composable public static <T> java.util.List<androidx.navigation3.runtime.NavEntry<T>> rememberDecoratedNavEntries(java.util.List<T> backStack, optional java.util.List<androidx.navigation3.runtime.NavEntryDecorator<T>> entryDecorators, kotlin.jvm.functions.Function1<T,androidx.navigation3.runtime.NavEntry<T>> entryProvider);
   }
 
@@ -12,11 +12,11 @@
   }
 
   public final class EntryProviderKt {
-    method public static inline <T> kotlin.jvm.functions.Function1<T,androidx.navigation3.runtime.NavEntry<T>> entryProvider(optional kotlin.jvm.functions.Function1<? super T,? extends androidx.navigation3.runtime.NavEntry<T>> fallback, kotlin.jvm.functions.Function1<? super androidx.navigation3.runtime.EntryProviderScope<T>,kotlin.Unit> builder);
+    method public static inline <T> kotlin.jvm.functions.Function1<T,androidx.navigation3.runtime.NavEntry<T>> entryProvider(optional kotlin.jvm.functions.Function1<? super T,androidx.navigation3.runtime.NavEntry<T>> fallback, kotlin.jvm.functions.Function1<? super androidx.navigation3.runtime.EntryProviderScope<T>,kotlin.Unit> builder);
   }
 
   @androidx.navigation3.runtime.EntryDsl public final class EntryProviderScope<T> {
-    ctor public EntryProviderScope(kotlin.jvm.functions.Function1<? super T,? extends androidx.navigation3.runtime.NavEntry<T>> fallback);
+    ctor public EntryProviderScope(kotlin.jvm.functions.Function1<? super T,androidx.navigation3.runtime.NavEntry<T>> fallback);
     method public <K extends T> void addEntryProvider(K key, optional Object contentKey, optional java.util.Map<java.lang.String,?> metadata, kotlin.jvm.functions.Function1<? super K,kotlin.Unit> content);
     method @BytecodeOnly public <K extends T> void addEntryProvider(K, Object, java.util.Map<java.lang.String!,? extends java.lang.Object!>, kotlin.jvm.functions.Function3<? super K!,? super androidx.compose.runtime.Composer!,? super java.lang.Integer!,kotlin.Unit!>);
     method public <K extends T> void addEntryProvider(kotlin.reflect.KClass<? extends K> clazz, optional kotlin.jvm.functions.Function1<K,?> clazzContentKey, optional java.util.Map<java.lang.String,?> metadata, kotlin.jvm.functions.Function1<? super K,kotlin.Unit> content);
@@ -66,14 +66,16 @@
     property public int size;
   }
 
-  public class NavEntry<T> {
+  public final class NavEntry<T> {
+    ctor public NavEntry(androidx.navigation3.runtime.NavEntry<T> navEntry, kotlin.jvm.functions.Function1<? super T,kotlin.Unit> content);
+    ctor @BytecodeOnly public NavEntry(androidx.navigation3.runtime.NavEntry<T!>, kotlin.jvm.functions.Function3<? super T!,? super androidx.compose.runtime.Composer!,? super java.lang.Integer!,kotlin.Unit!>);
     ctor public NavEntry(T key, optional Object contentKey, optional java.util.Map<java.lang.String,?> metadata, kotlin.jvm.functions.Function1<? super T,kotlin.Unit> content);
     ctor @BytecodeOnly public NavEntry(T, Object, java.util.Map<java.lang.String!,? extends java.lang.Object!>, kotlin.jvm.functions.Function3<? super T!,? super androidx.compose.runtime.Composer!,? super java.lang.Integer!,kotlin.Unit!>);
     method @KotlinOnly @androidx.compose.runtime.Composable public void Content();
     method @BytecodeOnly @androidx.compose.runtime.Composable public void Content(androidx.compose.runtime.Composer?, int);
-    method @InaccessibleFromKotlin public final Object getContentKey();
+    method @InaccessibleFromKotlin public Object getContentKey();
     method @InaccessibleFromKotlin public java.util.Map<java.lang.String,java.lang.Object> getMetadata();
-    property public final Object contentKey;
+    property public Object contentKey;
     property public java.util.Map<java.lang.String,java.lang.Object> metadata;
   }
 
@@ -86,12 +88,6 @@
     method @kotlin.PublishedApi internal static Object defaultContentKey(Object key);
   }
 
-  public class NavEntryWrapper<T> extends androidx.navigation3.runtime.NavEntry<T> {
-    ctor public NavEntryWrapper(androidx.navigation3.runtime.NavEntry<T> navEntry);
-    method @InaccessibleFromKotlin public final androidx.navigation3.runtime.NavEntry<T> getNavEntry();
-    property public final androidx.navigation3.runtime.NavEntry<T> navEntry;
-  }
-
   public interface NavKey {
   }
 
@@ -107,8 +103,8 @@
   }
 
   public final class SaveableStateHolderNavEntryDecoratorKt {
-    method @KotlinOnly @androidx.compose.runtime.Composable public static <T> androidx.navigation3.runtime.NavEntryDecorator<T> rememberSaveableStateHolderNavEntryDecorator(optional androidx.compose.runtime.saveable.SaveableStateHolder saveableStateHolder);
-    method @BytecodeOnly @androidx.compose.runtime.Composable public static <T> androidx.navigation3.runtime.NavEntryDecorator<T!> rememberSaveableStateHolderNavEntryDecorator(androidx.compose.runtime.saveable.SaveableStateHolder?, androidx.compose.runtime.Composer?, int, int);
+    method @KotlinOnly @androidx.compose.runtime.Composable public static <T> androidx.navigation3.runtime.SaveableStateHolderNavEntryDecorator<T> rememberSaveableStateHolderNavEntryDecorator(optional androidx.compose.runtime.saveable.SaveableStateHolder saveableStateHolder);
+    method @BytecodeOnly @androidx.compose.runtime.Composable public static <T> androidx.navigation3.runtime.SaveableStateHolderNavEntryDecorator<T!> rememberSaveableStateHolderNavEntryDecorator(androidx.compose.runtime.saveable.SaveableStateHolder?, androidx.compose.runtime.Composer?, int, int);
   }
 
 }
diff --git a/navigation3/navigation3-runtime/bcv/native/current.txt b/navigation3/navigation3-runtime/bcv/native/current.txt
index 2e13a5b..05111c7 100644
--- a/navigation3/navigation3-runtime/bcv/native/current.txt
+++ b/navigation3/navigation3-runtime/bcv/native/current.txt
@@ -66,54 +66,46 @@
     final inline fun <#A1: reified #A> entry(noinline kotlin/Function1<#A1, kotlin/Any> = ..., kotlin.collections/Map<kotlin/String, kotlin/Any> = ..., noinline kotlin/Function3<#A1, androidx.compose.runtime/Composer, kotlin/Int, kotlin/Unit>) // androidx.navigation3.runtime/EntryProviderScope.entry|entry(kotlin.Function1<0:0,kotlin.Any>;kotlin.collections.Map<kotlin.String,kotlin.Any>;kotlin.Function3<0:0,androidx.compose.runtime.Composer,kotlin.Int,kotlin.Unit>){0§<1:0>}[0]
 }
 
+final class <#A: kotlin/Any> androidx.navigation3.runtime/NavEntry { // androidx.navigation3.runtime/NavEntry|null[0]
+    constructor <init>(#A, kotlin/Any = ..., kotlin.collections/Map<kotlin/String, kotlin/Any> = ..., kotlin/Function3<#A, androidx.compose.runtime/Composer, kotlin/Int, kotlin/Unit>) // androidx.navigation3.runtime/NavEntry.<init>|<init>(1:0;kotlin.Any;kotlin.collections.Map<kotlin.String,kotlin.Any>;kotlin.Function3<1:0,androidx.compose.runtime.Composer,kotlin.Int,kotlin.Unit>){}[0]
+    constructor <init>(androidx.navigation3.runtime/NavEntry<#A>, kotlin/Function3<#A, androidx.compose.runtime/Composer, kotlin/Int, kotlin/Unit>) // androidx.navigation3.runtime/NavEntry.<init>|<init>(androidx.navigation3.runtime.NavEntry<1:0>;kotlin.Function3<1:0,androidx.compose.runtime.Composer,kotlin.Int,kotlin.Unit>){}[0]
+
+    final val contentKey // androidx.navigation3.runtime/NavEntry.contentKey|{}contentKey[0]
+        final fun <get-contentKey>(): kotlin/Any // androidx.navigation3.runtime/NavEntry.contentKey.<get-contentKey>|<get-contentKey>(){}[0]
+    final val metadata // androidx.navigation3.runtime/NavEntry.metadata|{}metadata[0]
+        final fun <get-metadata>(): kotlin.collections/Map<kotlin/String, kotlin/Any> // androidx.navigation3.runtime/NavEntry.metadata.<get-metadata>|<get-metadata>(){}[0]
+
+    final fun Content(androidx.compose.runtime/Composer?, kotlin/Int) // androidx.navigation3.runtime/NavEntry.Content|Content(androidx.compose.runtime.Composer?;kotlin.Int){}[0]
+    final fun equals(kotlin/Any?): kotlin/Boolean // androidx.navigation3.runtime/NavEntry.equals|equals(kotlin.Any?){}[0]
+    final fun hashCode(): kotlin/Int // androidx.navigation3.runtime/NavEntry.hashCode|hashCode(){}[0]
+    final fun toString(): kotlin/String // androidx.navigation3.runtime/NavEntry.toString|toString(){}[0]
+}
+
 final class <#A: kotlin/Any> androidx.navigation3.runtime/SaveableStateHolderNavEntryDecorator : androidx.navigation3.runtime/NavEntryDecorator<#A> { // androidx.navigation3.runtime/SaveableStateHolderNavEntryDecorator|null[0]
     constructor <init>(androidx.compose.runtime.saveable/SaveableStateHolder) // androidx.navigation3.runtime/SaveableStateHolderNavEntryDecorator.<init>|<init>(androidx.compose.runtime.saveable.SaveableStateHolder){}[0]
 }
 
-open class <#A: kotlin/Any> androidx.navigation3.runtime/NavEntry { // androidx.navigation3.runtime/NavEntry|null[0]
-    constructor <init>(#A, kotlin/Any = ..., kotlin.collections/Map<kotlin/String, kotlin/Any> = ..., kotlin/Function3<#A, androidx.compose.runtime/Composer, kotlin/Int, kotlin/Unit>) // androidx.navigation3.runtime/NavEntry.<init>|<init>(1:0;kotlin.Any;kotlin.collections.Map<kotlin.String,kotlin.Any>;kotlin.Function3<1:0,androidx.compose.runtime.Composer,kotlin.Int,kotlin.Unit>){}[0]
-
-    final val contentKey // androidx.navigation3.runtime/NavEntry.contentKey|{}contentKey[0]
-        final fun <get-contentKey>(): kotlin/Any // androidx.navigation3.runtime/NavEntry.contentKey.<get-contentKey>|<get-contentKey>(){}[0]
-    open val metadata // androidx.navigation3.runtime/NavEntry.metadata|{}metadata[0]
-        open fun <get-metadata>(): kotlin.collections/Map<kotlin/String, kotlin/Any> // androidx.navigation3.runtime/NavEntry.metadata.<get-metadata>|<get-metadata>(){}[0]
-
-    open fun Content(androidx.compose.runtime/Composer?, kotlin/Int) // androidx.navigation3.runtime/NavEntry.Content|Content(androidx.compose.runtime.Composer?;kotlin.Int){}[0]
-    open fun equals(kotlin/Any?): kotlin/Boolean // androidx.navigation3.runtime/NavEntry.equals|equals(kotlin.Any?){}[0]
-    open fun hashCode(): kotlin/Int // androidx.navigation3.runtime/NavEntry.hashCode|hashCode(){}[0]
-    open fun toString(): kotlin/String // androidx.navigation3.runtime/NavEntry.toString|toString(){}[0]
-}
-
 open class <#A: kotlin/Any> androidx.navigation3.runtime/NavEntryDecorator { // androidx.navigation3.runtime/NavEntryDecorator|null[0]
     constructor <init>(kotlin/Function1<kotlin/Any, kotlin/Unit> = ..., kotlin/Function3<androidx.navigation3.runtime/NavEntry<#A>, androidx.compose.runtime/Composer, kotlin/Int, kotlin/Unit>) // androidx.navigation3.runtime/NavEntryDecorator.<init>|<init>(kotlin.Function1<kotlin.Any,kotlin.Unit>;kotlin.Function3<androidx.navigation3.runtime.NavEntry<1:0>,androidx.compose.runtime.Composer,kotlin.Int,kotlin.Unit>){}[0]
 }
 
-open class <#A: kotlin/Any> androidx.navigation3.runtime/NavEntryWrapper : androidx.navigation3.runtime/NavEntry<#A> { // androidx.navigation3.runtime/NavEntryWrapper|null[0]
-    constructor <init>(androidx.navigation3.runtime/NavEntry<#A>) // androidx.navigation3.runtime/NavEntryWrapper.<init>|<init>(androidx.navigation3.runtime.NavEntry<1:0>){}[0]
-
-    final val navEntry // androidx.navigation3.runtime/NavEntryWrapper.navEntry|{}navEntry[0]
-        final fun <get-navEntry>(): androidx.navigation3.runtime/NavEntry<#A> // androidx.navigation3.runtime/NavEntryWrapper.navEntry.<get-navEntry>|<get-navEntry>(){}[0]
-}
-
 final val androidx.navigation3.runtime.serialization/androidx_navigation3_runtime_serialization_NavBackStackSerializer$stableprop // androidx.navigation3.runtime.serialization/androidx_navigation3_runtime_serialization_NavBackStackSerializer$stableprop|#static{}androidx_navigation3_runtime_serialization_NavBackStackSerializer$stableprop[0]
 final val androidx.navigation3.runtime/androidx_navigation3_runtime_EntryProviderScope$stableprop // androidx.navigation3.runtime/androidx_navigation3_runtime_EntryProviderScope$stableprop|#static{}androidx_navigation3_runtime_EntryProviderScope$stableprop[0]
 final val androidx.navigation3.runtime/androidx_navigation3_runtime_NavBackStack$stableprop // androidx.navigation3.runtime/androidx_navigation3_runtime_NavBackStack$stableprop|#static{}androidx_navigation3_runtime_NavBackStack$stableprop[0]
 final val androidx.navigation3.runtime/androidx_navigation3_runtime_NavEntry$stableprop // androidx.navigation3.runtime/androidx_navigation3_runtime_NavEntry$stableprop|#static{}androidx_navigation3_runtime_NavEntry$stableprop[0]
 final val androidx.navigation3.runtime/androidx_navigation3_runtime_NavEntryDecorator$stableprop // androidx.navigation3.runtime/androidx_navigation3_runtime_NavEntryDecorator$stableprop|#static{}androidx_navigation3_runtime_NavEntryDecorator$stableprop[0]
-final val androidx.navigation3.runtime/androidx_navigation3_runtime_NavEntryWrapper$stableprop // androidx.navigation3.runtime/androidx_navigation3_runtime_NavEntryWrapper$stableprop|#static{}androidx_navigation3_runtime_NavEntryWrapper$stableprop[0]
 final val androidx.navigation3.runtime/androidx_navigation3_runtime_SaveableStateHolderNavEntryDecorator$stableprop // androidx.navigation3.runtime/androidx_navigation3_runtime_SaveableStateHolderNavEntryDecorator$stableprop|#static{}androidx_navigation3_runtime_SaveableStateHolderNavEntryDecorator$stableprop[0]
 
 final fun <#A: kotlin/Any> androidx.navigation3.runtime/rememberDecoratedNavEntries(kotlin.collections/List<#A>, kotlin.collections/List<androidx.navigation3.runtime/NavEntryDecorator<#A>>?, kotlin/Function1<#A, androidx.navigation3.runtime/NavEntry<#A>>, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int): kotlin.collections/List<androidx.navigation3.runtime/NavEntry<#A>> // androidx.navigation3.runtime/rememberDecoratedNavEntries|rememberDecoratedNavEntries(kotlin.collections.List<0:0>;kotlin.collections.List<androidx.navigation3.runtime.NavEntryDecorator<0:0>>?;kotlin.Function1<0:0,androidx.navigation3.runtime.NavEntry<0:0>>;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int){0§<kotlin.Any>}[0]
 final fun <#A: kotlin/Any> androidx.navigation3.runtime/rememberDecoratedNavEntries(kotlin.collections/List<androidx.navigation3.runtime/NavEntry<#A>>, kotlin.collections/List<androidx.navigation3.runtime/NavEntryDecorator<#A>>?, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int): kotlin.collections/List<androidx.navigation3.runtime/NavEntry<#A>> // androidx.navigation3.runtime/rememberDecoratedNavEntries|rememberDecoratedNavEntries(kotlin.collections.List<androidx.navigation3.runtime.NavEntry<0:0>>;kotlin.collections.List<androidx.navigation3.runtime.NavEntryDecorator<0:0>>?;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int){0§<kotlin.Any>}[0]
-final fun <#A: kotlin/Any> androidx.navigation3.runtime/rememberSaveableStateHolderNavEntryDecorator(androidx.compose.runtime.saveable/SaveableStateHolder?, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int): androidx.navigation3.runtime/NavEntryDecorator<#A> // androidx.navigation3.runtime/rememberSaveableStateHolderNavEntryDecorator|rememberSaveableStateHolderNavEntryDecorator(androidx.compose.runtime.saveable.SaveableStateHolder?;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int){0§<kotlin.Any>}[0]
+final fun <#A: kotlin/Any> androidx.navigation3.runtime/rememberSaveableStateHolderNavEntryDecorator(androidx.compose.runtime.saveable/SaveableStateHolder?, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int): androidx.navigation3.runtime/SaveableStateHolderNavEntryDecorator<#A> // androidx.navigation3.runtime/rememberSaveableStateHolderNavEntryDecorator|rememberSaveableStateHolderNavEntryDecorator(androidx.compose.runtime.saveable.SaveableStateHolder?;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int){0§<kotlin.Any>}[0]
 final fun androidx.navigation3.runtime.serialization/androidx_navigation3_runtime_serialization_NavBackStackSerializer$stableprop_getter(): kotlin/Int // androidx.navigation3.runtime.serialization/androidx_navigation3_runtime_serialization_NavBackStackSerializer$stableprop_getter|androidx_navigation3_runtime_serialization_NavBackStackSerializer$stableprop_getter(){}[0]
 final fun androidx.navigation3.runtime/androidx_navigation3_runtime_EntryProviderScope$stableprop_getter(): kotlin/Int // androidx.navigation3.runtime/androidx_navigation3_runtime_EntryProviderScope$stableprop_getter|androidx_navigation3_runtime_EntryProviderScope$stableprop_getter(){}[0]
 final fun androidx.navigation3.runtime/androidx_navigation3_runtime_NavBackStack$stableprop_getter(): kotlin/Int // androidx.navigation3.runtime/androidx_navigation3_runtime_NavBackStack$stableprop_getter|androidx_navigation3_runtime_NavBackStack$stableprop_getter(){}[0]
 final fun androidx.navigation3.runtime/androidx_navigation3_runtime_NavEntry$stableprop_getter(): kotlin/Int // androidx.navigation3.runtime/androidx_navigation3_runtime_NavEntry$stableprop_getter|androidx_navigation3_runtime_NavEntry$stableprop_getter(){}[0]
 final fun androidx.navigation3.runtime/androidx_navigation3_runtime_NavEntryDecorator$stableprop_getter(): kotlin/Int // androidx.navigation3.runtime/androidx_navigation3_runtime_NavEntryDecorator$stableprop_getter|androidx_navigation3_runtime_NavEntryDecorator$stableprop_getter(){}[0]
-final fun androidx.navigation3.runtime/androidx_navigation3_runtime_NavEntryWrapper$stableprop_getter(): kotlin/Int // androidx.navigation3.runtime/androidx_navigation3_runtime_NavEntryWrapper$stableprop_getter|androidx_navigation3_runtime_NavEntryWrapper$stableprop_getter(){}[0]
 final fun androidx.navigation3.runtime/androidx_navigation3_runtime_SaveableStateHolderNavEntryDecorator$stableprop_getter(): kotlin/Int // androidx.navigation3.runtime/androidx_navigation3_runtime_SaveableStateHolderNavEntryDecorator$stableprop_getter|androidx_navigation3_runtime_SaveableStateHolderNavEntryDecorator$stableprop_getter(){}[0]
 final fun androidx.navigation3.runtime/defaultContentKey(kotlin/Any): kotlin/Any // androidx.navigation3.runtime/defaultContentKey|defaultContentKey(kotlin.Any){}[0]
 final fun androidx.navigation3.runtime/rememberNavBackStack(androidx.savedstate.serialization/SavedStateConfiguration, kotlin/Array<out androidx.navigation3.runtime/NavKey>..., androidx.compose.runtime/Composer?, kotlin/Int): androidx.navigation3.runtime/NavBackStack<androidx.navigation3.runtime/NavKey> // androidx.navigation3.runtime/rememberNavBackStack|rememberNavBackStack(androidx.savedstate.serialization.SavedStateConfiguration;kotlin.Array<out|androidx.navigation3.runtime.NavKey>...;androidx.compose.runtime.Composer?;kotlin.Int){}[0]
 final inline fun <#A: kotlin/Any> androidx.navigation3.runtime/entryProvider(noinline kotlin/Function1<#A, androidx.navigation3.runtime/NavEntry<#A>> = ..., kotlin/Function1<androidx.navigation3.runtime/EntryProviderScope<#A>, kotlin/Unit>): kotlin/Function1<#A, androidx.navigation3.runtime/NavEntry<#A>> // androidx.navigation3.runtime/entryProvider|entryProvider(kotlin.Function1<0:0,androidx.navigation3.runtime.NavEntry<0:0>>;kotlin.Function1<androidx.navigation3.runtime.EntryProviderScope<0:0>,kotlin.Unit>){0§<kotlin.Any>}[0]
-final inline fun <#A: reified androidx.navigation3.runtime/NavKey> androidx.navigation3.runtime.serialization/NavBackStackSerializer(): androidx.navigation3.runtime.serialization/NavBackStackSerializer<#A> // androidx.navigation3.runtime.serialization/NavBackStackSerializer|NavBackStackSerializer(){0§<androidx.navigation3.runtime.NavKey>}[0]
+final inline fun <#A: reified androidx.navigation3.runtime/NavKey> androidx.navigation3.runtime.serialization/NavBackStackSerializer(): androidx.navigation3.runtime.serialization/NavBackStackSerializer<#A> // androidx.navigation3.runtime.serialization/NavBackStackSerializer|NavBackStackSerializer(){0§<androidx.navigation3.runtime.NavKey>}[0]
\ No newline at end of file
diff --git a/navigation3/navigation3-runtime/src/androidInstrumentedTest/kotlin/androidx/navigation3/runtime/DecoratedNavEntriesTest.kt b/navigation3/navigation3-runtime/src/androidInstrumentedTest/kotlin/androidx/navigation3/runtime/DecoratedNavEntriesTest.kt
index bb49297..53d8190 100644
--- a/navigation3/navigation3-runtime/src/androidInstrumentedTest/kotlin/androidx/navigation3/runtime/DecoratedNavEntriesTest.kt
+++ b/navigation3/navigation3-runtime/src/androidInstrumentedTest/kotlin/androidx/navigation3/runtime/DecoratedNavEntriesTest.kt
@@ -42,7 +42,7 @@
         val state = mutableStateOf(2) // force into else branch
 
         val backStack = mutableStateListOf(1)
-        val entryDecorators = listOf(createTestNavEntryDecorator<Int> {})
+        val entryDecorators = listOf(NavEntryDecorator<Int> {})
         val entryProvider: (key: Int) -> NavEntry<Int> = { NavEntry(1) {} }
         composeTestRule.setContent {
             if (state.value == 1) {
@@ -64,7 +64,7 @@
         val state = mutableStateOf(1)
 
         val backStack = mutableStateListOf(1)
-        val entryDecorators = listOf(createTestNavEntryDecorator<Int> {})
+        val entryDecorators = listOf(NavEntryDecorator<Int> {})
         val entryProvider: (key: Int) -> NavEntry<Int> = { NavEntry(1) {} }
         composeTestRule.setContent {
             if (state.value == 1) {
@@ -84,16 +84,16 @@
     fun decorator_called() {
         var calledWrapContent = false
 
-        val decorator = createTestNavEntryDecorator<Any> { entry -> calledWrapContent = true }
+        val decorator = NavEntryDecorator<Any> { entry -> calledWrapContent = true }
 
         composeTestRule.setContent {
-            WithDecoratedNavEntries(
-                backStack = listOf("something"),
-                entryDecorators = listOf(decorator),
-                entryProvider = { NavEntry("something") {} },
-            ) { records ->
-                records.last().Content()
-            }
+            val entries =
+                rememberDecoratedNavEntries(
+                    backStack = listOf("something"),
+                    entryDecorators = listOf(decorator),
+                    entryProvider = { NavEntry("something") {} },
+                )
+            entries.last().Content()
         }
 
         assertThat(calledWrapContent).isTrue()
@@ -103,16 +103,16 @@
     fun decorator_calledOnce() {
         var calledWrapContentCount = 0
 
-        val decorator = createTestNavEntryDecorator<Any> { entry -> calledWrapContentCount++ }
+        val decorator = NavEntryDecorator<Any> { entry -> calledWrapContentCount++ }
 
         composeTestRule.setContent {
-            WithDecoratedNavEntries(
-                backStack = listOf("something"),
-                entryDecorators = listOf(decorator, decorator),
-                entryProvider = { NavEntry("something") {} },
-            ) { records ->
-                records.last().Content()
-            }
+            val entries =
+                rememberDecoratedNavEntries(
+                    backStack = listOf("something"),
+                    entryDecorators = listOf(decorator, decorator),
+                    entryProvider = { NavEntry("something") {} },
+                )
+            entries.last().Content()
         }
 
         composeTestRule.runOnIdle { assertThat(calledWrapContentCount).isEqualTo(1) }
@@ -124,25 +124,25 @@
         var outerEntryDecorator: Int = -1
         var innerEntryDecorator: Int = -1
         val innerDecorator =
-            createTestNavEntryDecorator<Any> { entry ->
+            NavEntryDecorator<Any> { entry ->
                 innerEntryDecorator = ++callOrder
                 entry.Content()
             }
 
         val outerDecorator =
-            createTestNavEntryDecorator<Any> { entry ->
+            NavEntryDecorator<Any> { entry ->
                 outerEntryDecorator = ++callOrder
                 entry.Content()
             }
 
         composeTestRule.setContent {
-            WithDecoratedNavEntries(
-                backStack = listOf("something"),
-                entryDecorators = listOf(outerDecorator, innerDecorator),
-                entryProvider = { NavEntry("something") {} },
-            ) { entries ->
-                entries.lastOrNull()?.Content()
-            }
+            val entries =
+                rememberDecoratedNavEntries(
+                    backStack = listOf("something"),
+                    entryDecorators = listOf(outerDecorator, innerDecorator),
+                    entryProvider = { NavEntry("something") {} },
+                )
+            entries.lastOrNull()?.Content()
         }
 
         composeTestRule.waitForIdle()
@@ -157,29 +157,25 @@
         var outerPop = -1
         var innerPop = -1
         val innerDecorator =
-            createTestNavEntryDecorator<Any>(onPop = { _ -> innerPop = ++count }) { entry ->
-                entry.Content()
-            }
+            NavEntryDecorator<Any>(onPop = { _ -> innerPop = ++count }) { entry -> entry.Content() }
         val outerDecorator =
-            createTestNavEntryDecorator<Any>(onPop = { _ -> outerPop = ++count }) { entry ->
-                entry.Content()
-            }
+            NavEntryDecorator<Any>(onPop = { _ -> outerPop = ++count }) { entry -> entry.Content() }
         lateinit var backStack: SnapshotStateList<Int>
         composeTestRule.setContent {
             backStack = remember { mutableStateListOf(1, 2) }
-            WithDecoratedNavEntries(
-                backStack = backStack,
-                entryDecorators = listOf(outerDecorator, innerDecorator),
-                entryProvider = { key ->
-                    when (key) {
-                        1 -> NavEntry(1) {}
-                        2 -> NavEntry(2) {}
-                        else -> error("Invalid Key")
-                    }
-                },
-            ) { entries ->
-                entries.lastOrNull()?.let { it.Content() }
-            }
+            val entries =
+                rememberDecoratedNavEntries(
+                    backStack = backStack,
+                    entryDecorators = listOf(outerDecorator, innerDecorator),
+                    entryProvider = { key ->
+                        when (key) {
+                            1 -> NavEntry(1) {}
+                            2 -> NavEntry(2) {}
+                            else -> error("Invalid Key")
+                        }
+                    },
+                )
+            entries.lastOrNull()?.Content()
         }
         composeTestRule.runOnIdle { backStack.removeAt(1) }
 
@@ -194,28 +190,26 @@
         val entriesRendered = mutableListOf<String>()
 
         val decorator =
-            createTestNavEntryDecorator<String>(
-                onPop = { key -> entriesOnPop.add(key as String) }
-            ) { entry ->
+            NavEntryDecorator<String>(onPop = { key -> entriesOnPop.add(key as String) }) { entry ->
                 entry.Content()
             }
         lateinit var backStack: SnapshotStateList<String>
         composeTestRule.setContent {
             backStack = remember { mutableStateListOf("first", "second", "third") }
-            WithDecoratedNavEntries(
-                backStack = backStack,
-                entryDecorators = listOf(decorator),
-                entryProvider = { key ->
-                    when (key) {
-                        "first" -> NavEntry("first", "first") { entriesRendered.add(it) }
-                        "second" -> NavEntry("second", "second") { entriesRendered.add(it) }
-                        "third" -> NavEntry("third", "third") { entriesRendered.add(it) }
-                        else -> error("Invalid Key")
-                    }
-                },
-            ) { entries ->
-                entries.lastOrNull()?.let { it.Content() }
-            }
+            val entries =
+                rememberDecoratedNavEntries(
+                    backStack = backStack,
+                    entryDecorators = listOf(decorator),
+                    entryProvider = { key ->
+                        when (key) {
+                            "first" -> NavEntry("first", "first") { entriesRendered.add(it) }
+                            "second" -> NavEntry("second", "second") { entriesRendered.add(it) }
+                            "third" -> NavEntry("third", "third") { entriesRendered.add(it) }
+                            else -> error("Invalid Key")
+                        }
+                    },
+                )
+            entries.lastOrNull()?.Content()
         }
 
         assertThat(entriesRendered).containsExactly("third")
@@ -235,33 +229,31 @@
     fun decorator_onPop_newlyAddedDecorator() {
         val decoratorPopCallback = mutableListOf<String>()
         val decorator1 =
-            createTestNavEntryDecorator<Any>(
-                onPop = { key -> decoratorPopCallback.add("decorator1") }
-            ) { entry ->
+            NavEntryDecorator<Any>(onPop = { key -> decoratorPopCallback.add("decorator1") }) {
+                entry ->
                 entry.Content()
             }
         val decorator2 =
-            createTestNavEntryDecorator<Any>(
-                onPop = { key -> decoratorPopCallback.add("decorator2") }
-            ) { entry ->
+            NavEntryDecorator<Any>(onPop = { key -> decoratorPopCallback.add("decorator2") }) {
+                entry ->
                 entry.Content()
             }
         val backStack = mutableStateListOf(1, 2)
         val decorators = mutableStateListOf(decorator1)
         composeTestRule.setContent {
-            WithDecoratedNavEntries(
-                backStack = backStack,
-                entryDecorators = decorators,
-                entryProvider = { key ->
-                    when (key) {
-                        1 -> NavEntry(1) {}
-                        2 -> NavEntry(2) {}
-                        else -> error("Invalid Key")
-                    }
-                },
-            ) { entries ->
-                entries.lastOrNull()?.let { it.Content() }
-            }
+            val entries =
+                rememberDecoratedNavEntries(
+                    backStack = backStack,
+                    entryDecorators = decorators,
+                    entryProvider = { key ->
+                        when (key) {
+                            1 -> NavEntry(1) {}
+                            2 -> NavEntry(2) {}
+                            else -> error("Invalid Key")
+                        }
+                    },
+                )
+            entries.lastOrNull()?.Content()
         }
 
         composeTestRule.waitForIdle()
@@ -284,33 +276,31 @@
     fun decorator_noOnPop_removedDecorator() {
         val decoratorPopCallback = mutableListOf<String>()
         val decorator1 =
-            createTestNavEntryDecorator<Any>(
-                onPop = { key -> decoratorPopCallback.add("decorator1") }
-            ) { entry ->
+            NavEntryDecorator<Any>(onPop = { key -> decoratorPopCallback.add("decorator1") }) {
+                entry ->
                 entry.Content()
             }
         val decorator2 =
-            createTestNavEntryDecorator<Any>(
-                onPop = { key -> decoratorPopCallback.add("decorator2") }
-            ) { entry ->
+            NavEntryDecorator<Any>(onPop = { key -> decoratorPopCallback.add("decorator2") }) {
+                entry ->
                 entry.Content()
             }
         val backStack = mutableStateListOf(1, 2)
         val decorators = mutableStateListOf(decorator1, decorator2)
         composeTestRule.setContent {
-            WithDecoratedNavEntries(
-                backStack = backStack,
-                entryDecorators = decorators,
-                entryProvider = { key ->
-                    when (key) {
-                        1 -> NavEntry(1) {}
-                        2 -> NavEntry(2) {}
-                        else -> error("Invalid Key")
-                    }
-                },
-            ) { entries ->
-                entries.lastOrNull()?.let { it.Content() }
-            }
+            val entries =
+                rememberDecoratedNavEntries(
+                    backStack = backStack,
+                    entryDecorators = decorators,
+                    entryProvider = { key ->
+                        when (key) {
+                            1 -> NavEntry(1) {}
+                            2 -> NavEntry(2) {}
+                            else -> error("Invalid Key")
+                        }
+                    },
+                )
+            entries.lastOrNull()?.Content()
         }
 
         composeTestRule.waitForIdle()
@@ -333,33 +323,31 @@
     fun decorator_noOnPop_atomicRemoveDecoratorAndPopEntry() {
         val decoratorPopCallback = mutableListOf<String>()
         val decorator1 =
-            createTestNavEntryDecorator<Any>(
-                onPop = { key -> decoratorPopCallback.add("decorator1") }
-            ) { entry ->
+            NavEntryDecorator<Any>(onPop = { key -> decoratorPopCallback.add("decorator1") }) {
+                entry ->
                 entry.Content()
             }
         val decorator2 =
-            createTestNavEntryDecorator<Any>(
-                onPop = { key -> decoratorPopCallback.add("decorator2") }
-            ) { entry ->
+            NavEntryDecorator<Any>(onPop = { key -> decoratorPopCallback.add("decorator2") }) {
+                entry ->
                 entry.Content()
             }
         val backStack = mutableStateListOf(1, 2)
         val decorators = mutableStateListOf(decorator1, decorator2)
         composeTestRule.setContent {
-            WithDecoratedNavEntries(
-                backStack = backStack,
-                entryDecorators = decorators,
-                entryProvider = { key ->
-                    when (key) {
-                        1 -> NavEntry(1) {}
-                        2 -> NavEntry(2) {}
-                        else -> error("Invalid Key")
-                    }
-                },
-            ) { entries ->
-                entries.lastOrNull()?.let { it.Content() }
-            }
+            val entries =
+                rememberDecoratedNavEntries(
+                    backStack = backStack,
+                    entryDecorators = decorators,
+                    entryProvider = { key ->
+                        when (key) {
+                            1 -> NavEntry(1) {}
+                            2 -> NavEntry(2) {}
+                            else -> error("Invalid Key")
+                        }
+                    },
+                )
+            entries.lastOrNull()?.Content()
         }
 
         composeTestRule.waitForIdle()
@@ -379,25 +367,25 @@
     fun decorator_wrapAddedEntry() {
         val wrappedEntries = mutableListOf<String>()
         val decorator =
-            createTestNavEntryDecorator<String> {
+            NavEntryDecorator<String> {
                 wrappedEntries.add(it.contentKey as String)
                 it.Content()
             }
         val backStack = mutableStateListOf("first")
         composeTestRule.setContent {
-            WithDecoratedNavEntries(
-                backStack = backStack,
-                entryDecorators = listOf(decorator),
-                entryProvider = {
-                    when (it) {
-                        "first" -> NavEntry("first", "first") {}
-                        "second" -> NavEntry("second", "second") {}
-                        else -> error("Unknown key")
-                    }
-                },
-            ) { entries ->
-                entries.lastOrNull()?.let { it.Content() }
-            }
+            val entries =
+                rememberDecoratedNavEntries(
+                    backStack = backStack,
+                    entryDecorators = listOf(decorator),
+                    entryProvider = {
+                        when (it) {
+                            "first" -> NavEntry("first", "first") {}
+                            "second" -> NavEntry("second", "second") {}
+                            else -> error("Unknown key")
+                        }
+                    },
+                )
+            entries.lastOrNull()?.Content()
         }
 
         composeTestRule.waitForIdle()
@@ -418,8 +406,8 @@
         val state = mutableStateOf(2) // force into else branch
 
         val backStack = mutableStateListOf(1)
-        val initialDecorators = listOf(createTestNavEntryDecorator<Int> {})
-        val additionalDecorators = listOf(createTestNavEntryDecorator<Int> {})
+        val initialDecorators = listOf(NavEntryDecorator<Int> {})
+        val additionalDecorators = listOf(NavEntryDecorator<Int> {})
         val entryProvider: (key: Int) -> NavEntry<Int> = { NavEntry(1) {} }
         composeTestRule.setContent {
             if (state.value == 1) {
@@ -447,8 +435,8 @@
         val state = mutableStateOf(1)
 
         val backStack = mutableStateListOf(1)
-        val initialDecorators = listOf(createTestNavEntryDecorator<Int> {})
-        val additionalDecorators = listOf(createTestNavEntryDecorator<Int> {})
+        val initialDecorators = listOf(NavEntryDecorator<Int> {})
+        val additionalDecorators = listOf(NavEntryDecorator<Int> {})
         val entryProvider: (key: Int) -> NavEntry<Int> = { NavEntry(1) {} }
         composeTestRule.setContent {
             if (state.value == 1) {
@@ -477,9 +465,9 @@
         var calledWrapContent = false
         var calledReWrapContent = false
 
-        val decorator = createTestNavEntryDecorator<Any> { entry -> calledWrapContent = true }
+        val decorator = NavEntryDecorator<Any> { entry -> calledWrapContent = true }
         val redecorator =
-            createTestNavEntryDecorator<Any> { entry ->
+            NavEntryDecorator<Any> { entry ->
                 calledReWrapContent = true
                 entry.Content()
             }
@@ -490,8 +478,8 @@
                 initialEntryDecorators = listOf(decorator),
                 additionalEntryDecorators = listOf(redecorator),
                 entryProvider = { NavEntry("something") {} },
-            ) { records ->
-                records.last().Content()
+            ) { entries ->
+                entries.last().Content()
             }
         }
 
@@ -504,9 +492,9 @@
         var calledWrapContentCount = 0
         var calledReWrapContentCount = 0
 
-        val decorator = createTestNavEntryDecorator<Any> { entry -> calledWrapContentCount++ }
+        val decorator = NavEntryDecorator<Any> { entry -> calledWrapContentCount++ }
         val redecorator =
-            createTestNavEntryDecorator<Any> { entry ->
+            NavEntryDecorator<Any> { entry ->
                 calledReWrapContentCount++
                 entry.Content()
             }
@@ -517,8 +505,8 @@
                 initialEntryDecorators = listOf(decorator),
                 additionalEntryDecorators = listOf(redecorator),
                 entryProvider = { NavEntry("something") {} },
-            ) { records ->
-                records.last().Content()
+            ) { entries ->
+                entries.last().Content()
             }
         }
 
@@ -532,10 +520,9 @@
         var outerEntryDecorator: Int = -1
         var innerEntryDecorator: Int = -1
 
-        val innerDecorator =
-            createTestNavEntryDecorator<Any> { entry -> innerEntryDecorator = ++callOrder }
+        val innerDecorator = NavEntryDecorator<Any> { entry -> innerEntryDecorator = ++callOrder }
         val outerDecorator =
-            createTestNavEntryDecorator<Any> { entry ->
+            NavEntryDecorator<Any> { entry ->
                 outerEntryDecorator = ++callOrder
                 entry.Content()
             }
@@ -546,8 +533,8 @@
                 initialEntryDecorators = listOf(innerDecorator),
                 additionalEntryDecorators = listOf(outerDecorator),
                 entryProvider = { NavEntry("something") {} },
-            ) { records ->
-                records.last().Content()
+            ) { entries ->
+                entries.last().Content()
             }
         }
 
@@ -562,11 +549,11 @@
         var decoratorPop = -1
 
         val decorator =
-            createTestNavEntryDecorator<Any>(onPop = { _ -> decoratorPop = ++count }) { entry ->
+            NavEntryDecorator<Any>(onPop = { _ -> decoratorPop = ++count }) { entry ->
                 entry.Content()
             }
         val redecorator =
-            createTestNavEntryDecorator<Any>(onPop = { _ -> redecoratorPop = ++count }) { entry ->
+            NavEntryDecorator<Any>(onPop = { _ -> redecoratorPop = ++count }) { entry ->
                 entry.Content()
             }
         lateinit var backStack: SnapshotStateList<Int>
@@ -584,8 +571,8 @@
                         else -> error("Invalid Key")
                     }
                 },
-            ) { records ->
-                records.last().Content()
+            ) { entries ->
+                entries.last().Content()
             }
         }
 
@@ -599,9 +586,9 @@
     @Test
     fun redecorator_wrapAddedEntry() {
         val wrappedEntries = mutableListOf<String>()
-        val decorator = createTestNavEntryDecorator<String> { it.Content() }
+        val decorator = NavEntryDecorator<String> { it.Content() }
         val redecorator =
-            createTestNavEntryDecorator<String> {
+            NavEntryDecorator<String> {
                 wrappedEntries.add(it.contentKey as String)
                 it.Content()
             }
@@ -639,24 +626,24 @@
         var dec1Wrapped = 0
         var dec2Wrapped = 0
         val decorator1 =
-            createTestNavEntryDecorator<Any> {
+            NavEntryDecorator<Any> {
                 dec1Wrapped++
                 it.Content()
             }
         val decorator2 =
-            createTestNavEntryDecorator<Any> {
+            NavEntryDecorator<Any> {
                 dec2Wrapped++
                 it.Content()
             }
         val decorators = mutableStateListOf(decorator1)
         composeTestRule.setContent {
-            WithDecoratedNavEntries(
-                backStack = listOf("something"),
-                entryDecorators = decorators,
-                entryProvider = { NavEntry("something") {} },
-            ) { entries ->
-                entries.lastOrNull()?.let { it.Content() }
-            }
+            val entries =
+                rememberDecoratedNavEntries(
+                    backStack = listOf("something"),
+                    entryDecorators = decorators,
+                    entryProvider = { NavEntry("something") {} },
+                )
+            entries.lastOrNull()?.Content()
         }
         composeTestRule.waitForIdle()
         assertThat(dec1Wrapped).isEqualTo(1)
@@ -674,24 +661,24 @@
         var dec1Wrapped = 0
         var dec2Wrapped = 0
         val decorator1 =
-            createTestNavEntryDecorator<Any> {
+            NavEntryDecorator<Any> {
                 dec1Wrapped++
                 it.Content()
             }
         val decorator2 =
-            createTestNavEntryDecorator<Any> {
+            NavEntryDecorator<Any> {
                 dec2Wrapped++
                 it.Content()
             }
         val decorators = mutableStateListOf(decorator1, decorator2)
         composeTestRule.setContent {
-            WithDecoratedNavEntries(
-                backStack = listOf("something"),
-                entryDecorators = decorators,
-                entryProvider = { NavEntry("something") {} },
-            ) { entries ->
-                entries.lastOrNull()?.let { it.Content() }
-            }
+            val entries =
+                rememberDecoratedNavEntries(
+                    backStack = listOf("something"),
+                    entryDecorators = decorators,
+                    entryProvider = { NavEntry("something") {} },
+                )
+            entries.lastOrNull()?.Content()
         }
         composeTestRule.waitForIdle()
         assertThat(dec1Wrapped).isEqualTo(1)
@@ -708,22 +695,19 @@
     fun decoratorState_differentContentKeySeparatesState() {
         val stateMap = mutableMapOf<Int, String>()
         val decorator =
-            createTestNavEntryDecorator<Any>(
-                onPop = { contentKey -> stateMap.remove(contentKey) }
-            ) { entry ->
+            NavEntryDecorator<Any>(onPop = { contentKey -> stateMap.remove(contentKey) }) { entry ->
                 stateMap.put(entry.contentKey as Int, "state")
                 entry.Content()
             }
-        lateinit var backStack: SnapshotStateList<Any>
+        val backStack: SnapshotStateList<Any> = mutableStateListOf(DataClass(1))
         composeTestRule.setContent {
-            backStack = mutableStateListOf(DataClass(1))
-            WithDecoratedNavEntries(
-                backStack = backStack,
-                entryDecorators = listOf(decorator),
-                entryProvider = entryProvider { entry<DataClass>({ it.arg }) {} },
-            ) { entries ->
-                entries.lastOrNull()?.Content()
-            }
+            val entries =
+                rememberDecoratedNavEntries(
+                    backStack = backStack,
+                    entryDecorators = listOf(decorator),
+                    entryProvider = entryProvider { entry<DataClass>({ it.arg }) {} },
+                )
+            entries.lastOrNull()?.Content()
         }
         composeTestRule.waitForIdle()
         assertThat(stateMap).containsExactly(1 to "state")
@@ -741,27 +725,24 @@
     fun decoratorState_sameContentKeySharedState() {
         var popCalled = false
         val decorator =
-            createTestNavEntryDecorator<Int>(onPop = { popCalled = true }) { entry ->
-                entry.Content()
-            }
+            NavEntryDecorator<Int>(onPop = { popCalled = true }) { entry -> entry.Content() }
         val entry1 = NavEntry(1, contentKey = "sameKey") {}
         val entry2 = NavEntry(2, contentKey = "sameKey") {}
-        lateinit var backStack: SnapshotStateList<Int>
+        val backStack = mutableStateListOf(1, 2)
         composeTestRule.setContent {
-            backStack = mutableStateListOf(1, 2)
-            WithDecoratedNavEntries(
-                backStack = backStack,
-                entryDecorators = listOf(decorator),
-                entryProvider = { key ->
-                    when (key) {
-                        1 -> entry1
-                        2 -> entry2
-                        else -> error("Invalid Key")
-                    }
-                },
-            ) { entries ->
-                entries.lastOrNull()?.let { it.Content() }
-            }
+            val entries =
+                rememberDecoratedNavEntries(
+                    backStack = backStack,
+                    entryDecorators = listOf(decorator),
+                    entryProvider = { key ->
+                        when (key) {
+                            1 -> entry1
+                            2 -> entry2
+                            else -> error("Invalid Key")
+                        }
+                    },
+                )
+            entries.lastOrNull()?.Content()
         }
         assertThat(entry1.contentKey).isEqualTo(entry2.contentKey)
         composeTestRule.runOnIdle { backStack.removeAt(backStack.lastIndex) }
@@ -786,9 +767,8 @@
                 }
             val entryDecorators =
                 listOf(
-                    createTestNavEntryDecorator<Any>(
-                        onPop = { contentKey -> stateMap.remove(contentKey) }
-                    ) { entry ->
+                    NavEntryDecorator<Any>(onPop = { contentKey -> stateMap.remove(contentKey) }) {
+                        entry ->
                         stateMap.put(entry.contentKey as Int, "state")
                         entry.Content()
                     }
@@ -824,9 +804,8 @@
                 }
             val entryDecorators =
                 listOf(
-                    createTestNavEntryDecorator<Any>(
-                        onPop = { contentKey -> stateMap.remove(contentKey) }
-                    ) { entry ->
+                    NavEntryDecorator<Any>(onPop = { contentKey -> stateMap.remove(contentKey) }) {
+                        entry ->
                         stateMap.put(entry.contentKey as Int, "state")
                         entry.Content()
                     }
@@ -862,9 +841,8 @@
                 }
             val entryDecorators =
                 listOf(
-                    createTestNavEntryDecorator<Any>(
-                        onPop = { contentKey -> stateMap.remove(contentKey) }
-                    ) { entry ->
+                    NavEntryDecorator<Any>(onPop = { contentKey -> stateMap.remove(contentKey) }) {
+                        entry ->
                         stateMap.put(entry.contentKey as Int, "state")
                         entry.Content()
                     }
@@ -905,7 +883,7 @@
                     backStack = backStack,
                     entryDecorators =
                         listOf(
-                            createTestNavEntryDecorator<Any>(
+                            NavEntryDecorator<Any>(
                                 onPop = { contentKey ->
                                     stateMap.remove(contentKey)
                                     popCalled = true
@@ -940,9 +918,8 @@
         composeTestRule.setContent {
             backStackState = remember { mutableStateOf(1) }
             val decorator =
-                createTestNavEntryDecorator<Any>(
-                    onPop = { contentKey -> stateMap.remove(contentKey) }
-                ) { entry ->
+                NavEntryDecorator<Any>(onPop = { contentKey -> stateMap.remove(contentKey) }) {
+                    entry ->
                     stateMap.put(entry.contentKey as Int, "state")
                     entry.Content()
                 }
@@ -978,9 +955,8 @@
         val backStack = mutableStateListOf(key1, key2)
         val entryDecorators =
             listOf(
-                createTestNavEntryDecorator<Any>(
-                    onPop = { contentKey -> stateMap.remove(contentKey) }
-                ) { entry ->
+                NavEntryDecorator<Any>(onPop = { contentKey -> stateMap.remove(contentKey) }) {
+                    entry ->
                     stateMap.put(entry.contentKey as Int, "state")
                     entry.Content()
                 }
@@ -1010,7 +986,7 @@
         val backStack = mutableStateListOf(key1, key2, key2)
         val entryDecorators =
             listOf(
-                createTestNavEntryDecorator<Any>(
+                NavEntryDecorator<Any>(
                     onPop = { contentKey ->
                         popCalled = true
                         stateMap.remove(contentKey)
@@ -1047,9 +1023,8 @@
         val backStack = mutableStateListOf(key1, key2, key2)
         val entryDecorators =
             listOf(
-                createTestNavEntryDecorator<Any>(
-                    onPop = { contentKey -> stateMap.remove(contentKey) }
-                ) { entry ->
+                NavEntryDecorator<Any>(onPop = { contentKey -> stateMap.remove(contentKey) }) {
+                    entry ->
                     stateMap.put(entry.contentKey as Int, "state")
                     entry.Content()
                 }
@@ -1084,7 +1059,7 @@
         val previousState = mutableMapOf<Int, String>()
         val previousDecorator =
             listOf(
-                createTestNavEntryDecorator<Any>(
+                NavEntryDecorator<Any>(
                     onPop = { contentKey -> previousState.remove(contentKey) }
                 ) { entry ->
                     previousState.put(entry.contentKey as Int, "state")
@@ -1095,9 +1070,8 @@
         val newState = mutableMapOf<Int, String>()
         val newDecorator =
             listOf(
-                createTestNavEntryDecorator<Any>(
-                    onPop = { contentKey -> newState.remove(contentKey) }
-                ) { entry ->
+                NavEntryDecorator<Any>(onPop = { contentKey -> newState.remove(contentKey) }) {
+                    entry ->
                     newState.put(entry.contentKey as Int, "state")
                     entry.Content()
                 }
@@ -1131,7 +1105,7 @@
         val previousState = mutableMapOf<Int, String>()
         val previousDecorator =
             listOf(
-                createTestNavEntryDecorator<Any>(
+                NavEntryDecorator<Any>(
                     onPop = { contentKey -> previousState.remove(contentKey) }
                 ) { entry ->
                     previousState.put(entry.contentKey as Int, "state")
@@ -1142,9 +1116,8 @@
         val newState = mutableMapOf<Int, String>()
         val newDecorator =
             listOf(
-                createTestNavEntryDecorator<Any>(
-                    onPop = { contentKey -> newState.remove(contentKey) }
-                ) { entry ->
+                NavEntryDecorator<Any>(onPop = { contentKey -> newState.remove(contentKey) }) {
+                    entry ->
                     newState.put(entry.contentKey as Int, "state")
                     entry.Content()
                 }
@@ -1181,9 +1154,8 @@
 
         val entryDecorator =
             listOf(
-                createTestNavEntryDecorator<Any>(
-                    onPop = { contentKey -> currentState.remove(contentKey) }
-                ) { entry ->
+                NavEntryDecorator<Any>(onPop = { contentKey -> currentState.remove(contentKey) }) {
+                    entry ->
                     currentState.put(entry.contentKey as Int, "state")
                     entry.Content()
                 }
@@ -1738,17 +1710,6 @@
 }
 
 @Composable
-private fun <T : Any> WithDecoratedNavEntries(
-    backStack: List<T>,
-    entryDecorators: List<NavEntryDecorator<T>> = listOf(),
-    entryProvider: (key: T) -> NavEntry<T>,
-    content: @Composable (List<NavEntry<T>>) -> Unit,
-) {
-    val decoratedEntries = rememberDecoratedNavEntries(backStack, entryDecorators, entryProvider)
-    content(decoratedEntries)
-}
-
-@Composable
 private fun <T : Any> WithRedecoratedNavEntries(
     backStack: List<T>,
     initialEntryDecorators: List<@JvmSuppressWildcards NavEntryDecorator<T>> = listOf(),
diff --git a/navigation3/navigation3-runtime/src/commonMain/kotlin/androidx/navigation3/runtime/DecoratedNavEntries.kt b/navigation3/navigation3-runtime/src/commonMain/kotlin/androidx/navigation3/runtime/DecoratedNavEntries.kt
index 1b2b987..a95e5d8 100644
--- a/navigation3/navigation3-runtime/src/commonMain/kotlin/androidx/navigation3/runtime/DecoratedNavEntries.kt
+++ b/navigation3/navigation3-runtime/src/commonMain/kotlin/androidx/navigation3/runtime/DecoratedNavEntries.kt
@@ -172,8 +172,7 @@
         }
 
     PrepareBackStack(decoratedEntries, entryDecorators, keysInBackstack, keysInComposition)
-    @Suppress("ListIterator")
-    return remember(entries.toList(), entryDecorators.toList()) { decoratedEntries }
+    return decoratedEntries
 }
 
 /**
@@ -192,44 +191,33 @@
     keysInComposition: MutableSet<Any>,
 ): NavEntry<T> {
     val latestDecorators by rememberUpdatedState(decorators)
-    val initial =
-        object : NavEntryWrapper<T>(entry) {
-            @Composable
-            override fun Content() {
-                val keysInComposition = keysInComposition
-                // track if entry is in backstack and/or still in composition
-                DisposableEffect(key1 = contentKey) {
-                    keysInComposition.add(contentKey)
-                    onDispose {
-                        val notInComposition = keysInComposition.remove(contentKey)
-                        val popped = !keysInBackstack.contains(contentKey)
-                        if (popped && notInComposition) {
-                            // we reverse the scopes before popping to imitate the order
-                            // of onDispose calls if each scope/decorator had their own
-                            // onDispose
-                            // calls for clean up
-                            // convert to mutableList first for backwards compat.
-                            latestDecorators.fastForEachReversedOrForEachReversed {
-                                it.onPop(contentKey)
-                            }
-                        }
-                    }
+    val contentKey = entry.contentKey
+    return NavEntry(navEntry = entry) {
+        val keysInComposition = keysInComposition
+        // track if entry is in backstack and/or still in composition
+        DisposableEffect(key1 = contentKey) {
+            keysInComposition.add(contentKey)
+            onDispose {
+                val notInComposition = keysInComposition.remove(contentKey)
+                val popped = !keysInBackstack.contains(contentKey)
+                if (popped && notInComposition) {
+                    // we reverse the scopes before popping to imitate the order
+                    // of onDispose calls if each scope/decorator had their own
+                    // onDispose
+                    // calls for clean up
+                    // convert to mutableList first for backwards compat.
+                    latestDecorators.fastForEachReversedOrForEachReversed { it.onPop(contentKey) }
                 }
-                // wrap entry with decorators then invoke Content
-                decorators
-                    .fastDistinctOrDistinct()
-                    .foldRight(initial = entry) { decorator, wrappedEntry ->
-                        object : NavEntryWrapper<T>(wrappedEntry) {
-                            @Composable
-                            override fun Content() {
-                                decorator.decorate(wrappedEntry)
-                            }
-                        }
-                    }
-                    .Content()
             }
         }
-    return initial
+        // wrap entry with decorators then invoke Content
+        decorators
+            .fastDistinctOrDistinct()
+            .foldRight(initial = entry) { decorator, wrappedEntry ->
+                NavEntry<T>(wrappedEntry) { decorator.decorate(wrappedEntry) }
+            }
+            .Content()
+    }
 }
 
 /**
diff --git a/navigation3/navigation3-runtime/src/commonMain/kotlin/androidx/navigation3/runtime/NavEntry.kt b/navigation3/navigation3-runtime/src/commonMain/kotlin/androidx/navigation3/runtime/NavEntry.kt
index b9ee445..390c4e7 100644
--- a/navigation3/navigation3-runtime/src/commonMain/kotlin/androidx/navigation3/runtime/NavEntry.kt
+++ b/navigation3/navigation3-runtime/src/commonMain/kotlin/androidx/navigation3/runtime/NavEntry.kt
@@ -36,23 +36,30 @@
  * @param metadata provides information to the display
  * @param content content for this entry to be displayed when this entry is active
  */
-public open class NavEntry<T : Any>(
+public class NavEntry<T : Any>(
     private val key: T,
     public val contentKey: Any = defaultContentKey(key),
-    public open val metadata: Map<String, Any> = emptyMap(),
+    public val metadata: Map<String, Any> = emptyMap(),
     private val content: @Composable (T) -> Unit,
 ) {
-    /** Allows creating a NavEntry from another NavEntry while keeping [content] field private */
-    internal constructor(
-        navEntry: NavEntry<T>
-    ) : this(navEntry.key, navEntry.contentKey, navEntry.metadata, navEntry.content)
+    /**
+     * NavEntry constructor to create a NavEntry from another NavEntry
+     *
+     * @param navEntry The entry that provides the [key], [contentKey], and [metadata] for the new
+     *   entry.
+     * @param content content for this entry to be displayed when this entry is active
+     */
+    public constructor(
+        navEntry: NavEntry<T>,
+        content: @Composable (T) -> Unit,
+    ) : this(navEntry.key, navEntry.contentKey, navEntry.metadata, content)
 
     /**
      * Invokes the composable content of this NavEntry with the key that was provided when
      * instantiating this NavEntry
      */
     @Composable
-    public open fun Content() {
+    public fun Content() {
         this.content(key)
     }
 
@@ -62,15 +69,21 @@
 
         other as NavEntry<*>
 
-        return key == other.key && contentKey == other.contentKey && metadata == other.metadata
+        return key == other.key &&
+            contentKey == other.contentKey &&
+            metadata == other.metadata &&
+            content === other.content
     }
 
     override fun hashCode(): Int {
-        return key.hashCode() * 31 + contentKey.hashCode() * 31 + metadata.hashCode() * 31
+        return key.hashCode() * 31 +
+            contentKey.hashCode() * 31 +
+            metadata.hashCode() * 31 +
+            content.hashCode() * 31
     }
 
     override fun toString(): String {
-        return "NavEntry(key=$key, contentKey=$contentKey, metadata=$metadata)"
+        return "NavEntry(key=$key, contentKey=$contentKey, metadata=$metadata, content=$content)"
     }
 }
 
diff --git a/navigation3/navigation3-runtime/src/commonMain/kotlin/androidx/navigation3/runtime/NavEntryWrapper.kt b/navigation3/navigation3-runtime/src/commonMain/kotlin/androidx/navigation3/runtime/NavEntryWrapper.kt
deleted file mode 100644
index 273f733..0000000
--- a/navigation3/navigation3-runtime/src/commonMain/kotlin/androidx/navigation3/runtime/NavEntryWrapper.kt
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright 2025 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 androidx.navigation3.runtime
-
-/**
- * Class that wraps a [NavEntry] within another [NavEntry].
- *
- * This provides a nesting mechanism for [NavEntry]s that allows properly nested content.
- *
- * @param T the type of the backStack key
- * @param navEntry the [NavEntry] to wrap
- */
-public open class NavEntryWrapper<T : Any>(public val navEntry: NavEntry<T>) :
-    NavEntry<T>(navEntry)
diff --git a/navigation3/navigation3-runtime/src/commonMain/kotlin/androidx/navigation3/runtime/SaveableStateHolderNavEntryDecorator.kt b/navigation3/navigation3-runtime/src/commonMain/kotlin/androidx/navigation3/runtime/SaveableStateHolderNavEntryDecorator.kt
index d681adf..fe447ef 100644
--- a/navigation3/navigation3-runtime/src/commonMain/kotlin/androidx/navigation3/runtime/SaveableStateHolderNavEntryDecorator.kt
+++ b/navigation3/navigation3-runtime/src/commonMain/kotlin/androidx/navigation3/runtime/SaveableStateHolderNavEntryDecorator.kt
@@ -32,7 +32,8 @@
 @Composable
 public fun <T : Any> rememberSaveableStateHolderNavEntryDecorator(
     saveableStateHolder: SaveableStateHolder = rememberSaveableStateHolder()
-): NavEntryDecorator<T> = remember { SaveableStateHolderNavEntryDecorator(saveableStateHolder) }
+): SaveableStateHolderNavEntryDecorator<T> =
+    remember(saveableStateHolder) { SaveableStateHolderNavEntryDecorator(saveableStateHolder) }
 
 /**
  * Wraps the content of a [NavEntry] with a [SaveableStateHolder.SaveableStateProvider] to ensure
diff --git a/navigation3/navigation3-ui/api/current.txt b/navigation3/navigation3-ui/api/current.txt
index 286dbcd..a19f8b1 100644
--- a/navigation3/navigation3-ui/api/current.txt
+++ b/navigation3/navigation3-ui/api/current.txt
@@ -3,8 +3,7 @@
 
   public final class DialogSceneStrategy<T> implements androidx.navigation3.scene.SceneStrategy<T> {
     ctor public DialogSceneStrategy();
-    method @BytecodeOnly @androidx.compose.runtime.Composable public androidx.navigation3.scene.Scene<T!>? calculateScene(java.util.List<? extends androidx.navigation3.runtime.NavEntry<T!>!>, kotlin.jvm.functions.Function0<kotlin.Unit!>, androidx.compose.runtime.Composer?, int);
-    method @KotlinOnly @androidx.compose.runtime.Composable public androidx.navigation3.scene.Scene<T>? calculateScene(java.util.List<androidx.navigation3.runtime.NavEntry<T>> entries, kotlin.jvm.functions.Function0<kotlin.Unit> onBack);
+    method public androidx.navigation3.scene.Scene<T>? calculateScene(androidx.navigation3.scene.SceneStrategyScope<T>, java.util.List<androidx.navigation3.runtime.NavEntry<T>> entries);
     field public static final androidx.navigation3.scene.DialogSceneStrategy.Companion Companion;
   }
 
@@ -48,20 +47,25 @@
   }
 
   public final class SceneStateKt {
-    method @BytecodeOnly @androidx.compose.runtime.Composable public static <T> androidx.navigation3.scene.SceneState<T!> rememberSceneState(java.util.List<? extends androidx.navigation3.runtime.NavEntry<T!>!>, androidx.navigation3.scene.SceneStrategy<T!>, kotlin.jvm.functions.Function0<kotlin.Unit!>, androidx.compose.runtime.Composer?, int);
     method @KotlinOnly @androidx.compose.runtime.Composable public static <T> androidx.navigation3.scene.SceneState<T> rememberSceneState(java.util.List<androidx.navigation3.runtime.NavEntry<T>> entries, androidx.navigation3.scene.SceneStrategy<T> sceneStrategy, kotlin.jvm.functions.Function0<kotlin.Unit> onBack);
+    method @BytecodeOnly @androidx.compose.runtime.Composable public static <T> androidx.navigation3.scene.SceneState<T!> rememberSceneState(java.util.List<androidx.navigation3.runtime.NavEntry<T!>!>, androidx.navigation3.scene.SceneStrategy<T!>, kotlin.jvm.functions.Function0<kotlin.Unit!>, androidx.compose.runtime.Composer?, int);
   }
 
   public fun interface SceneStrategy<T> {
-    method @BytecodeOnly @androidx.compose.runtime.Composable public androidx.navigation3.scene.Scene<T!>? calculateScene(java.util.List<? extends androidx.navigation3.runtime.NavEntry<T!>!>, kotlin.jvm.functions.Function0<kotlin.Unit!>, androidx.compose.runtime.Composer?, int);
-    method @KotlinOnly @androidx.compose.runtime.Composable public androidx.navigation3.scene.Scene<T>? calculateScene(java.util.List<androidx.navigation3.runtime.NavEntry<T>> entries, kotlin.jvm.functions.Function0<kotlin.Unit> onBack);
+    method public androidx.navigation3.scene.Scene<T>? calculateScene(androidx.navigation3.scene.SceneStrategyScope<T>, java.util.List<androidx.navigation3.runtime.NavEntry<T>> entries);
     method public default infix androidx.navigation3.scene.SceneStrategy<T> then(androidx.navigation3.scene.SceneStrategy<T> sceneStrategy);
   }
 
+  public final class SceneStrategyScope<T> {
+    ctor public SceneStrategyScope();
+    ctor public SceneStrategyScope(optional kotlin.jvm.functions.Function0<kotlin.Unit> onBack);
+    method @InaccessibleFromKotlin public kotlin.jvm.functions.Function0<kotlin.Unit> getOnBack();
+    property public kotlin.jvm.functions.Function0<kotlin.Unit> onBack;
+  }
+
   public final class SinglePaneSceneStrategy<T> implements androidx.navigation3.scene.SceneStrategy<T> {
     ctor public SinglePaneSceneStrategy();
-    method @BytecodeOnly @androidx.compose.runtime.Composable public androidx.navigation3.scene.Scene<T!> calculateScene(java.util.List<? extends androidx.navigation3.runtime.NavEntry<T!>!>, kotlin.jvm.functions.Function0<kotlin.Unit!>, androidx.compose.runtime.Composer?, int);
-    method @KotlinOnly @androidx.compose.runtime.Composable public androidx.navigation3.scene.Scene<T> calculateScene(java.util.List<androidx.navigation3.runtime.NavEntry<T>> entries, kotlin.jvm.functions.Function0<kotlin.Unit> onBack);
+    method public androidx.navigation3.scene.Scene<T> calculateScene(androidx.navigation3.scene.SceneStrategyScope<T>, java.util.List<androidx.navigation3.runtime.NavEntry<T>> entries);
   }
 
 }
@@ -83,8 +87,8 @@
   public final class NavDisplayKt {
     method @BytecodeOnly @androidx.compose.runtime.Composable @androidx.compose.runtime.ComposableTarget(applier="androidx.compose.ui.UiComposable") public static <T> void NavDisplay(androidx.navigation3.scene.SceneState<T!>, androidx.navigationevent.compose.NavigationEventState<androidx.navigation3.scene.SceneInfo<T!>!>, androidx.compose.ui.Modifier?, androidx.compose.ui.Alignment?, androidx.compose.animation.SizeTransform?, kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation3.scene.Scene<T!>!>!,androidx.compose.animation.ContentTransform!>?, kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation3.scene.Scene<T!>!>!,androidx.compose.animation.ContentTransform!>?, kotlin.jvm.functions.Function2<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation3.scene.Scene<T!>!>!,? super java.lang.Integer!,androidx.compose.animation.ContentTransform!>?, androidx.compose.runtime.Composer?, int, int);
     method @KotlinOnly @androidx.compose.runtime.Composable public static <T> void NavDisplay(androidx.navigation3.scene.SceneState<T> sceneState, androidx.navigationevent.compose.NavigationEventState<androidx.navigation3.scene.SceneInfo<T>> navigationEventState, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.Alignment contentAlignment, optional androidx.compose.animation.SizeTransform? sizeTransform, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation3.scene.Scene<T>>,androidx.compose.animation.ContentTransform> transitionSpec, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation3.scene.Scene<T>>,androidx.compose.animation.ContentTransform> popTransitionSpec, optional kotlin.jvm.functions.Function2<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation3.scene.Scene<T>>,java.lang.Integer,androidx.compose.animation.ContentTransform> predictivePopTransitionSpec);
-    method @BytecodeOnly @androidx.compose.runtime.Composable public static <T> void NavDisplay(java.util.List<? extends androidx.navigation3.runtime.NavEntry<T!>!>, androidx.compose.ui.Modifier?, androidx.compose.ui.Alignment?, androidx.navigation3.scene.SceneStrategy<T!>?, androidx.compose.animation.SizeTransform?, kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation3.scene.Scene<T!>!>!,androidx.compose.animation.ContentTransform!>?, kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation3.scene.Scene<T!>!>!,androidx.compose.animation.ContentTransform!>?, kotlin.jvm.functions.Function2<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation3.scene.Scene<T!>!>!,? super java.lang.Integer!,androidx.compose.animation.ContentTransform!>?, kotlin.jvm.functions.Function0<kotlin.Unit!>, androidx.compose.runtime.Composer?, int, int);
-    method @BytecodeOnly @androidx.compose.runtime.Composable public static <T> void NavDisplay(java.util.List<? extends T!>, androidx.compose.ui.Modifier?, androidx.compose.ui.Alignment?, kotlin.jvm.functions.Function0<kotlin.Unit!>?, java.util.List<? extends androidx.navigation3.runtime.NavEntryDecorator<T!>!>?, androidx.navigation3.scene.SceneStrategy<T!>?, androidx.compose.animation.SizeTransform?, kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation3.scene.Scene<T!>!>!,androidx.compose.animation.ContentTransform!>?, kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation3.scene.Scene<T!>!>!,androidx.compose.animation.ContentTransform!>?, kotlin.jvm.functions.Function2<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation3.scene.Scene<T!>!>!,? super java.lang.Integer!,androidx.compose.animation.ContentTransform!>?, kotlin.jvm.functions.Function1<? super T!,? extends androidx.navigation3.runtime.NavEntry<T!>!>, androidx.compose.runtime.Composer?, int, int, int);
+    method @BytecodeOnly @androidx.compose.runtime.Composable public static <T> void NavDisplay(java.util.List<? extends T!>, androidx.compose.ui.Modifier?, androidx.compose.ui.Alignment?, kotlin.jvm.functions.Function0<kotlin.Unit!>?, java.util.List<? extends androidx.navigation3.runtime.NavEntryDecorator<T!>!>?, androidx.navigation3.scene.SceneStrategy<T!>?, androidx.compose.animation.SizeTransform?, kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation3.scene.Scene<T!>!>!,androidx.compose.animation.ContentTransform!>?, kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation3.scene.Scene<T!>!>!,androidx.compose.animation.ContentTransform!>?, kotlin.jvm.functions.Function2<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation3.scene.Scene<T!>!>!,? super java.lang.Integer!,androidx.compose.animation.ContentTransform!>?, kotlin.jvm.functions.Function1<? super T!,androidx.navigation3.runtime.NavEntry<T!>!>, androidx.compose.runtime.Composer?, int, int, int);
+    method @BytecodeOnly @androidx.compose.runtime.Composable public static <T> void NavDisplay(java.util.List<androidx.navigation3.runtime.NavEntry<T!>!>, androidx.compose.ui.Modifier?, androidx.compose.ui.Alignment?, androidx.navigation3.scene.SceneStrategy<T!>?, androidx.compose.animation.SizeTransform?, kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation3.scene.Scene<T!>!>!,androidx.compose.animation.ContentTransform!>?, kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation3.scene.Scene<T!>!>!,androidx.compose.animation.ContentTransform!>?, kotlin.jvm.functions.Function2<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation3.scene.Scene<T!>!>!,? super java.lang.Integer!,androidx.compose.animation.ContentTransform!>?, kotlin.jvm.functions.Function0<kotlin.Unit!>, androidx.compose.runtime.Composer?, int, int);
     method @KotlinOnly @androidx.compose.runtime.Composable public static <T> void NavDisplay(java.util.List<androidx.navigation3.runtime.NavEntry<T>> entries, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.Alignment contentAlignment, optional androidx.navigation3.scene.SceneStrategy<T> sceneStrategy, optional androidx.compose.animation.SizeTransform? sizeTransform, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation3.scene.Scene<T>>,androidx.compose.animation.ContentTransform> transitionSpec, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation3.scene.Scene<T>>,androidx.compose.animation.ContentTransform> popTransitionSpec, optional kotlin.jvm.functions.Function2<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation3.scene.Scene<T>>,java.lang.Integer,androidx.compose.animation.ContentTransform> predictivePopTransitionSpec, kotlin.jvm.functions.Function0<kotlin.Unit> onBack);
     method @KotlinOnly @androidx.compose.runtime.Composable public static <T> void NavDisplay(java.util.List<T> backStack, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.Alignment contentAlignment, optional kotlin.jvm.functions.Function0<kotlin.Unit> onBack, optional java.util.List<androidx.navigation3.runtime.NavEntryDecorator<T>> entryDecorators, optional androidx.navigation3.scene.SceneStrategy<T> sceneStrategy, optional androidx.compose.animation.SizeTransform? sizeTransform, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation3.scene.Scene<T>>,androidx.compose.animation.ContentTransform> transitionSpec, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation3.scene.Scene<T>>,androidx.compose.animation.ContentTransform> popTransitionSpec, optional kotlin.jvm.functions.Function2<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation3.scene.Scene<T>>,java.lang.Integer,androidx.compose.animation.ContentTransform> predictivePopTransitionSpec, kotlin.jvm.functions.Function1<T,androidx.navigation3.runtime.NavEntry<T>> entryProvider);
     method public static <T> kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation3.scene.Scene<T>>,androidx.compose.animation.ContentTransform> defaultPopTransitionSpec();
diff --git a/navigation3/navigation3-ui/api/restricted_current.txt b/navigation3/navigation3-ui/api/restricted_current.txt
index 286dbcd..a19f8b1 100644
--- a/navigation3/navigation3-ui/api/restricted_current.txt
+++ b/navigation3/navigation3-ui/api/restricted_current.txt
@@ -3,8 +3,7 @@
 
   public final class DialogSceneStrategy<T> implements androidx.navigation3.scene.SceneStrategy<T> {
     ctor public DialogSceneStrategy();
-    method @BytecodeOnly @androidx.compose.runtime.Composable public androidx.navigation3.scene.Scene<T!>? calculateScene(java.util.List<? extends androidx.navigation3.runtime.NavEntry<T!>!>, kotlin.jvm.functions.Function0<kotlin.Unit!>, androidx.compose.runtime.Composer?, int);
-    method @KotlinOnly @androidx.compose.runtime.Composable public androidx.navigation3.scene.Scene<T>? calculateScene(java.util.List<androidx.navigation3.runtime.NavEntry<T>> entries, kotlin.jvm.functions.Function0<kotlin.Unit> onBack);
+    method public androidx.navigation3.scene.Scene<T>? calculateScene(androidx.navigation3.scene.SceneStrategyScope<T>, java.util.List<androidx.navigation3.runtime.NavEntry<T>> entries);
     field public static final androidx.navigation3.scene.DialogSceneStrategy.Companion Companion;
   }
 
@@ -48,20 +47,25 @@
   }
 
   public final class SceneStateKt {
-    method @BytecodeOnly @androidx.compose.runtime.Composable public static <T> androidx.navigation3.scene.SceneState<T!> rememberSceneState(java.util.List<? extends androidx.navigation3.runtime.NavEntry<T!>!>, androidx.navigation3.scene.SceneStrategy<T!>, kotlin.jvm.functions.Function0<kotlin.Unit!>, androidx.compose.runtime.Composer?, int);
     method @KotlinOnly @androidx.compose.runtime.Composable public static <T> androidx.navigation3.scene.SceneState<T> rememberSceneState(java.util.List<androidx.navigation3.runtime.NavEntry<T>> entries, androidx.navigation3.scene.SceneStrategy<T> sceneStrategy, kotlin.jvm.functions.Function0<kotlin.Unit> onBack);
+    method @BytecodeOnly @androidx.compose.runtime.Composable public static <T> androidx.navigation3.scene.SceneState<T!> rememberSceneState(java.util.List<androidx.navigation3.runtime.NavEntry<T!>!>, androidx.navigation3.scene.SceneStrategy<T!>, kotlin.jvm.functions.Function0<kotlin.Unit!>, androidx.compose.runtime.Composer?, int);
   }
 
   public fun interface SceneStrategy<T> {
-    method @BytecodeOnly @androidx.compose.runtime.Composable public androidx.navigation3.scene.Scene<T!>? calculateScene(java.util.List<? extends androidx.navigation3.runtime.NavEntry<T!>!>, kotlin.jvm.functions.Function0<kotlin.Unit!>, androidx.compose.runtime.Composer?, int);
-    method @KotlinOnly @androidx.compose.runtime.Composable public androidx.navigation3.scene.Scene<T>? calculateScene(java.util.List<androidx.navigation3.runtime.NavEntry<T>> entries, kotlin.jvm.functions.Function0<kotlin.Unit> onBack);
+    method public androidx.navigation3.scene.Scene<T>? calculateScene(androidx.navigation3.scene.SceneStrategyScope<T>, java.util.List<androidx.navigation3.runtime.NavEntry<T>> entries);
     method public default infix androidx.navigation3.scene.SceneStrategy<T> then(androidx.navigation3.scene.SceneStrategy<T> sceneStrategy);
   }
 
+  public final class SceneStrategyScope<T> {
+    ctor public SceneStrategyScope();
+    ctor public SceneStrategyScope(optional kotlin.jvm.functions.Function0<kotlin.Unit> onBack);
+    method @InaccessibleFromKotlin public kotlin.jvm.functions.Function0<kotlin.Unit> getOnBack();
+    property public kotlin.jvm.functions.Function0<kotlin.Unit> onBack;
+  }
+
   public final class SinglePaneSceneStrategy<T> implements androidx.navigation3.scene.SceneStrategy<T> {
     ctor public SinglePaneSceneStrategy();
-    method @BytecodeOnly @androidx.compose.runtime.Composable public androidx.navigation3.scene.Scene<T!> calculateScene(java.util.List<? extends androidx.navigation3.runtime.NavEntry<T!>!>, kotlin.jvm.functions.Function0<kotlin.Unit!>, androidx.compose.runtime.Composer?, int);
-    method @KotlinOnly @androidx.compose.runtime.Composable public androidx.navigation3.scene.Scene<T> calculateScene(java.util.List<androidx.navigation3.runtime.NavEntry<T>> entries, kotlin.jvm.functions.Function0<kotlin.Unit> onBack);
+    method public androidx.navigation3.scene.Scene<T> calculateScene(androidx.navigation3.scene.SceneStrategyScope<T>, java.util.List<androidx.navigation3.runtime.NavEntry<T>> entries);
   }
 
 }
@@ -83,8 +87,8 @@
   public final class NavDisplayKt {
     method @BytecodeOnly @androidx.compose.runtime.Composable @androidx.compose.runtime.ComposableTarget(applier="androidx.compose.ui.UiComposable") public static <T> void NavDisplay(androidx.navigation3.scene.SceneState<T!>, androidx.navigationevent.compose.NavigationEventState<androidx.navigation3.scene.SceneInfo<T!>!>, androidx.compose.ui.Modifier?, androidx.compose.ui.Alignment?, androidx.compose.animation.SizeTransform?, kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation3.scene.Scene<T!>!>!,androidx.compose.animation.ContentTransform!>?, kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation3.scene.Scene<T!>!>!,androidx.compose.animation.ContentTransform!>?, kotlin.jvm.functions.Function2<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation3.scene.Scene<T!>!>!,? super java.lang.Integer!,androidx.compose.animation.ContentTransform!>?, androidx.compose.runtime.Composer?, int, int);
     method @KotlinOnly @androidx.compose.runtime.Composable public static <T> void NavDisplay(androidx.navigation3.scene.SceneState<T> sceneState, androidx.navigationevent.compose.NavigationEventState<androidx.navigation3.scene.SceneInfo<T>> navigationEventState, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.Alignment contentAlignment, optional androidx.compose.animation.SizeTransform? sizeTransform, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation3.scene.Scene<T>>,androidx.compose.animation.ContentTransform> transitionSpec, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation3.scene.Scene<T>>,androidx.compose.animation.ContentTransform> popTransitionSpec, optional kotlin.jvm.functions.Function2<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation3.scene.Scene<T>>,java.lang.Integer,androidx.compose.animation.ContentTransform> predictivePopTransitionSpec);
-    method @BytecodeOnly @androidx.compose.runtime.Composable public static <T> void NavDisplay(java.util.List<? extends androidx.navigation3.runtime.NavEntry<T!>!>, androidx.compose.ui.Modifier?, androidx.compose.ui.Alignment?, androidx.navigation3.scene.SceneStrategy<T!>?, androidx.compose.animation.SizeTransform?, kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation3.scene.Scene<T!>!>!,androidx.compose.animation.ContentTransform!>?, kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation3.scene.Scene<T!>!>!,androidx.compose.animation.ContentTransform!>?, kotlin.jvm.functions.Function2<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation3.scene.Scene<T!>!>!,? super java.lang.Integer!,androidx.compose.animation.ContentTransform!>?, kotlin.jvm.functions.Function0<kotlin.Unit!>, androidx.compose.runtime.Composer?, int, int);
-    method @BytecodeOnly @androidx.compose.runtime.Composable public static <T> void NavDisplay(java.util.List<? extends T!>, androidx.compose.ui.Modifier?, androidx.compose.ui.Alignment?, kotlin.jvm.functions.Function0<kotlin.Unit!>?, java.util.List<? extends androidx.navigation3.runtime.NavEntryDecorator<T!>!>?, androidx.navigation3.scene.SceneStrategy<T!>?, androidx.compose.animation.SizeTransform?, kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation3.scene.Scene<T!>!>!,androidx.compose.animation.ContentTransform!>?, kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation3.scene.Scene<T!>!>!,androidx.compose.animation.ContentTransform!>?, kotlin.jvm.functions.Function2<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation3.scene.Scene<T!>!>!,? super java.lang.Integer!,androidx.compose.animation.ContentTransform!>?, kotlin.jvm.functions.Function1<? super T!,? extends androidx.navigation3.runtime.NavEntry<T!>!>, androidx.compose.runtime.Composer?, int, int, int);
+    method @BytecodeOnly @androidx.compose.runtime.Composable public static <T> void NavDisplay(java.util.List<? extends T!>, androidx.compose.ui.Modifier?, androidx.compose.ui.Alignment?, kotlin.jvm.functions.Function0<kotlin.Unit!>?, java.util.List<? extends androidx.navigation3.runtime.NavEntryDecorator<T!>!>?, androidx.navigation3.scene.SceneStrategy<T!>?, androidx.compose.animation.SizeTransform?, kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation3.scene.Scene<T!>!>!,androidx.compose.animation.ContentTransform!>?, kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation3.scene.Scene<T!>!>!,androidx.compose.animation.ContentTransform!>?, kotlin.jvm.functions.Function2<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation3.scene.Scene<T!>!>!,? super java.lang.Integer!,androidx.compose.animation.ContentTransform!>?, kotlin.jvm.functions.Function1<? super T!,androidx.navigation3.runtime.NavEntry<T!>!>, androidx.compose.runtime.Composer?, int, int, int);
+    method @BytecodeOnly @androidx.compose.runtime.Composable public static <T> void NavDisplay(java.util.List<androidx.navigation3.runtime.NavEntry<T!>!>, androidx.compose.ui.Modifier?, androidx.compose.ui.Alignment?, androidx.navigation3.scene.SceneStrategy<T!>?, androidx.compose.animation.SizeTransform?, kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation3.scene.Scene<T!>!>!,androidx.compose.animation.ContentTransform!>?, kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation3.scene.Scene<T!>!>!,androidx.compose.animation.ContentTransform!>?, kotlin.jvm.functions.Function2<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation3.scene.Scene<T!>!>!,? super java.lang.Integer!,androidx.compose.animation.ContentTransform!>?, kotlin.jvm.functions.Function0<kotlin.Unit!>, androidx.compose.runtime.Composer?, int, int);
     method @KotlinOnly @androidx.compose.runtime.Composable public static <T> void NavDisplay(java.util.List<androidx.navigation3.runtime.NavEntry<T>> entries, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.Alignment contentAlignment, optional androidx.navigation3.scene.SceneStrategy<T> sceneStrategy, optional androidx.compose.animation.SizeTransform? sizeTransform, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation3.scene.Scene<T>>,androidx.compose.animation.ContentTransform> transitionSpec, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation3.scene.Scene<T>>,androidx.compose.animation.ContentTransform> popTransitionSpec, optional kotlin.jvm.functions.Function2<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation3.scene.Scene<T>>,java.lang.Integer,androidx.compose.animation.ContentTransform> predictivePopTransitionSpec, kotlin.jvm.functions.Function0<kotlin.Unit> onBack);
     method @KotlinOnly @androidx.compose.runtime.Composable public static <T> void NavDisplay(java.util.List<T> backStack, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.Alignment contentAlignment, optional kotlin.jvm.functions.Function0<kotlin.Unit> onBack, optional java.util.List<androidx.navigation3.runtime.NavEntryDecorator<T>> entryDecorators, optional androidx.navigation3.scene.SceneStrategy<T> sceneStrategy, optional androidx.compose.animation.SizeTransform? sizeTransform, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation3.scene.Scene<T>>,androidx.compose.animation.ContentTransform> transitionSpec, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation3.scene.Scene<T>>,androidx.compose.animation.ContentTransform> popTransitionSpec, optional kotlin.jvm.functions.Function2<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation3.scene.Scene<T>>,java.lang.Integer,androidx.compose.animation.ContentTransform> predictivePopTransitionSpec, kotlin.jvm.functions.Function1<T,androidx.navigation3.runtime.NavEntry<T>> entryProvider);
     method public static <T> kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation3.scene.Scene<T>>,androidx.compose.animation.ContentTransform> defaultPopTransitionSpec();
diff --git a/navigation3/navigation3-ui/bcv/native/current.txt b/navigation3/navigation3-ui/bcv/native/current.txt
index dabd4b6..cb8cca6 100644
--- a/navigation3/navigation3-ui/bcv/native/current.txt
+++ b/navigation3/navigation3-ui/bcv/native/current.txt
@@ -7,7 +7,7 @@
 
 // Library unique name: <androidx.navigation3:navigation3-ui>
 abstract fun interface <#A: kotlin/Any> androidx.navigation3.scene/SceneStrategy { // androidx.navigation3.scene/SceneStrategy|null[0]
-    abstract fun calculateScene(kotlin.collections/List<androidx.navigation3.runtime/NavEntry<#A>>, kotlin/Function0<kotlin/Unit>, androidx.compose.runtime/Composer?, kotlin/Int): androidx.navigation3.scene/Scene<#A>? // androidx.navigation3.scene/SceneStrategy.calculateScene|calculateScene(kotlin.collections.List<androidx.navigation3.runtime.NavEntry<1:0>>;kotlin.Function0<kotlin.Unit>;androidx.compose.runtime.Composer?;kotlin.Int){}[0]
+    abstract fun (androidx.navigation3.scene/SceneStrategyScope<#A>).calculateScene(kotlin.collections/List<androidx.navigation3.runtime/NavEntry<#A>>): androidx.navigation3.scene/Scene<#A>? // androidx.navigation3.scene/SceneStrategy.calculateScene|calculateScene@androidx.navigation3.scene.SceneStrategyScope<1:0>(kotlin.collections.List<androidx.navigation3.runtime.NavEntry<1:0>>){}[0]
     open fun then(androidx.navigation3.scene/SceneStrategy<#A>): androidx.navigation3.scene/SceneStrategy<#A> // androidx.navigation3.scene/SceneStrategy.then|then(androidx.navigation3.scene.SceneStrategy<1:0>){}[0]
 }
 
@@ -32,7 +32,7 @@
 final class <#A: kotlin/Any> androidx.navigation3.scene/DialogSceneStrategy : androidx.navigation3.scene/SceneStrategy<#A> { // androidx.navigation3.scene/DialogSceneStrategy|null[0]
     constructor <init>() // androidx.navigation3.scene/DialogSceneStrategy.<init>|<init>(){}[0]
 
-    final fun calculateScene(kotlin.collections/List<androidx.navigation3.runtime/NavEntry<#A>>, kotlin/Function0<kotlin/Unit>, androidx.compose.runtime/Composer?, kotlin/Int): androidx.navigation3.scene/Scene<#A>? // androidx.navigation3.scene/DialogSceneStrategy.calculateScene|calculateScene(kotlin.collections.List<androidx.navigation3.runtime.NavEntry<1:0>>;kotlin.Function0<kotlin.Unit>;androidx.compose.runtime.Composer?;kotlin.Int){}[0]
+    final fun (androidx.navigation3.scene/SceneStrategyScope<#A>).calculateScene(kotlin.collections/List<androidx.navigation3.runtime/NavEntry<#A>>): androidx.navigation3.scene/Scene<#A>? // androidx.navigation3.scene/DialogSceneStrategy.calculateScene|calculateScene@androidx.navigation3.scene.SceneStrategyScope<1:0>(kotlin.collections.List<androidx.navigation3.runtime.NavEntry<1:0>>){}[0]
 
     final object Companion { // androidx.navigation3.scene/DialogSceneStrategy.Companion|null[0]
         final fun dialog(androidx.compose.ui.window/DialogProperties = ...): kotlin.collections/Map<kotlin/String, kotlin/Any> // androidx.navigation3.scene/DialogSceneStrategy.Companion.dialog|dialog(androidx.compose.ui.window.DialogProperties){}[0]
@@ -65,10 +65,17 @@
     final fun toString(): kotlin/String // androidx.navigation3.scene/SceneState.toString|toString(){}[0]
 }
 
+final class <#A: kotlin/Any> androidx.navigation3.scene/SceneStrategyScope { // androidx.navigation3.scene/SceneStrategyScope|null[0]
+    constructor <init>(kotlin/Function0<kotlin/Unit> = ...) // androidx.navigation3.scene/SceneStrategyScope.<init>|<init>(kotlin.Function0<kotlin.Unit>){}[0]
+
+    final val onBack // androidx.navigation3.scene/SceneStrategyScope.onBack|{}onBack[0]
+        final fun <get-onBack>(): kotlin/Function0<kotlin/Unit> // androidx.navigation3.scene/SceneStrategyScope.onBack.<get-onBack>|<get-onBack>(){}[0]
+}
+
 final class <#A: kotlin/Any> androidx.navigation3.scene/SinglePaneSceneStrategy : androidx.navigation3.scene/SceneStrategy<#A> { // androidx.navigation3.scene/SinglePaneSceneStrategy|null[0]
     constructor <init>() // androidx.navigation3.scene/SinglePaneSceneStrategy.<init>|<init>(){}[0]
 
-    final fun calculateScene(kotlin.collections/List<androidx.navigation3.runtime/NavEntry<#A>>, kotlin/Function0<kotlin/Unit>, androidx.compose.runtime/Composer?, kotlin/Int): androidx.navigation3.scene/Scene<#A> // androidx.navigation3.scene/SinglePaneSceneStrategy.calculateScene|calculateScene(kotlin.collections.List<androidx.navigation3.runtime.NavEntry<1:0>>;kotlin.Function0<kotlin.Unit>;androidx.compose.runtime.Composer?;kotlin.Int){}[0]
+    final fun (androidx.navigation3.scene/SceneStrategyScope<#A>).calculateScene(kotlin.collections/List<androidx.navigation3.runtime/NavEntry<#A>>): androidx.navigation3.scene/Scene<#A> // androidx.navigation3.scene/SinglePaneSceneStrategy.calculateScene|calculateScene@androidx.navigation3.scene.SceneStrategyScope<1:0>(kotlin.collections.List<androidx.navigation3.runtime.NavEntry<1:0>>){}[0]
 }
 
 final object androidx.navigation3.ui/NavDisplay { // androidx.navigation3.ui/NavDisplay|null[0]
@@ -82,6 +89,7 @@
 final val androidx.navigation3.scene/androidx_navigation3_scene_SceneInfo$stableprop // androidx.navigation3.scene/androidx_navigation3_scene_SceneInfo$stableprop|#static{}androidx_navigation3_scene_SceneInfo$stableprop[0]
 final val androidx.navigation3.scene/androidx_navigation3_scene_SceneSetupNavEntryDecorator$stableprop // androidx.navigation3.scene/androidx_navigation3_scene_SceneSetupNavEntryDecorator$stableprop|#static{}androidx_navigation3_scene_SceneSetupNavEntryDecorator$stableprop[0]
 final val androidx.navigation3.scene/androidx_navigation3_scene_SceneState$stableprop // androidx.navigation3.scene/androidx_navigation3_scene_SceneState$stableprop|#static{}androidx_navigation3_scene_SceneState$stableprop[0]
+final val androidx.navigation3.scene/androidx_navigation3_scene_SceneStrategyScope$stableprop // androidx.navigation3.scene/androidx_navigation3_scene_SceneStrategyScope$stableprop|#static{}androidx_navigation3_scene_SceneStrategyScope$stableprop[0]
 final val androidx.navigation3.scene/androidx_navigation3_scene_SinglePaneScene$stableprop // androidx.navigation3.scene/androidx_navigation3_scene_SinglePaneScene$stableprop|#static{}androidx_navigation3_scene_SinglePaneScene$stableprop[0]
 final val androidx.navigation3.scene/androidx_navigation3_scene_SinglePaneSceneStrategy$stableprop // androidx.navigation3.scene/androidx_navigation3_scene_SinglePaneSceneStrategy$stableprop|#static{}androidx_navigation3_scene_SinglePaneSceneStrategy$stableprop[0]
 final val androidx.navigation3.ui/LocalNavAnimatedContentScope // androidx.navigation3.ui/LocalNavAnimatedContentScope|{}LocalNavAnimatedContentScope[0]
@@ -100,6 +108,7 @@
 final fun androidx.navigation3.scene/androidx_navigation3_scene_SceneInfo$stableprop_getter(): kotlin/Int // androidx.navigation3.scene/androidx_navigation3_scene_SceneInfo$stableprop_getter|androidx_navigation3_scene_SceneInfo$stableprop_getter(){}[0]
 final fun androidx.navigation3.scene/androidx_navigation3_scene_SceneSetupNavEntryDecorator$stableprop_getter(): kotlin/Int // androidx.navigation3.scene/androidx_navigation3_scene_SceneSetupNavEntryDecorator$stableprop_getter|androidx_navigation3_scene_SceneSetupNavEntryDecorator$stableprop_getter(){}[0]
 final fun androidx.navigation3.scene/androidx_navigation3_scene_SceneState$stableprop_getter(): kotlin/Int // androidx.navigation3.scene/androidx_navigation3_scene_SceneState$stableprop_getter|androidx_navigation3_scene_SceneState$stableprop_getter(){}[0]
+final fun androidx.navigation3.scene/androidx_navigation3_scene_SceneStrategyScope$stableprop_getter(): kotlin/Int // androidx.navigation3.scene/androidx_navigation3_scene_SceneStrategyScope$stableprop_getter|androidx_navigation3_scene_SceneStrategyScope$stableprop_getter(){}[0]
 final fun androidx.navigation3.scene/androidx_navigation3_scene_SinglePaneScene$stableprop_getter(): kotlin/Int // androidx.navigation3.scene/androidx_navigation3_scene_SinglePaneScene$stableprop_getter|androidx_navigation3_scene_SinglePaneScene$stableprop_getter(){}[0]
 final fun androidx.navigation3.scene/androidx_navigation3_scene_SinglePaneSceneStrategy$stableprop_getter(): kotlin/Int // androidx.navigation3.scene/androidx_navigation3_scene_SinglePaneSceneStrategy$stableprop_getter|androidx_navigation3_scene_SinglePaneSceneStrategy$stableprop_getter(){}[0]
 final fun androidx.navigation3.ui/androidx_navigation3_ui_NavDisplay$stableprop_getter(): kotlin/Int // androidx.navigation3.ui/androidx_navigation3_ui_NavDisplay$stableprop_getter|androidx_navigation3_ui_NavDisplay$stableprop_getter(){}[0]
diff --git a/navigation3/navigation3-ui/integration-tests/navigation3-demos/src/main/kotlin/androidx/navigation3/demos/HierarchicalSceneSample.kt b/navigation3/navigation3-ui/integration-tests/navigation3-demos/src/main/kotlin/androidx/navigation3/demos/HierarchicalSceneSample.kt
index c7dc5b4..bf0b69a 100644
--- a/navigation3/navigation3-ui/integration-tests/navigation3-demos/src/main/kotlin/androidx/navigation3/demos/HierarchicalSceneSample.kt
+++ b/navigation3/navigation3-ui/integration-tests/navigation3-demos/src/main/kotlin/androidx/navigation3/demos/HierarchicalSceneSample.kt
@@ -46,6 +46,7 @@
 import androidx.navigation3.runtime.rememberSaveableStateHolderNavEntryDecorator
 import androidx.navigation3.scene.Scene
 import androidx.navigation3.scene.SceneStrategy
+import androidx.navigation3.scene.SceneStrategyScope
 import androidx.navigation3.ui.LocalNavAnimatedContentScope
 import androidx.navigation3.ui.NavDisplay
 import androidx.savedstate.compose.serialization.serializers.SnapshotStateListSerializer
@@ -191,22 +192,38 @@
             }
         }
     }
+
+    override fun equals(other: Any?): Boolean {
+        if (this === other) return true
+        if (other == null || this::class != other::class) return false
+
+        other as HierarchicalScene<*>
+
+        return key == other.key &&
+            navEntries == other.navEntries &&
+            previousEntries == other.previousEntries
+    }
+
+    override fun hashCode(): Int {
+        return key.hashCode() * 31 + navEntries.hashCode() * 31 + previousEntries.hashCode() * 31
+    }
+
+    override fun toString(): String {
+        return "HierarchicalScene(key=$key, entries=$entries, previousEntries=$previousEntries)"
+    }
 }
 
 private class HierarchicalSceneStrategy<T : Any>(private val columns: Int) : SceneStrategy<T> {
-    @Composable
-    override fun calculateScene(entries: List<NavEntry<T>>, onBack: () -> Unit): Scene<T> {
+    override fun SceneStrategyScope<T>.calculateScene(entries: List<NavEntry<T>>): Scene<T> {
         val includedEntries = entries.takeLast(columns)
-        return remember(columns, includedEntries) {
-            HierarchicalScene(
-                List(columns, includedEntries::getOrNull),
-                previousEntries =
-                    if (entries.size > columns) {
-                        entries.dropLast(1)
-                    } else {
-                        emptyList()
-                    },
-            )
-        }
+        return HierarchicalScene(
+            List(columns, includedEntries::getOrNull),
+            previousEntries =
+                if (entries.size > columns) {
+                    entries.dropLast(1)
+                } else {
+                    emptyList()
+                },
+        )
     }
 }
diff --git a/navigation3/navigation3-ui/samples/src/main/kotlin/androidx/navigation3/scene/samples/SceneStrategySamples.kt b/navigation3/navigation3-ui/samples/src/main/kotlin/androidx/navigation3/scene/samples/SceneStrategySamples.kt
new file mode 100644
index 0000000..37e802f
--- /dev/null
+++ b/navigation3/navigation3-ui/samples/src/main/kotlin/androidx/navigation3/scene/samples/SceneStrategySamples.kt
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2025 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 androidx.navigation3.scene.samples
+
+import androidx.annotation.Sampled
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.window.Dialog
+import androidx.navigation3.runtime.NavEntry
+import androidx.navigation3.scene.OverlayScene
+import androidx.navigation3.scene.Scene
+import androidx.navigation3.scene.SceneStrategy
+import androidx.navigation3.scene.SceneStrategyScope
+
+@Suppress("FunctionName", "unused")
+@Sampled
+fun SceneStrategyOnBackSample() {
+    /** Class that shows a [NavEntry] as a [Dialog]. */
+    class SimpleDialogScene<T : Any>(
+        private val entry: NavEntry<T>,
+        override val previousEntries: List<NavEntry<T>>,
+        onBack: () -> Unit,
+    ) : OverlayScene<T> {
+        override val key = entry.contentKey
+        override val entries = listOf(entry)
+        override val overlaidEntries = previousEntries
+
+        override val content: @Composable () -> Unit = {
+            Dialog(onDismissRequest = onBack) { entry.Content() }
+        }
+    }
+
+    /**
+     * A [SceneStrategy] that shows every screen above the first one as a dialog.
+     *
+     * In a real example, you'd have developers opt into displaying their entry as a dialog by
+     * providing a companion method that provides [NavEntry.metadata].
+     *
+     * @see androidx.navigation3.scene.DialogSceneStrategy
+     */
+    class SimpleDialogSceneStrategy<T : Any> : SceneStrategy<T> {
+        override fun SceneStrategyScope<T>.calculateScene(entries: List<NavEntry<T>>): Scene<T>? {
+            val entry = entries.lastOrNull() ?: return null
+            val previousEntries = entries.dropLast(1)
+            // Only show this as a dialog if there is something 'underneath' the dialog
+            return if (previousEntries.isNotEmpty()) {
+                SimpleDialogScene(entry, previousEntries, onBack)
+            } else {
+                null
+            }
+        }
+    }
+}
diff --git a/navigation3/navigation3-ui/samples/src/main/kotlin/androidx/navigation3/ui/samples/CustomSceneSamples.kt b/navigation3/navigation3-ui/samples/src/main/kotlin/androidx/navigation3/ui/samples/CustomSceneSamples.kt
index 2af9adf..53742dc 100644
--- a/navigation3/navigation3-ui/samples/src/main/kotlin/androidx/navigation3/ui/samples/CustomSceneSamples.kt
+++ b/navigation3/navigation3-ui/samples/src/main/kotlin/androidx/navigation3/ui/samples/CustomSceneSamples.kt
@@ -49,6 +49,7 @@
 import androidx.navigation3.runtime.rememberSaveableStateHolderNavEntryDecorator
 import androidx.navigation3.scene.Scene
 import androidx.navigation3.scene.SceneStrategy
+import androidx.navigation3.scene.SceneStrategyScope
 import androidx.navigation3.ui.NavDisplay
 import androidx.navigation3.ui.NavDisplay.popTransitionSpec
 import androidx.navigation3.ui.NavDisplay.predictivePopTransitionSpec
@@ -83,8 +84,7 @@
 }
 
 private class DefaultSceneTransitionsSceneStrategy<T : Any>() : SceneStrategy<T> {
-    @Composable
-    override fun calculateScene(entries: List<NavEntry<T>>, onBack: () -> Unit): Scene<T>? {
+    override fun SceneStrategyScope<T>.calculateScene(entries: List<NavEntry<T>>): Scene<T>? {
         if (entries.isEmpty()) return null
         return DefaultSceneTransitionsScene(entries.last(), entries.dropLast(1))
     }
@@ -128,8 +128,7 @@
 }
 
 private class SceneOverrideEntryTransitionsSceneStrategy<T : Any>() : SceneStrategy<T> {
-    @Composable
-    override fun calculateScene(entries: List<NavEntry<T>>, onBack: () -> Unit): Scene<T>? {
+    override fun SceneStrategyScope<T>.calculateScene(entries: List<NavEntry<T>>): Scene<T>? {
         if (entries.isEmpty()) return null
         return SceneOverrideEntryTransitionsScene(entries.last(), entries.dropLast(1))
     }
diff --git a/navigation3/navigation3-ui/src/androidInstrumentedTest/kotlin/androidx/navigation3/scene/SceneInfoTest.kt b/navigation3/navigation3-ui/src/androidInstrumentedTest/kotlin/androidx/navigation3/scene/SceneInfoTest.kt
index 0b22539..f6772a5 100644
--- a/navigation3/navigation3-ui/src/androidInstrumentedTest/kotlin/androidx/navigation3/scene/SceneInfoTest.kt
+++ b/navigation3/navigation3-ui/src/androidInstrumentedTest/kotlin/androidx/navigation3/scene/SceneInfoTest.kt
@@ -50,7 +50,7 @@
         val backStack = mutableListOf(KEY_1, KEY_2, KEY_3, KEY_4, KEY_5)
 
         // This scene strategy simulates a pop of 2 entries.
-        val sceneStrategy = TestSceneStrategy { current, entries, _ ->
+        val sceneStrategy = TestSceneStrategy { current, entries ->
             TestScene(current!!.contentKey, entries, entries.dropLast(2))
         }
 
@@ -118,10 +118,10 @@
 ) : Scene<T>
 
 private class TestSceneStrategy<T : Any>(
-    private val calculateScene: (NavEntry<T>?, List<NavEntry<T>>, () -> Unit) -> Scene<T>
+    private val calculateScene: (NavEntry<T>?, entries: List<NavEntry<T>>) -> Scene<T>
 ) : SceneStrategy<T> {
 
-    @Composable
-    override fun calculateScene(entries: List<NavEntry<T>>, onBack: () -> Unit): Scene<T>? =
-        calculateScene(entries.lastOrNull(), entries, onBack)
+    override fun SceneStrategyScope<T>.calculateScene(entries: List<NavEntry<T>>): Scene<T>? {
+        return calculateScene(entries.lastOrNull(), entries)
+    }
 }
diff --git a/navigation3/navigation3-ui/src/androidInstrumentedTest/kotlin/androidx/navigation3/scene/usecases/HierarchicalSceneTest.kt b/navigation3/navigation3-ui/src/androidInstrumentedTest/kotlin/androidx/navigation3/scene/usecases/HierarchicalSceneTest.kt
index b5fd71f..0f3d3a5 100644
--- a/navigation3/navigation3-ui/src/androidInstrumentedTest/kotlin/androidx/navigation3/scene/usecases/HierarchicalSceneTest.kt
+++ b/navigation3/navigation3-ui/src/androidInstrumentedTest/kotlin/androidx/navigation3/scene/usecases/HierarchicalSceneTest.kt
@@ -40,6 +40,7 @@
 import androidx.navigation3.runtime.NavEntry
 import androidx.navigation3.scene.Scene
 import androidx.navigation3.scene.SceneStrategy
+import androidx.navigation3.scene.SceneStrategyScope
 import androidx.navigation3.ui.NavDisplay
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.LargeTest
@@ -88,20 +89,17 @@
 }
 
 private class HierarchicalSceneStrategy<T : Any>(private val columns: Int) : SceneStrategy<T> {
-    @Composable
-    override fun calculateScene(entries: List<NavEntry<T>>, onBack: () -> Unit): Scene<T> {
+    override fun SceneStrategyScope<T>.calculateScene(entries: List<NavEntry<T>>): Scene<T> {
         val includedEntries = entries.takeLast(columns)
-        return remember(columns, includedEntries) {
-            HierarchicalScene(
-                List(columns, includedEntries::getOrNull),
-                previousEntries =
-                    if (entries.size > columns) {
-                        entries.dropLast(1)
-                    } else {
-                        emptyList()
-                    },
-            )
-        }
+        return HierarchicalScene(
+            List(columns, includedEntries::getOrNull),
+            previousEntries =
+                if (entries.size > columns) {
+                    entries.dropLast(1)
+                } else {
+                    emptyList()
+                },
+        )
     }
 }
 
diff --git a/navigation3/navigation3-ui/src/androidInstrumentedTest/kotlin/androidx/navigation3/ui/TestDualPaneScenes.kt b/navigation3/navigation3-ui/src/androidInstrumentedTest/kotlin/androidx/navigation3/ui/TestDualPaneScenes.kt
index 28d83f3..eca3308 100644
--- a/navigation3/navigation3-ui/src/androidInstrumentedTest/kotlin/androidx/navigation3/ui/TestDualPaneScenes.kt
+++ b/navigation3/navigation3-ui/src/androidInstrumentedTest/kotlin/androidx/navigation3/ui/TestDualPaneScenes.kt
@@ -28,6 +28,7 @@
 import androidx.navigation3.runtime.NavEntry
 import androidx.navigation3.scene.Scene
 import androidx.navigation3.scene.SceneStrategy
+import androidx.navigation3.scene.SceneStrategyScope
 import androidx.navigation3.ui.NavDisplay.popTransitionSpec
 import kotlin.collections.plus
 
@@ -48,8 +49,7 @@
 }
 
 class TestTwoPaneSceneStrategy<T : Any> : SceneStrategy<T> {
-    @Composable
-    override fun calculateScene(entries: List<NavEntry<T>>, onBack: () -> Unit): Scene<T>? {
+    override fun SceneStrategyScope<T>.calculateScene(entries: List<NavEntry<T>>): Scene<T>? {
         if (entries.size < 2) return null
         val lastTwoEntries = entries.takeLast(2)
         return TestTwoPaneScene(
@@ -65,8 +65,7 @@
     val durationMillis: Int,
     val overrideEntryAnimations: Boolean = false,
 ) : SceneStrategy<T> {
-    @Composable
-    override fun calculateScene(entries: List<NavEntry<T>>, onBack: () -> Unit): Scene<T>? {
+    override fun SceneStrategyScope<T>.calculateScene(entries: List<NavEntry<T>>): Scene<T>? {
         if (entries.size < 2) return null
         val lastTwoEntries = entries.takeLast(2)
         return TestAnimatedTwoPaneScene(
diff --git a/navigation3/navigation3-ui/src/androidInstrumentedTest/kotlin/androidx/navigation3/ui/TestNestedTransitionScenes.kt b/navigation3/navigation3-ui/src/androidInstrumentedTest/kotlin/androidx/navigation3/ui/TestNestedTransitionScenes.kt
index 6476222..3d4ca3b 100644
--- a/navigation3/navigation3-ui/src/androidInstrumentedTest/kotlin/androidx/navigation3/ui/TestNestedTransitionScenes.kt
+++ b/navigation3/navigation3-ui/src/androidInstrumentedTest/kotlin/androidx/navigation3/ui/TestNestedTransitionScenes.kt
@@ -38,6 +38,7 @@
 import androidx.navigation3.runtime.NavEntry
 import androidx.navigation3.scene.Scene
 import androidx.navigation3.scene.SceneStrategy
+import androidx.navigation3.scene.SceneStrategyScope
 import androidx.navigationevent.NavigationEvent
 import androidx.navigationevent.NavigationEventInfo
 import androidx.navigationevent.NavigationEventTransitionState
@@ -51,8 +52,7 @@
  * scene but *not* animate the transition.
  */
 class CardStackSceneStrategy<T : Any>(val duration: Int = 300) : SceneStrategy<T> {
-    @Composable
-    override fun calculateScene(entries: List<NavEntry<T>>, onBack: () -> Unit): Scene<T>? {
+    override fun SceneStrategyScope<T>.calculateScene(entries: List<NavEntry<T>>): Scene<T>? {
         val cardEntries = entries.takeLastWhile { entry -> entry.metadata.contains(CARD_KEY) }
         return if (cardEntries.isNotEmpty()) {
             CardStackScene(
diff --git a/navigation3/navigation3-ui/src/commonMain/kotlin/androidx/navigation3/scene/DialogScene.kt b/navigation3/navigation3-ui/src/commonMain/kotlin/androidx/navigation3/scene/DialogScene.kt
index cdc80a6..848d915 100644
--- a/navigation3/navigation3-ui/src/commonMain/kotlin/androidx/navigation3/scene/DialogScene.kt
+++ b/navigation3/navigation3-ui/src/commonMain/kotlin/androidx/navigation3/scene/DialogScene.kt
@@ -70,8 +70,10 @@
  * This strategy should always be added before any non-overlay scene strategies.
  */
 public class DialogSceneStrategy<T : Any>() : SceneStrategy<T> {
-    @Composable
-    public override fun calculateScene(entries: List<NavEntry<T>>, onBack: () -> Unit): Scene<T>? {
+
+    public override fun SceneStrategyScope<T>.calculateScene(
+        entries: List<NavEntry<T>>
+    ): Scene<T>? {
         val lastEntry = entries.lastOrNull()
         val dialogProperties = lastEntry?.metadata?.get(DIALOG_KEY) as? DialogProperties
         return dialogProperties?.let { properties ->
diff --git a/navigation3/navigation3-ui/src/commonMain/kotlin/androidx/navigation3/scene/SceneSetupNavEntryDecorator.kt b/navigation3/navigation3-ui/src/commonMain/kotlin/androidx/navigation3/scene/SceneSetupNavEntryDecorator.kt
index a8a7e0e..b1a51a6 100644
--- a/navigation3/navigation3-ui/src/commonMain/kotlin/androidx/navigation3/scene/SceneSetupNavEntryDecorator.kt
+++ b/navigation3/navigation3-ui/src/commonMain/kotlin/androidx/navigation3/scene/SceneSetupNavEntryDecorator.kt
@@ -27,9 +27,10 @@
 
 /** Returns a [SceneSetupNavEntryDecorator] that is remembered across recompositions. */
 @Composable
-internal fun <T : Any> rememberSceneSetupNavEntryDecorator(): NavEntryDecorator<T> = remember {
-    SceneSetupNavEntryDecorator()
-}
+internal fun <T : Any> rememberSceneSetupNavEntryDecorator(): SceneSetupNavEntryDecorator<T> =
+    remember {
+        SceneSetupNavEntryDecorator()
+    }
 
 /**
  * A [NavEntryDecorator] that wraps each entry in a [movableContentOf] to allow nav displays to
diff --git a/navigation3/navigation3-ui/src/commonMain/kotlin/androidx/navigation3/scene/SceneState.kt b/navigation3/navigation3-ui/src/commonMain/kotlin/androidx/navigation3/scene/SceneState.kt
index 46f065a..def92a5 100644
--- a/navigation3/navigation3-ui/src/commonMain/kotlin/androidx/navigation3/scene/SceneState.kt
+++ b/navigation3/navigation3-ui/src/commonMain/kotlin/androidx/navigation3/scene/SceneState.kt
@@ -37,63 +37,69 @@
     entries: List<NavEntry<T>>,
     sceneStrategy: SceneStrategy<T>,
     onBack: () -> Unit,
-): SceneState<T> {
-    // re-wrap the entries with the SceneSetupNavEntryDecorator to ensure all the ensures are
-    // inside of a moveable content.
-    // Calculate the single scene based on the sceneStrategy and start the list there.
-    val allScenes =
-        mutableListOf(
-            sceneStrategy.calculateSceneWithSinglePaneFallback(
-                rememberDecoratedNavEntries(entries, listOf(rememberSceneSetupNavEntryDecorator())),
-                onBack,
+): SceneState<T> =
+    with(SceneStrategyScope<T>(onBack)) {
+        // re-wrap the entries with the SceneSetupNavEntryDecorator to ensure all the ensures are
+        // inside of a moveable content.
+        // Calculate the single scene based on the sceneStrategy and start the list there.
+        val allScenes =
+            mutableListOf(
+                sceneStrategy.calculateSceneWithSinglePaneFallback(
+                    this,
+                    rememberDecoratedNavEntries(
+                        entries,
+                        listOf(rememberSceneSetupNavEntryDecorator()),
+                    ),
+                )
             )
-        )
-    // find all of the OverlayScenes
-    do {
-        // Starts from previously calculated scene and check if it is an OverlayScene
-        val overlayScene = allScenes.last() as? OverlayScene
-        val overlaidEntries = overlayScene?.overlaidEntries
-        if (overlaidEntries != null) {
-            // TODO Consider allowing a NavDisplay of only OverlayScene instances
-            require(overlaidEntries.isNotEmpty()) {
-                "Overlaid entries from $overlayScene must not be empty"
+        // find all of the OverlayScenes
+        do {
+            // Starts from previously calculated scene and check if it is an OverlayScene
+            val overlayScene = allScenes.last() as? OverlayScene
+            val overlaidEntries = overlayScene?.overlaidEntries
+            if (overlaidEntries != null) {
+                // TODO Consider allowing a NavDisplay of only OverlayScene instances
+                require(overlaidEntries.isNotEmpty()) {
+                    "Overlaid entries from $overlayScene must not be empty"
+                }
+                // Keep added scenes to the end of our list until we find a non-overlay scene
+                allScenes +=
+                    sceneStrategy.calculateSceneWithSinglePaneFallback(this, overlaidEntries)
             }
-            // Keep added scenes to the end of our list until we find a non-overlay scene
-            allScenes += sceneStrategy.calculateSceneWithSinglePaneFallback(overlaidEntries, onBack)
-        }
-    } while (overlaidEntries != null)
+        } while (overlaidEntries != null)
 
-    // Find all the overlay scenes
-    val overlayScenes = allScenes.dropLast(1).fastMap { it as OverlayScene<T> }
-    // The currentScene is just just whatever is last on the list.
-    val currentScene = allScenes.last()
-    // Get the previous scenes, starting from the current scene.
-    val previousScenes = mutableListOf(allScenes.first())
+        // Find all the overlay scenes
+        val overlayScenes = allScenes.dropLast(1).fastMap { it as OverlayScene<T> }
+        // The currentScene is just just whatever is last on the list.
+        val currentScene = allScenes.last()
+        // Get the previous scenes, starting from the current scene.
+        val previousScenes = mutableListOf(allScenes.first())
 
-    do {
-        // get the first scene off the list
-        val previousScene = previousScenes.firstOrNull()
-        val previousEntries = previousScene?.previousEntries
-        if (!previousEntries.isNullOrEmpty()) {
-            // If there are previous entries, add the scene from those entries to the front of the
-            // list
-            previousScenes.add(
-                0,
-                sceneStrategy.calculateSceneWithSinglePaneFallback(previousEntries, onBack),
-            )
-        }
-    } while (!previousEntries.isNullOrEmpty())
+        do {
+            // get the first scene off the list
+            val previousScene = previousScenes.firstOrNull()
+            val previousEntries = previousScene?.previousEntries
+            if (!previousEntries.isNullOrEmpty()) {
+                // If there are previous entries, add the scene from those entries to the front of
+                // the
+                // list
+                previousScenes.add(
+                    0,
+                    sceneStrategy.calculateSceneWithSinglePaneFallback(this, previousEntries),
+                )
+            }
+        } while (!previousEntries.isNullOrEmpty())
 
-    // remove the currentScene from the list
-    previousScenes.remove(currentScene)
+        // remove the currentScene from the list
+        previousScenes.remove(currentScene)
 
-    return SceneState(
-        entries = entries,
-        overlayScenes = overlayScenes,
-        currentScene = currentScene,
-        previousScenes = previousScenes,
-    )
-}
+        return SceneState(
+            entries = entries,
+            overlayScenes = overlayScenes,
+            currentScene = currentScene,
+            previousScenes = previousScenes,
+        )
+    }
 
 /**
  * Class for holding the state associated with a scene
diff --git a/navigation3/navigation3-ui/src/commonMain/kotlin/androidx/navigation3/scene/SceneStrategy.kt b/navigation3/navigation3-ui/src/commonMain/kotlin/androidx/navigation3/scene/SceneStrategy.kt
index 490a5d6..cfda0bc 100644
--- a/navigation3/navigation3-ui/src/commonMain/kotlin/androidx/navigation3/scene/SceneStrategy.kt
+++ b/navigation3/navigation3-ui/src/commonMain/kotlin/androidx/navigation3/scene/SceneStrategy.kt
@@ -16,10 +16,29 @@
 
 package androidx.navigation3.scene
 
-import androidx.compose.runtime.Composable
 import androidx.navigation3.runtime.NavEntry
 
 /**
+ * Scope used to create a [Scene] from a list of [NavEntry]s.
+ *
+ * This Scope should be provided to the [SceneStrategy.calculateScene] function to create Scenes.
+ */
+public class SceneStrategyScope<T : Any>(
+    /**
+     * A callback that should be connected to any internal handling of system back done by the
+     * returned [Scene].
+     *
+     * For example, if your [Scene] uses a separate window that handles system back itself or if the
+     * UI present in your [Scene] allows users to go back via a custom gesture or affordance, this
+     * callback allows you to bubble up that event to the [SceneState] /
+     * [androidx.navigation3.ui.NavDisplay] that interfaces with the developer owned back stack.
+     *
+     * @sample androidx.navigation3.scene.samples.SceneStrategyOnBackSample
+     */
+    public val onBack: () -> Unit = {}
+)
+
+/**
  * A strategy that tries to calculate a [Scene] given a list of [NavEntry].
  *
  * If the list of [NavEntry] does not result in a [Scene] for this strategy, `null` will be returned
@@ -27,8 +46,8 @@
  */
 public fun interface SceneStrategy<T : Any> {
     /**
-     * Given a back stack of [entries], calculate whether this [SceneStrategy] should take on the
-     * task of rendering one or more of those entries.
+     * Given a [SceneStrategyScope], calculate whether this [SceneStrategy] should take on the task
+     * of rendering one or more of the entries in the scope.
      *
      * By returning a non-null [Scene], your [Scene] takes on the responsibility of rendering the
      * set of entries you declare in [Scene.entries]. If you return `null`, the next available
@@ -36,17 +55,18 @@
      *
      * @param entries The entries on the back stack that should be considered valid to render via a
      *   returned Scene.
-     * @param onBack a callback that should be connected to any internal handling of system back
-     *   done by the returned [Scene].
      */
-    @Composable public fun calculateScene(entries: List<NavEntry<T>>, onBack: () -> Unit): Scene<T>?
+    public fun SceneStrategyScope<T>.calculateScene(entries: List<NavEntry<T>>): Scene<T>?
 
     /**
      * Chains this [SceneStrategy] with another [sceneStrategy] to return a combined
      * [SceneStrategy].
      */
     public infix fun then(sceneStrategy: SceneStrategy<T>): SceneStrategy<T> =
-        SceneStrategy { entries, onBack ->
-            calculateScene(entries, onBack) ?: sceneStrategy.calculateScene(entries, onBack)
+        object : SceneStrategy<T> {
+            override fun SceneStrategyScope<T>.calculateScene(
+                entries: List<NavEntry<T>>
+            ): Scene<T>? =
+                calculateScene(entries) ?: with(sceneStrategy) { calculateScene(entries) }
         }
 }
diff --git a/navigation3/navigation3-ui/src/commonMain/kotlin/androidx/navigation3/scene/SinglePaneScene.kt b/navigation3/navigation3-ui/src/commonMain/kotlin/androidx/navigation3/scene/SinglePaneScene.kt
index 874da7a9..038337f 100644
--- a/navigation3/navigation3-ui/src/commonMain/kotlin/androidx/navigation3/scene/SinglePaneScene.kt
+++ b/navigation3/navigation3-ui/src/commonMain/kotlin/androidx/navigation3/scene/SinglePaneScene.kt
@@ -57,18 +57,20 @@
  * list.
  */
 public class SinglePaneSceneStrategy<T : Any> : SceneStrategy<T> {
-    @Composable
-    override fun calculateScene(entries: List<NavEntry<T>>, onBack: () -> Unit): Scene<T> =
-        SinglePaneScene(
+
+    override fun SceneStrategyScope<T>.calculateScene(entries: List<NavEntry<T>>): Scene<T> {
+        return SinglePaneScene(
             key = entries.last().contentKey,
             entry = entries.last(),
             previousEntries = entries.dropLast(1),
         )
+    }
 }
 
-@Composable
 internal fun <T : Any> SceneStrategy<T>.calculateSceneWithSinglePaneFallback(
+    scope: SceneStrategyScope<T>,
     entries: List<NavEntry<T>>,
-    onBack: () -> Unit,
-): Scene<T> =
-    calculateScene(entries, onBack) ?: SinglePaneSceneStrategy<T>().calculateScene(entries, onBack)
+): Scene<T> {
+    return scope.calculateScene(entries)
+        ?: with(SinglePaneSceneStrategy<T>()) { scope.calculateScene(entries) }
+}
diff --git a/navigationevent/navigationevent-compose/build.gradle b/navigationevent/navigationevent-compose/build.gradle
index 6cc765f..d73f029 100644
--- a/navigationevent/navigationevent-compose/build.gradle
+++ b/navigationevent/navigationevent-compose/build.gradle
@@ -70,7 +70,7 @@
             }
         }
 
-        androidUnitTest {
+        androidHostTest {
             dependsOn(commonTest)
         }
 
diff --git a/room3/GEMINI.md b/room3/GEMINI.md
index 71bc251..b4f767d 100644
--- a/room3/GEMINI.md
+++ b/room3/GEMINI.md
@@ -2,20 +2,34 @@
 
 ## General Instructions:
 
-When modifying any .kt file, format it via the following command:
-`./gradlew :ktCheckFile --format --file <file>`. If more than one file needs formatting, continue
-adding `--file <next-file>` to the command.
+- When modifying any .kt file, format it via the following command:
+  `./gradlew :ktCheckFile --format --file <file>`. If more than one file needs formatting, continue
+  adding `--file <next-file>` to the command.
+- When a public API is changed or when asked to update the public API files, execute:
+  `./gradlew <project>:updateApi`, the projects and their root paths can be found in
+  `settings.gradle`.
+- When moving files, use `git mv` to keep version control history.
+
+## Development Workflow & Refactoring:
+
+- **Test Migration:** There is an ongoing effort to migrate tests from the Java-based
+  `integration-tests/testapp` to the Kotlin-based `integration-tests/kotlintestapp`.
+- **Language Conversion:** When migrating files, convert them from Java to idiomatic Kotlin.
+- **Assertion Library:** When migrating or writing new tests, replace Hamcrest assertions with
+  Kruth.
+- **Kotlin Idioms:** Prefer modern Kotlin idioms for readability. For example, convert concatenated
+  strings in annotations like `@DatabaseView` to use multi-line strings.
 
 ## Description of sub-projects:
 
 - room3-common: Contains the annotation APIs from the library.
 - room3-runtime: Contains the runtime part of the library.
 - room3-compiler: Contains the KSP processor part of the library.
-- room3-compiler-processing: Contains the XProcessing library used for KSP processing and code 
+- room3-compiler-processing: Contains the XProcessing library used for KSP processing and code
   generation.
-- room3-migration: Contains the migration serialization structure for reading and storing schemas.
-- room3-testing: Contains the testing helper library for validating migrations.
-- room3-gradle-plugin: Contains the Room Gradle Plugin used to configure schema directories.
+- room-migration: Contains the migration serialization structure for reading and storing schemas.
+- room-testing: Contains the testing helper library for validating migrations.
+- room-gradle-plugin: Contains the Room Gradle Plugin used to configure schema directories.
 
 ## Documentation links:
 
@@ -30,4 +44,4 @@
 - https://developer.android.com/training/data-storage/room/migrating-db-versions
 - https://developer.android.com/training/data-storage/room/testing-db
 - https://developer.android.com/training/data-storage/room/referencing-data
-- https://developer.android.com/training/data-storage/room/sqlite-room-migration
\ No newline at end of file
+- https://developer.android.com/training/data-storage/room/sqlite-room-migration
diff --git a/room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/FtsTestDatabase.kt b/room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/FtsTestDatabase.kt
new file mode 100644
index 0000000..6c37cbf
--- /dev/null
+++ b/room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/FtsTestDatabase.kt
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2018 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 androidx.room3.integration.kotlintestapp
+
+import androidx.room3.Database
+import androidx.room3.RoomDatabase
+import androidx.room3.integration.kotlintestapp.dao.MailDao
+import androidx.room3.integration.kotlintestapp.dao.SongDao
+import androidx.room3.integration.kotlintestapp.vo.Mail
+import androidx.room3.integration.kotlintestapp.vo.Song
+import androidx.room3.integration.kotlintestapp.vo.SongDescription
+
+@Database(
+    entities = [Mail::class, SongDescription::class, Song::class],
+    version = 1,
+    exportSchema = false,
+)
+abstract class FtsTestDatabase : RoomDatabase() {
+    abstract fun getMailDao(): MailDao
+
+    abstract fun getSongDao(): SongDao
+}
diff --git a/room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/TestDatabase.kt b/room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/TestDatabase.kt
index 31132e8..91ed7f7 100644
--- a/room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/TestDatabase.kt
+++ b/room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/TestDatabase.kt
@@ -25,9 +25,13 @@
 import androidx.room3.integration.kotlintestapp.dao.CounterDao
 import androidx.room3.integration.kotlintestapp.dao.DependencyDao
 import androidx.room3.integration.kotlintestapp.dao.DerivedDao
+import androidx.room3.integration.kotlintestapp.dao.FunnyNamedDao
 import androidx.room3.integration.kotlintestapp.dao.MusicDao
+import androidx.room3.integration.kotlintestapp.dao.PetCoupleDao
 import androidx.room3.integration.kotlintestapp.dao.PetDao
+import androidx.room3.integration.kotlintestapp.dao.SchoolDao
 import androidx.room3.integration.kotlintestapp.dao.ToyDao
+import androidx.room3.integration.kotlintestapp.dao.UserPetDao
 import androidx.room3.integration.kotlintestapp.dao.UsersDao
 import androidx.room3.integration.kotlintestapp.vo.Album
 import androidx.room3.integration.kotlintestapp.vo.Artist
@@ -37,15 +41,18 @@
 import androidx.room3.integration.kotlintestapp.vo.Counter
 import androidx.room3.integration.kotlintestapp.vo.DataClassFromDependency
 import androidx.room3.integration.kotlintestapp.vo.EntityWithJavaPojoList
+import androidx.room3.integration.kotlintestapp.vo.FunnyNamedEntity
 import androidx.room3.integration.kotlintestapp.vo.Image
 import androidx.room3.integration.kotlintestapp.vo.JavaEntity
 import androidx.room3.integration.kotlintestapp.vo.NoArgClass
 import androidx.room3.integration.kotlintestapp.vo.Pet
+import androidx.room3.integration.kotlintestapp.vo.PetCouple
 import androidx.room3.integration.kotlintestapp.vo.PetUser
 import androidx.room3.integration.kotlintestapp.vo.PetWithUser
 import androidx.room3.integration.kotlintestapp.vo.Playlist
 import androidx.room3.integration.kotlintestapp.vo.PlaylistSongXRef
 import androidx.room3.integration.kotlintestapp.vo.Publisher
+import androidx.room3.integration.kotlintestapp.vo.School
 import androidx.room3.integration.kotlintestapp.vo.Song
 import androidx.room3.integration.kotlintestapp.vo.Toy
 import androidx.room3.integration.kotlintestapp.vo.User
@@ -75,6 +82,9 @@
             Artist::class,
             Album::class,
             Image::class,
+            School::class,
+            PetCouple::class,
+            FunnyNamedEntity::class,
         ],
     views = [PetWithUser::class],
     version = 1,
@@ -101,6 +111,14 @@
 
     abstract fun musicDao(): MusicDao
 
+    abstract fun userPetDao(): UserPetDao
+
+    abstract fun schoolDao(): SchoolDao
+
+    abstract fun petCoupleDao(): PetCoupleDao
+
+    abstract fun funnyNamedDao(): FunnyNamedDao
+
     class Converters {
         @TypeConverter
         fun fromTimestamp(value: Long): Date {
diff --git a/room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/dao/FunnyNamedDao.kt b/room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/dao/FunnyNamedDao.kt
new file mode 100644
index 0000000..0abc91f
--- /dev/null
+++ b/room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/dao/FunnyNamedDao.kt
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2017 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 androidx.room3.integration.kotlintestapp.dao
+
+import androidx.lifecycle.LiveData
+import androidx.room3.Dao
+import androidx.room3.Delete
+import androidx.room3.Insert
+import androidx.room3.Query
+import androidx.room3.Update
+import androidx.room3.integration.kotlintestapp.vo.FunnyNamedEntity
+import androidx.room3.integration.kotlintestapp.vo.FunnyNamedEntity.Companion.COLUMN_ID
+import androidx.room3.integration.kotlintestapp.vo.FunnyNamedEntity.Companion.TABLE_NAME
+
+@Dao
+interface FunnyNamedDao {
+    @Insert fun insert(vararg entities: FunnyNamedEntity)
+
+    @Delete fun delete(vararg entities: FunnyNamedEntity)
+
+    @Update fun update(vararg entities: FunnyNamedEntity)
+
+    @Query("select * from \"$TABLE_NAME\" WHERE \"$COLUMN_ID\" IN (:ids)")
+    fun loadAll(vararg ids: Int): List<FunnyNamedEntity>
+
+    @Query("select * from \"$TABLE_NAME\" WHERE \"$COLUMN_ID\" = :id")
+    fun observableOne(id: Int): LiveData<FunnyNamedEntity>
+
+    @Query("select * from \"$TABLE_NAME\" WHERE \"$COLUMN_ID\" = :id")
+    fun load(id: Int): FunnyNamedEntity?
+}
diff --git a/room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/dao/MailDao.kt b/room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/dao/MailDao.kt
new file mode 100644
index 0000000..d64a135
--- /dev/null
+++ b/room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/dao/MailDao.kt
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2018 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 androidx.room3.integration.kotlintestapp.dao
+
+import androidx.room3.Dao
+import androidx.room3.Insert
+import androidx.room3.Query
+import androidx.room3.integration.kotlintestapp.vo.Mail
+import kotlinx.coroutines.flow.Flow
+
+@Dao
+interface MailDao {
+    @Insert fun insert(mail: Mail)
+
+    @Insert fun insert(mails: List<Mail>)
+
+    @Query("SELECT rowId, * FROM mail WHERE mail MATCH :searchQuery")
+    fun getMail(searchQuery: String): List<Mail>
+
+    @Query("SELECT rowId, * FROM mail WHERE subject MATCH :searchQuery")
+    fun getMailWithSubject(searchQuery: String): List<Mail>
+
+    @Query("SELECT rowId, * FROM mail WHERE body MATCH :searchQuery")
+    fun getMailWithBody(searchQuery: String): List<Mail>
+
+    @Query("SELECT snippet(mail) FROM mail WHERE body MATCH :searchQuery")
+    fun getMailBodySnippets(searchQuery: String): List<String>
+
+    @Query("SELECT rowId, * FROM mail") fun getFlowDataMail(): Flow<List<Mail>>
+
+    @Query("INSERT INTO mail(`mail`) VALUES('optimize')") fun optimizeMail()
+
+    @Query("INSERT INTO mail(`mail`) VALUES('rebuild')") fun rebuildMail()
+}
diff --git a/room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/dao/MusicDao.kt b/room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/dao/MusicDao.kt
index 6a707b0..44d454bb 100644
--- a/room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/dao/MusicDao.kt
+++ b/room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/dao/MusicDao.kt
@@ -31,6 +31,7 @@
 import androidx.room3.RawQuery
 import androidx.room3.RewriteQueriesToDropUnusedColumns
 import androidx.room3.Transaction
+import androidx.room3.Update
 import androidx.room3.integration.kotlintestapp.vo.Album
 import androidx.room3.integration.kotlintestapp.vo.AlbumNameAndBandName
 import androidx.room3.integration.kotlintestapp.vo.AlbumWithSongs
@@ -55,6 +56,8 @@
 interface MusicDao {
     @Insert fun addSongs(vararg songs: Song)
 
+    @Update fun updateSong(song: Song)
+
     @Insert fun addArtists(vararg artists: Artist)
 
     @Insert fun addAlbums(vararg albums: Album)
@@ -371,6 +374,10 @@
     @Query("SELECT * FROM Playlist WHERE mPlaylistId = :id")
     fun getPlaylistsWithSongsFlow(id: Int): Flow<PlaylistWithSongs>
 
+    @Transaction
+    @Query("SELECT * FROM Album WHERE mAlbumId = :id")
+    fun getAlbumWithSongsFlow(id: Int): Flow<AlbumWithSongs>
+
     @Query("SELECT * FROM Artist JOIN Song ON Artist.mArtistName = Song.mArtist")
     @RewriteQueriesToDropUnusedColumns
     fun artistNameToSongsMapColumn():
diff --git a/room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/dao/PetCoupleDao.kt b/room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/dao/PetCoupleDao.kt
new file mode 100644
index 0000000..f5cba25
--- /dev/null
+++ b/room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/dao/PetCoupleDao.kt
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2025 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 androidx.room3.integration.kotlintestapp.dao
+
+import androidx.room3.Dao
+import androidx.room3.Insert
+import androidx.room3.Query
+import androidx.room3.integration.kotlintestapp.vo.PetCouple
+
+@Dao
+interface PetCoupleDao {
+    @Insert fun insert(couple: PetCouple)
+
+    @Query("SELECT * FROM PetCouple") fun loadAll(): List<PetCouple>
+}
diff --git a/room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/dao/PetDao.kt b/room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/dao/PetDao.kt
index 6127f2f..f8929b9 100644
--- a/room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/dao/PetDao.kt
+++ b/room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/dao/PetDao.kt
@@ -39,26 +39,26 @@
     @Query("SELECT COUNT(*) FROM Pet") fun count(): Int
 
     @Transaction
-    @Query("SELECT * FROM Pet ORDER BY Pet.mPetId ASC")
+    @Query("SELECT * FROM Pet ORDER BY Pet.petId ASC")
     fun allPetsWithToyIds(): List<PetWithToyIds>
 
     @Transaction @Query("SELECT * FROM Pet") fun allPetsWithOwners(): List<PetAndOwner>
 
-    @Query("SELECT * FROM Pet WHERE Pet.mPetId = :id")
+    @Query("SELECT * FROM Pet WHERE Pet.petId = :id")
     fun petWithIdFuture(id: Int): ListenableFuture<Optional<Pet>>
 
-    @Query("SELECT * FROM Pet WHERE Pet.mPetId = :id") fun petWithIdFlowable(id: Int): Flowable<Pet>
+    @Query("SELECT * FROM Pet WHERE Pet.petId = :id") fun petWithIdFlowable(id: Int): Flowable<Pet>
 
-    @Query("SELECT * FROM Pet WHERE Pet.mPetId = :id") fun petWithId(id: Int): Pet
+    @Query("SELECT * FROM Pet WHERE Pet.petId = :id") fun petWithId(id: Int): Pet
 
-    @Query("SELECT * FROM Pet WHERE Pet.mPetId = :id") fun petWithIdLiveData(id: Int): LiveData<Pet>
+    @Query("SELECT * FROM Pet WHERE Pet.petId = :id") fun petWithIdLiveData(id: Int): LiveData<Pet>
 
-    @Query("SELECT * FROM PetWithUser WHERE mPetId = :id")
+    @Query("SELECT * FROM PetWithUser WHERE petId = :id")
     fun petWithUserLiveData(id: Int): LiveData<PetWithUser>
 
     @Delete fun delete(pet: Pet)
 
-    @Query("SELECT mPetId FROM Pet") fun allIds(): IntArray
+    @Query("SELECT petId FROM Pet") fun allIds(): IntArray
 
     @Transaction
     fun deleteAndInsert(oldPet: Pet, newPet: Pet, shouldFail: Boolean) {
diff --git a/room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/dao/SchoolDao.kt b/room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/dao/SchoolDao.kt
new file mode 100644
index 0000000..7e8dcc0
--- /dev/null
+++ b/room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/dao/SchoolDao.kt
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2017 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 androidx.room3.integration.kotlintestapp.dao
+
+import androidx.room3.Dao
+import androidx.room3.Insert
+import androidx.room3.OnConflictStrategy
+import androidx.room3.Query
+import androidx.room3.RoomWarnings
+import androidx.room3.integration.kotlintestapp.vo.Coordinates
+import androidx.room3.integration.kotlintestapp.vo.School
+import androidx.room3.integration.kotlintestapp.vo.SchoolRef
+
+@Dao
+abstract class SchoolDao {
+    @Insert(onConflict = OnConflictStrategy.REPLACE) abstract fun insert(vararg schools: School)
+
+    @Query("SELECT * from School WHERE address_street LIKE '%' || :street || '%'")
+    abstract fun findByStreet(street: String): List<School>
+
+    @Suppress(RoomWarnings.QUERY_MISMATCH)
+    @Query("SELECT id, name, manager_uId FROM School")
+    abstract fun schoolAndManagerNames(): List<School>
+
+    @Query("SELECT id, name, manager_uId FROM School")
+    @Suppress(RoomWarnings.QUERY_MISMATCH)
+    abstract fun schoolAndManagerIdsAsPoKo(): List<SchoolRef>
+
+    @Query("SELECT address_lat as lat, address_lng as lng FROM School WHERE id = :schoolId")
+    abstract fun loadCoordinates(schoolId: Int): Coordinates
+
+    @Suppress(RoomWarnings.QUERY_MISMATCH)
+    @Query("SELECT id, address_lat, address_lng FROM School WHERE id = :schoolId")
+    abstract fun loadCoordinatesAsSchool(schoolId: Int): School
+}
diff --git a/room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/dao/SongDao.kt b/room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/dao/SongDao.kt
new file mode 100644
index 0000000..0edf718
--- /dev/null
+++ b/room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/dao/SongDao.kt
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2018 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 androidx.room3.integration.kotlintestapp.dao
+
+import androidx.room3.Dao
+import androidx.room3.Insert
+import androidx.room3.Query
+import androidx.room3.integration.kotlintestapp.vo.Song
+import androidx.room3.integration.kotlintestapp.vo.SongDescription
+import kotlinx.coroutines.flow.Flow
+
+@Dao
+interface SongDao {
+    @Insert fun insert(song: Song)
+
+    @Insert fun insert(songs: List<Song>)
+
+    @Query("SELECT * FROM SongDescription WHERE SongDescription MATCH :searchQuery")
+    fun getSongDescriptions(searchQuery: String): List<SongDescription>
+
+    @Query(
+        """
+            SELECT s.mSongId, s.mTitle, s.mArtist, s.mAlbum, s.mLength, s.mReleasedYear
+            FROM Song as s JOIN SongDescription as fts ON (docid = mSongId)
+            WHERE fts.mTitle MATCH :searchQuery
+            """
+    )
+    fun getSongs(searchQuery: String): List<Song>
+
+    @Query("SELECT * FROM Song") fun getFlowSong(): Flow<List<Song>>
+
+    @Query("SELECT * FROM SongDescription")
+    fun getFlowSongDescription(): Flow<List<SongDescription>>
+}
diff --git a/room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/dao/ToyDao.kt b/room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/dao/ToyDao.kt
index 63af3fe..bed92d2 100644
--- a/room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/dao/ToyDao.kt
+++ b/room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/dao/ToyDao.kt
@@ -26,7 +26,7 @@
 interface ToyDao {
     @Insert fun insert(vararg toys: Toy)
 
-    @Query("SELECT * FROM Toy WHERE mId = :id") fun getToy(id: Int): Toy?
+    @Query("SELECT * FROM Toy WHERE id = :id") fun getToy(id: Int): Toy?
 
     @Insert(onConflict = OnConflictStrategy.REPLACE) fun insertOrReplace(toy: Toy)
 
diff --git a/room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/dao/UserPetDao.kt b/room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/dao/UserPetDao.kt
new file mode 100644
index 0000000..259cadf2
--- /dev/null
+++ b/room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/dao/UserPetDao.kt
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2025 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 androidx.room3.integration.kotlintestapp.dao
+
+import androidx.room3.Dao
+import androidx.room3.Query
+import androidx.room3.integration.kotlintestapp.vo.UserAndGenericPet
+import androidx.room3.integration.kotlintestapp.vo.UserAndPet
+
+@Dao
+interface UserPetDao {
+    @Query("SELECT * FROM User u, Pet p WHERE u.uId = p.userId") fun loadAll(): List<UserAndPet>
+
+    @Query("SELECT * FROM User u, Pet p WHERE u.uId = p.userId")
+    fun loadAllGeneric(): List<UserAndGenericPet>
+
+    @Query("SELECT * FROM User u LEFT OUTER JOIN Pet p ON u.uId = p.userId")
+    fun loadUsers(): List<UserAndPet>
+
+    @Query("SELECT * FROM Pet p LEFT OUTER JOIN User u ON u.uId = p.userId")
+    fun loadPets(): List<UserAndPet>
+}
diff --git a/room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/test/CollationTest.kt b/room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/test/CollationTest.kt
new file mode 100644
index 0000000..09cdbf4
--- /dev/null
+++ b/room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/test/CollationTest.kt
@@ -0,0 +1,130 @@
+/*
+ * Copyright 2025 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 androidx.room3.integration.kotlintestapp.test
+
+import androidx.kruth.assertThat
+import androidx.room3.ColumnInfo
+import androidx.room3.Dao
+import androidx.room3.Database
+import androidx.room3.Entity
+import androidx.room3.Insert
+import androidx.room3.PrimaryKey
+import androidx.room3.Query
+import androidx.room3.Room
+import androidx.room3.RoomDatabase
+import androidx.sqlite.driver.AndroidSQLiteDriver
+import androidx.test.core.app.ApplicationProvider
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import java.util.Locale
+import org.junit.After
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+
+/** Validates Android's built-in 'LOCALIZED' collator */
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class CollationTest {
+
+    private lateinit var db: CollateDb
+    private lateinit var dao: CollateDao
+    private lateinit var defaultLocale: Locale
+    private val item1 = CollateEntity(1, "abı")
+    private val item2 = CollateEntity(2, "abi")
+    private val item3 = CollateEntity(3, "abj")
+    private val item4 = CollateEntity(4, "abç")
+
+    @Before
+    fun init() {
+        defaultLocale = Locale.getDefault()
+    }
+
+    private fun initDao(systemLocale: Locale) {
+        Locale.setDefault(systemLocale)
+        db =
+            Room.inMemoryDatabaseBuilder<CollateDb>(ApplicationProvider.getApplicationContext())
+                .setDriver(AndroidSQLiteDriver())
+                .build()
+        dao = db.dao()
+        dao.insert(item1, item2, item3, item4)
+    }
+
+    @After
+    fun closeDb() {
+        db.close()
+        Locale.setDefault(defaultLocale)
+    }
+
+    @Test
+    fun localized() {
+        initDao(Locale("tr", "TR"))
+        val result = dao.sortedByLocalized()
+        assertThat(result).containsExactly(item4, item1, item2, item3).inOrder()
+    }
+
+    @Test
+    fun localized_asUnicode() {
+        initDao(Locale.getDefault())
+        val result = dao.sortedByLocalizedAsUnicode()
+        assertThat(result).containsExactly(item4, item2, item1, item3).inOrder()
+    }
+
+    @Test
+    fun unicode_asLocalized() {
+        initDao(Locale("tr", "TR"))
+        val result = dao.sortedByUnicodeAsLocalized()
+        assertThat(result).containsExactly(item4, item1, item2, item3).inOrder()
+    }
+
+    @Test
+    fun unicode() {
+        initDao(Locale.getDefault())
+        val result = dao.sortedByUnicode()
+        assertThat(result).containsExactly(item4, item2, item1, item3).inOrder()
+    }
+
+    @Entity
+    data class CollateEntity(
+        @PrimaryKey val id: Int,
+        @ColumnInfo(collate = ColumnInfo.LOCALIZED) val localizedName: String,
+        @ColumnInfo(collate = ColumnInfo.UNICODE) val unicodeName: String,
+    ) {
+        constructor(id: Int, name: String) : this(id, name, name)
+    }
+
+    @Dao
+    interface CollateDao {
+        @Query("SELECT * FROM CollateEntity ORDER BY localizedName ASC")
+        fun sortedByLocalized(): List<CollateEntity>
+
+        @Query("SELECT * FROM CollateEntity ORDER BY localizedName COLLATE UNICODE ASC")
+        fun sortedByLocalizedAsUnicode(): List<CollateEntity>
+
+        @Query("SELECT * FROM CollateEntity ORDER BY unicodeName ASC")
+        fun sortedByUnicode(): List<CollateEntity>
+
+        @Query("SELECT * FROM CollateEntity ORDER BY unicodeName COLLATE LOCALIZED ASC")
+        fun sortedByUnicodeAsLocalized(): List<CollateEntity>
+
+        @Insert fun insert(vararg entities: CollateEntity)
+    }
+
+    @Database(entities = [CollateEntity::class], version = 1, exportSchema = false)
+    abstract class CollateDb : RoomDatabase() {
+        abstract fun dao(): CollateDao
+    }
+}
diff --git a/room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/test/ConstructorTest.kt b/room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/test/ConstructorTest.kt
new file mode 100644
index 0000000..bd45bea
--- /dev/null
+++ b/room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/test/ConstructorTest.kt
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2017 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 androidx.room3.integration.kotlintestapp.test
+
+import androidx.kruth.assertThat
+import androidx.room3.Dao
+import androidx.room3.Database
+import androidx.room3.Embedded
+import androidx.room3.Entity
+import androidx.room3.Insert
+import androidx.room3.PrimaryKey
+import androidx.room3.Query
+import androidx.room3.Room
+import androidx.room3.RoomDatabase
+import androidx.sqlite.driver.AndroidSQLiteDriver
+import androidx.test.core.app.ApplicationProvider
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import org.junit.After
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(AndroidJUnit4::class)
+@SmallTest
+class ConstructorTest {
+    @Database(
+        version = 1,
+        entities = [FullConstructor::class, PartialConstructor::class],
+        exportSchema = false,
+    )
+    abstract class MyDb : RoomDatabase() {
+        abstract fun dao(): MyDao
+    }
+
+    @Dao
+    interface MyDao {
+        @Insert fun insertFull(vararg full: FullConstructor)
+
+        @Query("SELECT * FROM fc WHERE a = :a") fun loadFull(a: Int): FullConstructor
+
+        @Insert fun insertPartial(vararg partial: PartialConstructor)
+
+        @Query("SELECT * FROM pc WHERE a = :a") fun loadPartial(a: Int): PartialConstructor
+    }
+
+    @Entity(tableName = "fc")
+    data class FullConstructor(
+        @PrimaryKey val a: Int,
+        val b: Int,
+        @Embedded val embedded: MyEmbedded?,
+    )
+
+    @Entity(tableName = "pc")
+    data class PartialConstructor(@PrimaryKey val a: Int) {
+        var b: Int = 0
+        @Embedded var embedded: MyEmbedded? = null
+    }
+
+    data class MyEmbedded(val text: String?)
+
+    private lateinit var db: MyDb
+    private lateinit var dao: MyDao
+
+    @Before
+    fun init() {
+        db =
+            Room.inMemoryDatabaseBuilder<MyDb>(ApplicationProvider.getApplicationContext())
+                .setDriver(AndroidSQLiteDriver())
+                .build()
+        dao = db.dao()
+    }
+
+    @After
+    fun teardown() {
+        db.close()
+    }
+
+    @Test
+    fun insertAndReadFullConstructor() {
+        val inserted = FullConstructor(1, 2, null)
+        dao.insertFull(inserted)
+        val load = dao.loadFull(1)
+        assertThat(load).isEqualTo(inserted)
+    }
+
+    @Test
+    fun insertAndReadPartial() {
+        val item = PartialConstructor(3).apply { b = 7 }
+        dao.insertPartial(item)
+        val load = dao.loadPartial(3)
+        assertThat(load).isEqualTo(item)
+    }
+}
diff --git a/room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/test/CustomFTSTokenizerTest.kt b/room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/test/CustomFTSTokenizerTest.kt
new file mode 100644
index 0000000..801f3ce
--- /dev/null
+++ b/room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/test/CustomFTSTokenizerTest.kt
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2018 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 androidx.room3.integration.kotlintestapp.test
+
+import androidx.room3.Dao
+import androidx.room3.Database
+import androidx.room3.Entity
+import androidx.room3.Fts4
+import androidx.room3.FtsOptions
+import androidx.room3.Query
+import androidx.room3.RoomDatabase
+
+/**
+ * Not an actual test class, but it is here so that we can test that room-compiler will correctly
+ * verify a table's CREATE statement that contains a custom tokenizer.
+ */
+class CustomFTSTokenizerTest {
+    @Database(
+        entities = [TheEntity::class, TheEntityWithICU::class],
+        version = 1,
+        exportSchema = false,
+    )
+    abstract class CustomTokDatabase : RoomDatabase() {
+        abstract fun getDao(): TheDao
+    }
+
+    @Entity
+    @Fts4(tokenizer = "customICU", tokenizerArgs = ["en_AU"])
+    data class TheEntity(val data: String)
+
+    // For b/201753224
+    @Entity
+    @Fts4(tokenizer = FtsOptions.TOKENIZER_ICU)
+    data class TheEntityWithICU(val data: String)
+
+    @Dao
+    interface TheDao {
+        @Query("SELECT * FROM TheEntity WHERE data MATCH :term") fun search(term: String): TheEntity
+    }
+}
diff --git a/room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/test/DaoConflictStrategyTest.kt b/room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/test/DaoConflictStrategyTest.kt
index 4657cd7..16c3ae0 100644
--- a/room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/test/DaoConflictStrategyTest.kt
+++ b/room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/test/DaoConflictStrategyTest.kt
@@ -58,7 +58,7 @@
         toyDao.insertOrReplace(newToy)
         val output: Toy? = toyDao.getToy(10)
         assertThat(output).isNotNull()
-        assertThat(output!!.mName).isEqualTo(newToy.mName)
+        assertThat(output!!.name).isEqualTo(newToy.name)
     }
 
     @Test
@@ -67,7 +67,7 @@
         toyDao.insertOrIgnore(newToy)
         val output: Toy? = toyDao.getToy(10)
         assertThat(output).isNotNull()
-        assertThat(output!!.mName).isEqualTo(originalToy.mName)
+        assertThat(output!!.name).isEqualTo(originalToy.name)
     }
 
     @Test
@@ -83,7 +83,7 @@
         // Row is updated
         val output: Toy? = toyDao.getToy(11)
         assertThat(output).isNotNull()
-        assertThat(output!!.mName).isEqualTo(conflictToy.mName)
+        assertThat(output!!.name).isEqualTo(conflictToy.name)
     }
 
     @Test
@@ -99,6 +99,6 @@
         // Row is not updated
         val output: Toy? = toyDao.getToy(11)
         assertThat(output).isNotNull()
-        assertThat(output!!.mName).isEqualTo(newToy.mName)
+        assertThat(output!!.name).isEqualTo(newToy.name)
     }
 }
diff --git a/room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/test/DatabaseCallbackTest.kt b/room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/test/DatabaseCallbackTest.kt
new file mode 100644
index 0000000..c515cca
--- /dev/null
+++ b/room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/test/DatabaseCallbackTest.kt
@@ -0,0 +1,169 @@
+/*
+ * Copyright (C) 2017 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 androidx.room3.integration.kotlintestapp.test
+
+import android.content.Context
+import androidx.kruth.assertThat
+import androidx.kruth.assertThrows
+import androidx.room3.Room
+import androidx.room3.RoomDatabase
+import androidx.room3.integration.kotlintestapp.TestDatabase
+import androidx.room3.integration.kotlintestapp.test.TestDatabaseTest.UseDriver
+import androidx.sqlite.SQLiteConnection
+import androidx.sqlite.SQLiteException
+import androidx.sqlite.driver.AndroidSQLiteDriver
+import androidx.sqlite.driver.bundled.BundledSQLiteDriver
+import androidx.sqlite.execSQL
+import androidx.test.core.app.ApplicationProvider
+import androidx.test.filters.MediumTest
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.Parameterized
+import org.junit.runners.Parameterized.Parameters
+
+@MediumTest
+@RunWith(Parameterized::class)
+class DatabaseCallbackTest(private val useDriver: UseDriver) {
+
+    private companion object {
+        @JvmStatic
+        @Parameters(name = "useDriver={0}")
+        fun parameters() = arrayOf(UseDriver.ANDROID, UseDriver.BUNDLED)
+    }
+
+    @Test
+    fun createAndOpen() {
+        val context = ApplicationProvider.getApplicationContext<Context>()
+        context.deleteDatabase("test")
+
+        with(TestDatabaseCallback()) {
+            val db =
+                Room.databaseBuilder<TestDatabase>(context, "test")
+                    .apply {
+                        if (useDriver == UseDriver.ANDROID) {
+                            setDriver(AndroidSQLiteDriver())
+                        } else if (useDriver == UseDriver.BUNDLED) {
+                            setDriver(BundledSQLiteDriver())
+                        }
+                    }
+                    .addCallback(this)
+                    .build()
+            assertThat(created).isFalse()
+            assertThat(opened).isFalse()
+
+            db.booksDao().insertPublisher("p1", "pub1")
+            assertThat(created).isTrue()
+            assertThat(opened).isTrue()
+
+            db.close()
+        }
+
+        with(TestDatabaseCallback()) {
+            val db =
+                Room.databaseBuilder<TestDatabase>(context, "test")
+                    .apply {
+                        if (useDriver == UseDriver.ANDROID) {
+                            setDriver(AndroidSQLiteDriver())
+                        } else if (useDriver == UseDriver.BUNDLED) {
+                            setDriver(BundledSQLiteDriver())
+                        }
+                    }
+                    .addCallback(this)
+                    .build()
+            assertThat(created).isFalse()
+            assertThat(opened).isFalse()
+            assertThat(db.booksDao().getPublisher("p1").name).isEqualTo("pub1")
+            assertThat(created).isFalse() // Not called; already created by first db instance
+            assertThat(opened).isTrue()
+
+            db.close()
+        }
+    }
+
+    @Test
+    fun writeOnCreate() {
+        val context = ApplicationProvider.getApplicationContext<Context>()
+        val db =
+            Room.inMemoryDatabaseBuilder<TestDatabase>(context)
+                .apply {
+                    if (useDriver == UseDriver.ANDROID) {
+                        setDriver(AndroidSQLiteDriver())
+                    } else if (useDriver == UseDriver.BUNDLED) {
+                        setDriver(BundledSQLiteDriver())
+                    }
+                }
+                .addCallback(
+                    object : RoomDatabase.Callback() {
+                        override fun onCreate(connection: SQLiteConnection) {
+                            connection.execSQL(
+                                "INSERT INTO publisher (publisherId, name) VALUES ('p1', 'pub1')"
+                            )
+                        }
+                    }
+                )
+                .build()
+        assertThat(db.booksDao().getPublisher("p1").name).isEqualTo("pub1")
+        db.close()
+    }
+
+    @Test
+    fun exceptionOnCreate() {
+        val context = ApplicationProvider.getApplicationContext<Context>()
+        val db =
+            Room.inMemoryDatabaseBuilder<TestDatabase>(context)
+                .apply {
+                    if (useDriver == UseDriver.ANDROID) {
+                        setDriver(AndroidSQLiteDriver())
+                    } else if (useDriver == UseDriver.BUNDLED) {
+                        setDriver(BundledSQLiteDriver())
+                    }
+                }
+                .addCallback(
+                    object : RoomDatabase.Callback() {
+                        var isBadInsertDone = false
+
+                        override fun onCreate(connection: SQLiteConnection) {
+                            if (!isBadInsertDone) {
+                                isBadInsertDone = true
+                                connection.execSQL("INSERT INTO fake_table (c1) VALUES (1)")
+                            }
+                        }
+                    }
+                )
+                .build()
+
+        // Simulate user catching DB exceptions.
+        assertThrows<SQLiteException> { db.booksDao().getAllBooks() }
+
+        // Database should recover if on create was intermediate issue.
+        assertThat(db.booksDao().getAllBooks()).isEmpty()
+
+        db.close()
+    }
+
+    class TestDatabaseCallback : RoomDatabase.Callback() {
+        var created = false
+        var opened = false
+
+        override fun onCreate(connection: SQLiteConnection) {
+            created = true
+        }
+
+        override fun onOpen(connection: SQLiteConnection) {
+            opened = true
+        }
+    }
+}
diff --git a/room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/test/DatabaseViewTest.kt b/room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/test/DatabaseViewTest.kt
new file mode 100644
index 0000000..8dca1c1
--- /dev/null
+++ b/room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/test/DatabaseViewTest.kt
@@ -0,0 +1,416 @@
+/*
+ * Copyright 2018 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 androidx.room3.integration.kotlintestapp.test
+
+import android.content.Context
+import androidx.kruth.assertThat
+import androidx.room3.Dao
+import androidx.room3.Database
+import androidx.room3.DatabaseView
+import androidx.room3.Embedded
+import androidx.room3.Entity
+import androidx.room3.ExperimentalRoomApi
+import androidx.room3.ForeignKey
+import androidx.room3.Index
+import androidx.room3.Insert
+import androidx.room3.PrimaryKey
+import androidx.room3.Query
+import androidx.room3.Relation
+import androidx.room3.Room
+import androidx.room3.RoomDatabase
+import androidx.room3.Transaction
+import androidx.room3.withWriteTransaction
+import androidx.sqlite.driver.bundled.BundledSQLiteDriver
+import androidx.test.core.app.ApplicationProvider
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.MediumTest
+import androidx.test.filters.SmallTest
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.produceIn
+import kotlinx.coroutines.test.runTest
+import org.junit.After
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(AndroidJUnit4::class)
+class DatabaseViewTest {
+
+    @Entity(
+        foreignKeys =
+            [
+                ForeignKey(
+                    entity = Employee::class,
+                    childColumns = ["managerId"],
+                    parentColumns = ["id"],
+                ),
+                ForeignKey(entity = Team::class, childColumns = ["teamId"], parentColumns = ["id"]),
+            ],
+        indices = [Index("managerId"), Index("teamId")],
+    )
+    data class Employee(
+        @PrimaryKey val id: Long,
+        val name: String,
+        val managerId: Long?,
+        val teamId: Long,
+    )
+
+    @DatabaseView(
+        """
+        SELECT
+          employee.id,
+          employee.name,
+          employee.teamId,
+          manager.id AS manager_id,
+          manager.name AS manager_name,
+          manager.managerId AS manager_managerId,
+          manager.teamId AS manager_teamId
+         FROM Employee AS employee LEFT JOIN Employee AS manager
+         ON employee.managerId = manager.id
+        """
+    )
+    data class EmployeeWithManager(
+        val id: Long,
+        val name: String,
+        val teamId: Long,
+        @Embedded(prefix = "manager_") val manager: Employee?,
+    )
+
+    @DatabaseView(
+        """
+        SELECT
+          employee.id,
+          employee.name,
+          employee.manager_id,
+          employee.manager_name,
+          employee.manager_managerId,
+          employee.manager_teamId,
+          team.id AS team_id,
+          team.name AS team_name,
+          team.departmentId AS team_departmentId,
+          team.departmentName AS team_departmentName
+         FROM EmployeeWithManager AS employee
+         LEFT JOIN TeamDetail AS team ON employee.teamId = team.id
+        """
+    )
+    data class EmployeeDetail(
+        val id: Long,
+        val name: String,
+        @Embedded(prefix = "manager_") val manager: Employee?,
+        @Embedded(prefix = "team_") val team: TeamDetail,
+    )
+
+    data class TeamWithMembers(
+        @Embedded val teamDetail: TeamDetail,
+        @Relation(parentColumn = "id", entityColumn = "teamId")
+        val members: List<EmployeeWithManager>,
+    )
+
+    @Entity(
+        foreignKeys =
+            [
+                ForeignKey(
+                    entity = Department::class,
+                    childColumns = ["departmentId"],
+                    parentColumns = ["id"],
+                )
+            ],
+        indices = [Index("departmentId")],
+    )
+    data class Team(@PrimaryKey val id: Long, val departmentId: Long, val name: String)
+
+    @Entity data class Department(@PrimaryKey val id: Long, val name: String)
+
+    @DatabaseView(
+        """
+        SELECT
+          Team.id,
+          Team.name,
+          Team.departmentId,
+          Department.name AS departmentName
+        FROM Team INNER JOIN Department ON Team.departmentId = Department.id
+        """
+    )
+    data class TeamDetail(
+        val id: Long,
+        val name: String,
+        val departmentId: Long,
+        val departmentName: String,
+    )
+
+    @DatabaseView(
+        """
+        SELECT 
+          Team.*,
+          dep.id AS department_id,
+          dep.name as department_name
+        FROM Team INNER JOIN Department AS dep ON Team.departmentId = dep.id
+        """
+    )
+    data class TeamDetail2(
+        @Embedded val team: Team,
+        @Embedded(prefix = "department_") val department: Department,
+    )
+
+    @DatabaseView(
+        """
+        SELECT
+          td1.id AS first_id,
+          td1.name AS first_name,
+          td1.departmentId AS first_departmentId,
+          td1.departmentName AS first_departmentName,
+          td2.id AS second_id, td2.name AS second_name,
+          td2.departmentId AS second_departmentId,
+          td2.departmentName AS second_departmentName
+        FROM TeamDetail AS td1, TeamDetail AS td2 WHERE td1.id <> td2.id
+        """
+    )
+    data class TeamPair(
+        @Embedded(prefix = "first_") val first: TeamDetail,
+        @Embedded(prefix = "second_") val second: TeamDetail,
+    )
+
+    @Dao
+    interface EmployeeDao {
+        @Insert fun insert(employee: Employee): Long
+
+        @Query("UPDATE Employee SET managerId = :managerId WHERE id = :id")
+        fun updateReport(id: Long, managerId: Long)
+
+        @Query("SELECT * FROM EmployeeWithManager WHERE id = :id")
+        fun withManagerById(id: Long): EmployeeWithManager
+
+        @Query("SELECT * FROM EmployeeDetail WHERE id = :id")
+        fun detailById(id: Long): EmployeeDetail
+
+        @Query("SELECT * FROM EmployeeDetail WHERE id = :id")
+        fun flowDetailById(id: Long): Flow<EmployeeDetail?>
+    }
+
+    @Dao
+    interface TeamDao {
+        @Insert fun insert(team: Team): Long
+
+        @Query("SELECT * FROM TeamDetail WHERE id = :id") fun detailById(id: Long): TeamDetail
+
+        @Query("SELECT * FROM TeamDetail WHERE id = :id")
+        fun flowDetailById(id: Long): Flow<TeamDetail?>
+
+        @Transaction
+        @Query("SELECT * FROM TeamDetail WHERE id = :id")
+        fun withMembers(id: Long): TeamWithMembers
+
+        @Query("SELECT * FROM TeamDetail2 WHERE id = :id") fun detail2ById(id: Long): TeamDetail2
+
+        @Query("SELECT * FROM TeamPair WHERE first_id = :id")
+        fun roundRobinById(id: Long): List<TeamPair>
+    }
+
+    @Dao
+    interface DepartmentDao {
+        @Insert fun insert(department: Department): Long
+
+        @Query("UPDATE Department SET name = :name WHERE id = :id")
+        fun rename(id: Long, name: String)
+    }
+
+    @Database(
+        entities = [Department::class, Team::class, Employee::class],
+        views =
+            [
+                TeamDetail::class,
+                TeamDetail2::class,
+                TeamPair::class,
+                EmployeeWithManager::class,
+                EmployeeDetail::class,
+            ],
+        version = 1,
+        exportSchema = false,
+    )
+    abstract class CompanyDatabase : RoomDatabase() {
+        abstract fun department(): DepartmentDao
+
+        abstract fun team(): TeamDao
+
+        abstract fun employee(): EmployeeDao
+    }
+
+    private lateinit var db: CompanyDatabase
+
+    @Before
+    fun setup() {
+        val context = ApplicationProvider.getApplicationContext<Context>()
+        db =
+            Room.inMemoryDatabaseBuilder<CompanyDatabase>(context)
+                .setDriver(BundledSQLiteDriver())
+                .build()
+    }
+
+    @After
+    fun teardown() {
+        db.close()
+    }
+
+    @Test
+    @SmallTest
+    fun basic() {
+        db.department().insert(Department(1L, "Sales"))
+        db.department().insert(Department(2L, "IT"))
+        db.team().insert(Team(1L, 1L, "Books"))
+        db.team().insert(Team(2L, 2L, "Backend"))
+        val team1 = db.team().detailById(1L)
+        assertThat(team1.name).isEqualTo("Books")
+        assertThat(team1.departmentName).isEqualTo("Sales")
+        val team2 = db.team().detailById(2L)
+        assertThat(team2.name).isEqualTo("Backend")
+        assertThat(team2.departmentName).isEqualTo("IT")
+    }
+
+    @Test
+    @SmallTest
+    fun embedded() {
+        db.department().insert(Department(1, "Sales"))
+        db.team().insert(Team(1L, 1L, "Books"))
+        db.employee().insert(Employee(1L, "CEO", null, 1L))
+        db.employee().insert(Employee(2L, "John", 1L, 1L))
+        db.employee().insert(Employee(3L, "Jane", 2L, 1L))
+        assertThat(db.employee().withManagerById(1L).manager).isNull()
+        assertThat(db.employee().withManagerById(2L).manager?.name).isEqualTo("CEO")
+        assertThat(db.employee().withManagerById(3L).manager?.name).isEqualTo("John")
+    }
+
+    @Test
+    @MediumTest
+    fun flow() = runTest {
+        db.department().insert(Department(1L, "Shop"))
+        val team = db.team().flowDetailById(1L).produceIn(this)
+
+        assertThat(team.receive()).isNull()
+
+        db.team().insert(Team(1L, 1L, "Books"))
+        team.receive().let { detail ->
+            checkNotNull(detail)
+            assertThat(detail.name).isEqualTo("Books")
+            assertThat(detail.departmentName).isEqualTo("Shop")
+        }
+
+        db.department().rename(1L, "Sales")
+        team.receive().let { detail ->
+            checkNotNull(detail)
+            assertThat(detail.name).isEqualTo("Books")
+            assertThat(detail.departmentName).isEqualTo("Sales")
+        }
+
+        team.cancel()
+    }
+
+    @Test
+    @SmallTest
+    fun nested() {
+        db.department().insert(Department(1L, "Shop"))
+        db.team().insert(Team(1L, 1L, "Books"))
+        db.employee().insert(Employee(1L, "CEO", null, 1L))
+        db.employee().insert(Employee(2L, "John", 1L, 1L))
+
+        val employee = db.employee().detailById(2L)
+        assertThat(employee.name).isEqualTo("John")
+        assertThat(employee.manager?.name).isEqualTo("CEO")
+        assertThat(employee.team.name).isEqualTo("Books")
+        assertThat(employee.team.departmentName).isEqualTo("Shop")
+    }
+
+    @Test
+    @MediumTest
+    @OptIn(ExperimentalRoomApi::class)
+    fun nestedFlow() = runTest {
+        val employee = db.employee().flowDetailById(2L).produceIn(this)
+
+        assertThat(employee.receive()).isNull()
+
+        db.withWriteTransaction {
+            db.department().insert(Department(1L, "Shop"))
+            db.team().insert(Team(1L, 1L, "Books"))
+            db.employee().insert(Employee(1L, "CEO", null, 1L))
+            db.employee().insert(Employee(2L, "Jane", 1L, 1L))
+        }
+        employee.receive().let { detail ->
+            checkNotNull(detail)
+            assertThat(detail.name).isEqualTo("Jane")
+            assertThat(detail.manager!!.name).isEqualTo("CEO")
+            assertThat(detail.team.name).isEqualTo("Books")
+            assertThat(detail.team.departmentName).isEqualTo("Shop")
+        }
+
+        db.withWriteTransaction {
+            db.department().rename(1L, "Sales")
+            db.employee().insert(Employee(3L, "John", 1L, 1L))
+            db.employee().updateReport(2L, 3L)
+        }
+        employee.receive().let { detail ->
+            checkNotNull(detail)
+            assertThat(detail.name).isEqualTo("Jane")
+            assertThat(detail.manager!!.name).isEqualTo("John")
+            assertThat(detail.team.name).isEqualTo("Books")
+            assertThat(detail.team.departmentName).isEqualTo("Sales")
+        }
+
+        employee.cancel()
+    }
+
+    @Test
+    @MediumTest
+    fun viewInRelation() {
+        db.department().insert(Department(1L, "Shop"))
+        db.team().insert(Team(1L, 1L, "Books"))
+        db.employee().insert(Employee(1L, "CEO", null, 1L))
+        db.employee().insert(Employee(2L, "John", 1L, 1L))
+
+        val teamWithMembers = db.team().withMembers(1L)
+        assertThat(teamWithMembers.teamDetail.name).isEqualTo("Books")
+        assertThat(teamWithMembers.teamDetail.departmentName).isEqualTo("Shop")
+        assertThat(teamWithMembers.members).hasSize(2)
+        assertThat(teamWithMembers.members[0].name).isEqualTo("CEO")
+        assertThat(teamWithMembers.members[1].name).isEqualTo("John")
+        assertThat(teamWithMembers.members[1].manager?.name).isEqualTo("CEO")
+    }
+
+    @Test
+    @MediumTest
+    fun expandedProjection() {
+        db.department().insert(Department(3L, "Sales"))
+        db.team().insert(Team(5L, 3L, "Books"))
+        val detail = db.team().detail2ById(5L)
+        assertThat(detail.team.id).isEqualTo(5L)
+        assertThat(detail.team.name).isEqualTo("Books")
+        assertThat(detail.team.departmentId).isEqualTo(3L)
+        assertThat(detail.department.id).isEqualTo(3L)
+        assertThat(detail.department.name).isEqualTo("Sales")
+    }
+
+    @Test
+    @MediumTest
+    fun expandedProjection_embedView() {
+        db.department().insert(Department(3L, "Sales"))
+        db.team().insert(Team(5L, 3L, "Books"))
+        db.team().insert(Team(7L, 3L, "Toys"))
+        val pairs = db.team().roundRobinById(5L)
+        assertThat(pairs).hasSize(1)
+        assertThat(pairs.single().first.name).isEqualTo("Books")
+        assertThat(pairs.single().first.departmentName).isEqualTo("Sales")
+        assertThat(pairs.single().second.name).isEqualTo("Toys")
+        assertThat(pairs.single().second.departmentName).isEqualTo("Sales")
+    }
+}
diff --git a/room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/test/DefaultValueTest.kt b/room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/test/DefaultValueTest.kt
new file mode 100644
index 0000000..172720b
--- /dev/null
+++ b/room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/test/DefaultValueTest.kt
@@ -0,0 +1,133 @@
+/*
+ * Copyright 2018 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 androidx.room3.integration.kotlintestapp.test
+
+import androidx.kruth.assertThat
+import androidx.room3.ColumnInfo
+import androidx.room3.Dao
+import androidx.room3.Database
+import androidx.room3.Entity
+import androidx.room3.Insert
+import androidx.room3.PrimaryKey
+import androidx.room3.Query
+import androidx.room3.Room
+import androidx.room3.RoomDatabase
+import androidx.room3.TypeConverter
+import androidx.room3.TypeConverters
+import androidx.sqlite.driver.AndroidSQLiteDriver
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.MediumTest
+import androidx.test.platform.app.InstrumentationRegistry
+import java.text.ParseException
+import java.text.SimpleDateFormat
+import java.util.Date
+import java.util.TimeZone
+import org.junit.After
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@MediumTest
+@RunWith(AndroidJUnit4::class)
+class DefaultValueTest {
+
+    object TimestampConverter {
+        private val FORMAT =
+            SimpleDateFormat("yyyy-MM-dd kk:mm:ss").apply { timeZone = TimeZone.getTimeZone("UTC") }
+
+        @TypeConverter
+        fun toTimestamp(date: Date): String {
+            return FORMAT.format(date)
+        }
+
+        @TypeConverter
+        fun fromTimestamp(timestamp: String): Date {
+            return try {
+                FORMAT.parse(timestamp)
+            } catch (e: ParseException) {
+                throw RuntimeException(e)
+            }
+        }
+    }
+
+    @Entity
+    @TypeConverters(TimestampConverter::class)
+    data class Sample(
+        @PrimaryKey val id: Long,
+        val name: String,
+        @ColumnInfo(defaultValue = "No description") val description: String,
+        @ColumnInfo(defaultValue = "1") val available: Boolean,
+        @ColumnInfo(defaultValue = "0") val serial: Int,
+        @ColumnInfo(defaultValue = "CURRENT_TIMESTAMP") val timestamp: Date,
+    )
+
+    data class NameAndId(val id: Long, val name: String)
+
+    @Dao
+    interface SampleDao {
+        @Query("INSERT INTO Sample (name) VALUES (:name)") fun insert(name: String): Long
+
+        @Insert(entity = Sample::class) fun insertName(nameAndId: NameAndId)
+
+        @Query("SELECT * FROM Sample WHERE id = :id") fun byId(id: Long): Sample
+    }
+
+    @Database(entities = [Sample::class], version = 1, exportSchema = false)
+    abstract class DefaultValueDatabase : RoomDatabase() {
+        abstract fun dao(): SampleDao
+    }
+
+    private lateinit var db: DefaultValueDatabase
+
+    @Before
+    fun setup() {
+        val context = InstrumentationRegistry.getInstrumentation().targetContext
+        db =
+            Room.inMemoryDatabaseBuilder<DefaultValueDatabase>(context)
+                .setDriver(AndroidSQLiteDriver())
+                .build()
+    }
+
+    @After
+    fun teardown() {
+        db.close()
+    }
+
+    @Test
+    fun defaultValues() {
+        val id = db.dao().insert("A")
+        val now = System.currentTimeMillis()
+        val sample = db.dao().byId(id)
+        assertThat(sample.name).isEqualTo("A")
+        assertThat(sample.description).isEqualTo("No description")
+        assertThat(sample.available).isTrue()
+        assertThat(sample.serial).isEqualTo(0)
+        assertThat(sample.timestamp.time.toDouble()).isWithin(3000.0).of(now.toDouble())
+    }
+
+    @Test
+    fun defaultValues_partialEntity() {
+        val nameAndId = NameAndId(1, "A")
+        db.dao().insertName(nameAndId)
+        val now = System.currentTimeMillis()
+        val sample = db.dao().byId(1)
+        assertThat(sample.name).isEqualTo("A")
+        assertThat(sample.description).isEqualTo("No description")
+        assertThat(sample.available).isTrue()
+        assertThat(sample.serial).isEqualTo(0)
+        assertThat(sample.timestamp.time.toDouble()).isWithin(3000.0).of(now.toDouble())
+    }
+}
diff --git a/room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/test/EmbeddedTest.kt b/room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/test/EmbeddedTest.kt
new file mode 100644
index 0000000..3e02801
--- /dev/null
+++ b/room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/test/EmbeddedTest.kt
@@ -0,0 +1,226 @@
+/*
+ * Copyright (C) 2017 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 androidx.room3.integration.kotlintestapp.test
+
+import android.content.Context
+import androidx.kruth.assertThat
+import androidx.room3.Room
+import androidx.room3.integration.kotlintestapp.TestDatabase
+import androidx.room3.integration.kotlintestapp.dao.PetCoupleDao
+import androidx.room3.integration.kotlintestapp.dao.PetDao
+import androidx.room3.integration.kotlintestapp.dao.SchoolDao
+import androidx.room3.integration.kotlintestapp.dao.UserPetDao
+import androidx.room3.integration.kotlintestapp.dao.UsersDao
+import androidx.room3.integration.kotlintestapp.vo.PetCouple
+import androidx.room3.integration.kotlintestapp.vo.School
+import androidx.sqlite.driver.AndroidSQLiteDriver
+import androidx.test.core.app.ApplicationProvider
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import org.junit.After
+import org.junit.Before
+import org.junit.Ignore
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class EmbeddedTest {
+    private lateinit var db: TestDatabase
+    private lateinit var userDao: UsersDao
+    private lateinit var petDao: PetDao
+    private lateinit var userPetDao: UserPetDao
+    private lateinit var schoolDao: SchoolDao
+    private lateinit var petCoupleDao: PetCoupleDao
+
+    @Before
+    fun createDb() {
+        val context: Context = ApplicationProvider.getApplicationContext()
+        db =
+            Room.inMemoryDatabaseBuilder<TestDatabase>(context)
+                .setDriver(AndroidSQLiteDriver())
+                .build()
+        userDao = db.usersDao()
+        petDao = db.petDao()
+        userPetDao = db.userPetDao()
+        schoolDao = db.schoolDao()
+        petCoupleDao = db.petCoupleDao()
+    }
+
+    @After
+    fun closeDb() {
+        db.close()
+    }
+
+    @Test
+    fun loadAll() {
+        val pet = TestUtil.createPet(1)
+        val user = TestUtil.createUser(2)
+        pet.userId = user.uId
+        userDao.insertUser(user)
+        petDao.insertOrReplace(pet)
+        val all = userPetDao.loadAll()
+        assertThat(all).hasSize(1)
+        assertThat(all.single().user).isEqualTo(user)
+        assertThat(all.single().pet).isEqualTo(pet)
+    }
+
+    @Test
+    fun loadAllGeneric() {
+        val pet = TestUtil.createPet(1)
+        val user = TestUtil.createUser(2)
+        pet.userId = user.uId
+        userDao.insertUser(user)
+        petDao.insertOrReplace(pet)
+        val all = userPetDao.loadAllGeneric()
+        assertThat(all).hasSize(1)
+        assertThat(all.single().user).isEqualTo(user)
+        assertThat(all.single().item).isEqualTo(pet)
+    }
+
+    @Test
+    fun loadFromUsers() {
+        val pet = TestUtil.createPet(1)
+        val user = TestUtil.createUser(2)
+        pet.userId = user.uId
+        userDao.insertUser(user)
+        petDao.insertOrReplace(pet)
+        val all = userPetDao.loadUsers()
+        assertThat(all).hasSize(1)
+        assertThat(all.single().user).isEqualTo(user)
+        assertThat(all.single().pet).isEqualTo(pet)
+    }
+
+    @Test
+    fun loadFromUsersWithNullPet() {
+        val user = TestUtil.createUser(2)
+        userDao.insertUser(user)
+        val all = userPetDao.loadUsers()
+        assertThat(all).hasSize(1)
+        assertThat(all.single().user).isEqualTo(user)
+        assertThat(all.single().pet).isNull()
+    }
+
+    @Test
+    fun loadFromPets() {
+        val pet = TestUtil.createPet(1)
+        val user = TestUtil.createUser(2)
+        pet.userId = user.uId
+        userDao.insertUser(user)
+        petDao.insertOrReplace(pet)
+        val all = userPetDao.loadPets()
+        assertThat(all).hasSize(1)
+        assertThat(all.single().user).isEqualTo(user)
+        assertThat(all.single().pet).isEqualTo(pet)
+    }
+
+    @Test
+    fun loadFromPetsWithNullUser() {
+        val pet = TestUtil.createPet(1)
+        petDao.insertOrReplace(pet)
+        val all = userPetDao.loadPets()
+        assertThat(all).hasSize(1)
+        assertThat(all.single().user).isNull()
+        assertThat(all.single().pet).isEqualTo(pet)
+    }
+
+    @Test
+    fun findSchoolByStreet() {
+        val school = TestUtil.createSchool(3, 5)
+        school.address!!.street = "foo"
+        schoolDao.insert(school)
+        val result = schoolDao.findByStreet("foo")
+        assertThat(result).hasSize(1)
+        assertThat(result.single()).isEqualTo(school)
+    }
+
+    @Test
+    @Ignore
+    fun loadSubFieldsAsPoKo() {
+        loadSubFieldsTest { schoolDao.schoolAndManagerIdsAsPoKo().map { it } }
+    }
+
+    @Test
+    fun loadSubFieldsAsEntity() {
+        loadSubFieldsTest { schoolDao.schoolAndManagerNames() }
+    }
+
+    private fun loadSubFieldsTest(loader: () -> List<School>) {
+        val school = TestUtil.createSchool(3, 5)
+        school.name = "MTV High"
+        school.manager!!.uId = 5
+        schoolDao.insert(school)
+        val school2 = TestUtil.createSchool(4, 6)
+        school2.name = "MTV Low"
+        school2.manager = null
+        schoolDao.insert(school2)
+        val schools = loader()
+        assertThat(schools).hasSize(2)
+        schools[0].let {
+            assertThat(it.name).isEqualTo("MTV High")
+            assertThat(it.address).isNull()
+            assertThat(it.manager).isNotNull()
+            assertThat(it.manager!!.uId).isEqualTo(5)
+        }
+        schools[1].let {
+            assertThat(it.name).isEqualTo("MTV Low")
+            assertThat(it.address).isNull()
+            assertThat(it.manager).isNull()
+        }
+    }
+
+    @Test
+    fun loadNestedSub() {
+        val school = TestUtil.createSchool(3, 5)
+        school.address!!.coordinates!!.lat = 3.0
+        school.address!!.coordinates!!.lng = 4.0
+        schoolDao.insert(school)
+        val coordinates = schoolDao.loadCoordinates(3)
+        assertThat(coordinates.lat).isEqualTo(3.0)
+        assertThat(coordinates.lng).isEqualTo(4.0)
+        val asSchool = schoolDao.loadCoordinatesAsSchool(3)
+        assertThat(asSchool.address!!.coordinates!!.lat).isEqualTo(3.0)
+        assertThat(asSchool.address!!.coordinates!!.lng).isEqualTo(4.0)
+        // didn't ask for it so don't load
+        assertThat(asSchool.manager).isNull()
+        assertThat(asSchool.address!!.street).isNull()
+    }
+
+    @Test
+    fun sameFieldType() {
+        val male = TestUtil.createPet(3)
+        val female = TestUtil.createPet(5)
+        val petCouple = PetCouple("foo", male, female)
+        petCoupleDao.insert(petCouple)
+        val petCouples = petCoupleDao.loadAll()
+        assertThat(petCouples).hasSize(1)
+        assertThat(petCouples.single().id).isEqualTo("foo")
+        assertThat(petCouples.single().male).isEqualTo(male)
+        assertThat(petCouples.single().female).isEqualTo(female)
+    }
+
+    @Test
+    fun sameFieldOneNull() {
+        val loneWolf = TestUtil.createPet(3)
+        val petCouple = PetCouple("foo", loneWolf, null)
+        petCoupleDao.insert(petCouple)
+        val petCouples = petCoupleDao.loadAll()
+        assertThat(petCouples).hasSize(1)
+        assertThat(petCouples.single().id).isEqualTo("foo")
+        assertThat(petCouples.single().male).isEqualTo(loneWolf)
+        assertThat(petCouples.single().female).isNull()
+    }
+}
diff --git a/room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/test/ForeignKeyTest.kt b/room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/test/ForeignKeyTest.kt
new file mode 100644
index 0000000..5321153
--- /dev/null
+++ b/room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/test/ForeignKeyTest.kt
@@ -0,0 +1,316 @@
+/*
+ * Copyright (C) 2017 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 androidx.room3.integration.kotlintestapp.test
+
+import androidx.kruth.assertThat
+import androidx.kruth.assertThrows
+import androidx.room3.Dao
+import androidx.room3.Database
+import androidx.room3.Delete
+import androidx.room3.Entity
+import androidx.room3.ExperimentalRoomApi
+import androidx.room3.ForeignKey
+import androidx.room3.Index
+import androidx.room3.Insert
+import androidx.room3.PrimaryKey
+import androidx.room3.Query
+import androidx.room3.Room
+import androidx.room3.RoomDatabase
+import androidx.room3.integration.kotlintestapp.test.TestDatabaseTest.UseDriver
+import androidx.room3.withWriteTransaction
+import androidx.sqlite.SQLiteException
+import androidx.sqlite.driver.AndroidSQLiteDriver
+import androidx.sqlite.driver.bundled.BundledSQLiteDriver
+import androidx.test.core.app.ApplicationProvider
+import androidx.test.filters.SmallTest
+import kotlinx.coroutines.test.runTest
+import org.junit.After
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.Parameterized
+import org.junit.runners.Parameterized.Parameters
+
+@SmallTest
+@RunWith(Parameterized::class)
+class ForeignKeyTest(private val useDriver: UseDriver) {
+
+    private companion object {
+        @JvmStatic
+        @Parameters(name = "useDriver={0}")
+        fun parameters() = arrayOf(UseDriver.ANDROID, UseDriver.BUNDLED)
+    }
+
+    @Database(
+        version = 1,
+        entities = [A::class, B::class, C::class, D::class, E::class],
+        exportSchema = false,
+    )
+    internal abstract class ForeignKeyDb : RoomDatabase() {
+        abstract fun dao(): FkDao
+    }
+
+    @Dao
+    internal interface FkDao {
+        @Insert suspend fun insert(vararg a: A)
+
+        @Insert suspend fun insert(vararg b: B)
+
+        @Insert suspend fun insert(vararg c: C)
+
+        @Insert suspend fun insert(vararg d: D)
+
+        @Query("SELECT * FROM A WHERE id = :id") suspend fun loadA(id: Int): A?
+
+        @Query("SELECT * FROM B WHERE id = :id") suspend fun loadB(id: Int): B?
+
+        @Query("SELECT * FROM C WHERE id = :id") suspend fun loadC(id: Int): C?
+
+        @Query("SELECT * FROM D WHERE id = :id") suspend fun loadD(id: Int): D?
+
+        @Query("SELECT * FROM E WHERE id = :id") suspend fun loadE(id: Int): E?
+
+        @Delete suspend fun delete(vararg a: A)
+
+        @Delete suspend fun delete(vararg b: B)
+
+        @Delete suspend fun delete(vararg c: C)
+
+        @Query("UPDATE A SET name = :newName WHERE id = :id")
+        suspend fun changeNameA(id: Int, newName: String)
+
+        @Insert suspend fun insert(vararg e: E)
+    }
+
+    @Entity(
+        indices = [Index(value = ["name"], unique = true), Index("name", "lastName", unique = true)]
+    )
+    internal data class A(
+        @PrimaryKey(autoGenerate = true) var id: Int = 0,
+        var name: String,
+        var lastName: String? = null,
+    )
+
+    @Entity(
+        foreignKeys =
+            [ForeignKey(entity = A::class, parentColumns = ["name"], childColumns = ["aName"])],
+        indices = [Index("aName")],
+    )
+    internal data class B(@PrimaryKey(autoGenerate = true) var id: Int = 0, var aName: String)
+
+    @Entity(
+        foreignKeys =
+            [
+                ForeignKey(
+                    entity = A::class,
+                    parentColumns = ["name"],
+                    childColumns = ["aName"],
+                    deferred = true,
+                )
+            ],
+        indices = [Index("aName")],
+    )
+    internal data class C(@PrimaryKey(autoGenerate = true) var id: Int = 0, var aName: String)
+
+    @Entity(
+        foreignKeys =
+            [
+                ForeignKey(
+                    entity = A::class,
+                    parentColumns = ["name"],
+                    childColumns = ["aName"],
+                    onDelete = ForeignKey.CASCADE,
+                    onUpdate = ForeignKey.CASCADE,
+                )
+            ],
+        indices = [Index("aName")],
+    )
+    internal data class D(@PrimaryKey(autoGenerate = true) var id: Int = 0, var aName: String)
+
+    @Entity(
+        foreignKeys =
+            [
+                ForeignKey(
+                    entity = A::class,
+                    parentColumns = ["name", "lastName"],
+                    childColumns = ["aName", "aLastName"],
+                    onDelete = ForeignKey.SET_NULL,
+                    onUpdate = ForeignKey.CASCADE,
+                )
+            ],
+        indices = [Index("aName", "aLastName")],
+    )
+    internal data class E(
+        @PrimaryKey(autoGenerate = true) var id: Int = 0,
+        var aName: String? = null,
+        var aLastName: String? = null,
+    )
+
+    private lateinit var db: ForeignKeyDb
+    private lateinit var dao: FkDao
+
+    @Before
+    fun openDb() {
+        db =
+            Room.inMemoryDatabaseBuilder<ForeignKeyDb>(ApplicationProvider.getApplicationContext())
+                .apply {
+                    if (useDriver == UseDriver.ANDROID) {
+                        setDriver(AndroidSQLiteDriver())
+                    } else if (useDriver == UseDriver.BUNDLED) {
+                        setDriver(BundledSQLiteDriver())
+                    }
+                }
+                .build()
+        dao = db.dao()
+    }
+
+    @After
+    fun closeDb() {
+        db.close()
+    }
+
+    @Test
+    fun simpleForeignKeyFailure() = runTest {
+        assertThrowsForeignKeyError { dao.insert(B(aName = "foo")) }
+    }
+
+    @Test
+    fun simpleForeignKeyDeferredFailure() = runTest {
+        assertThrowsForeignKeyError { dao.insert(C(aName = "foo")) }
+    }
+
+    @Test
+    @OptIn(ExperimentalRoomApi::class)
+    fun immediateForeignKeyFailure() = runTest {
+        assertThrowsForeignKeyError {
+            db.withWriteTransaction {
+                dao.insert(B(aName = "foo"))
+                dao.insert(A(name = "foo"))
+            }
+        }
+    }
+
+    @Test
+    @OptIn(ExperimentalRoomApi::class)
+    fun deferredForeignKeySuccess() = runTest {
+        db.withWriteTransaction {
+            dao.insert(C(aName = "foo"))
+            dao.insert(A(name = "foo"))
+        }
+        assertThat(dao.loadA(1)).isNotNull()
+        assertThat(dao.loadC(1)).isNotNull()
+    }
+
+    @Test
+    fun onDelete_noAction() = runTest {
+        dao.insert(A(name = "a1"))
+        val a = checkNotNull(dao.loadA(1))
+        dao.insert(B(aName = "a1"))
+        assertThrowsForeignKeyError { dao.delete(a) }
+    }
+
+    @Test
+    @OptIn(ExperimentalRoomApi::class)
+    fun onDelete_noAction_withTransaction() = runTest {
+        dao.insert(A(name = "a1"))
+        val a = checkNotNull(dao.loadA(1))
+        dao.insert(B(aName = "a1"))
+        val b = checkNotNull(dao.loadB(1))
+        assertThrowsForeignKeyError {
+            db.withWriteTransaction {
+                dao.delete(a)
+                dao.delete(b)
+            }
+        }
+    }
+
+    @Test
+    fun onDelete_noAction_deferred() = runTest {
+        dao.insert(A(name = "a1"))
+        val a = checkNotNull(dao.loadA(1))
+        dao.insert(C(aName = "a1"))
+        assertThrowsForeignKeyError { dao.delete(a) }
+    }
+
+    @Test
+    @OptIn(ExperimentalRoomApi::class)
+    fun onDelete_noAction__deferredWithTransaction() = runTest {
+        dao.insert(A(name = "a1"))
+        val a = checkNotNull(dao.loadA(1))
+        dao.insert(C(aName = "a1"))
+        val c = checkNotNull(dao.loadC(1))
+        db.withWriteTransaction {
+            dao.delete(a)
+            dao.delete(c)
+        }
+    }
+
+    @Test
+    fun onDelete_cascade() = runTest {
+        dao.insert(A(name = "a1"))
+        val a = checkNotNull(dao.loadA(1))
+        dao.insert(D(aName = "a1"))
+        val d = dao.loadD(1)
+        assertThat(d).isNotNull()
+        dao.delete(a)
+        assertThat(dao.loadD(1)).isNull()
+    }
+
+    @Test
+    fun onUpdate_cascade() = runTest {
+        dao.insert(A(name = "a1"))
+        dao.insert(D(aName = "a1"))
+        val d = dao.loadD(1)
+        assertThat(d).isNotNull()
+        dao.changeNameA(1, "bla")
+        assertThat(dao.loadD(1)!!.aName).isEqualTo("bla")
+        assertThat(dao.loadA(1)!!.name).isEqualTo("bla")
+    }
+
+    @Test
+    fun multipleReferences() = runTest {
+        dao.insert(A(name = "a1", lastName = "a2"))
+        val a = dao.loadA(1)
+        assertThat(a).isNotNull()
+        assertThrowsForeignKeyError { dao.insert(E(aName = "a1", aLastName = "dsa")) }
+    }
+
+    @Test
+    fun onDelete_setNull_multipleReferences() = runTest {
+        dao.insert(A(name = "a1", lastName = "a2"))
+        val a = checkNotNull(dao.loadA(1))
+        dao.insert(E(aName = "a1", aLastName = "a2"))
+        assertThat(dao.loadE(1)).isNotNull()
+        dao.delete(a)
+        val e = checkNotNull(dao.loadE(1))
+        assertThat(e.aName).isNull()
+        assertThat(e.aLastName).isNull()
+    }
+
+    @Test
+    fun onUpdate_cascade_multipleReferences() = runTest {
+        dao.insert(A(name = "a1", lastName = "a2"))
+        dao.insert(E(aName = "a1", aLastName = "a2"))
+        assertThat(dao.loadE(1)).isNotNull()
+        dao.changeNameA(1, "foo")
+        assertThat(dao.loadE(1)).isNotNull()
+        assertThat(dao.loadE(1)!!.aName).isEqualTo("foo")
+        assertThat(dao.loadE(1)!!.aLastName).isEqualTo("a2")
+    }
+
+    private inline fun assertThrowsForeignKeyError(block: () -> Unit) =
+        assertThrows<SQLiteException>(block).hasMessageThat().contains("FOREIGN KEY")
+}
diff --git a/room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/test/FtsTableTest.kt b/room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/test/FtsTableTest.kt
new file mode 100644
index 0000000..094ff40
--- /dev/null
+++ b/room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/test/FtsTableTest.kt
@@ -0,0 +1,265 @@
+/*
+ * Copyright 2018 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 androidx.room3.integration.kotlintestapp.test
+
+import android.content.Context
+import androidx.kruth.assertThat
+import androidx.room3.Room
+import androidx.room3.integration.kotlintestapp.FtsTestDatabase
+import androidx.room3.integration.kotlintestapp.dao.MailDao
+import androidx.room3.integration.kotlintestapp.dao.SongDao
+import androidx.room3.integration.kotlintestapp.test.TestDatabaseTest.UseDriver
+import androidx.room3.integration.kotlintestapp.vo.Song
+import androidx.sqlite.driver.AndroidSQLiteDriver
+import androidx.sqlite.driver.bundled.BundledSQLiteDriver
+import androidx.test.core.app.ApplicationProvider
+import androidx.test.filters.SmallTest
+import kotlinx.coroutines.flow.produceIn
+import kotlinx.coroutines.test.runTest
+import org.junit.After
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.Parameterized
+import org.junit.runners.Parameterized.Parameters
+
+@SmallTest
+@RunWith(Parameterized::class)
+class FtsTableTest(private val useDriver: UseDriver) {
+
+    private companion object {
+        @JvmStatic
+        @Parameters(name = "useDriver={0}")
+        fun parameters() = arrayOf(UseDriver.ANDROID, UseDriver.BUNDLED)
+    }
+
+    private lateinit var database: FtsTestDatabase
+    private lateinit var mailDao: MailDao
+    private lateinit var songDao: SongDao
+
+    @Before
+    fun setup() {
+        val context: Context = ApplicationProvider.getApplicationContext()
+        database =
+            Room.inMemoryDatabaseBuilder<FtsTestDatabase>(context)
+                .apply {
+                    if (useDriver == UseDriver.ANDROID) {
+                        setDriver(AndroidSQLiteDriver())
+                    } else if (useDriver == UseDriver.BUNDLED) {
+                        setDriver(BundledSQLiteDriver())
+                    }
+                }
+                .build()
+        mailDao = database.getMailDao()
+        songDao = database.getSongDao()
+    }
+
+    @After
+    fun teardown() {
+        database.close()
+    }
+
+    @Test
+    fun readWrite() {
+        val item = TestUtil.createMail(1, "Hello old friend", "How are you? Wanna grab coffee?")
+        mailDao.insert(item)
+        val loaded = mailDao.getMail("coffee")
+        assertThat(loaded[0]).isEqualTo(item)
+    }
+
+    @Test
+    fun prefixQuery() {
+        val item1 = TestUtil.createMail(1, "Linux problem", "Hi - Need help with my linux machine.")
+        val item2 =
+            TestUtil.createMail(
+                2,
+                "Math help needed",
+                "Anyone able to help me with linear algebra?",
+            )
+        val item3 = TestUtil.createMail(3, "Chef needed", "Need a cheeseburger check ASAP")
+        mailDao.insert(listOf(item1, item2, item3))
+        val loaded = mailDao.getMail("lin*")
+        assertThat(loaded).hasSize(2)
+        assertThat(loaded[0]).isEqualTo(item1)
+        assertThat(loaded[1]).isEqualTo(item2)
+    }
+
+    @Test
+    fun prefixQuery_multiple() {
+        val item1 = TestUtil.createMail(1, "Linux problem", "Hi - Need help with my linux machine.")
+        val item2 =
+            TestUtil.createMail(
+                2,
+                "Math help needed",
+                "Anyone able to help me with linear algebra?",
+            )
+        val item3 = TestUtil.createMail(3, "Chef needed", "Need a cheeseburger check ASAP")
+        mailDao.insert(listOf(item1, item2, item3))
+        val loaded = mailDao.getMail("help linux")
+        assertThat(loaded).hasSize(1)
+        assertThat(loaded[0]).isEqualTo(item1)
+    }
+
+    @Test
+    fun prefixQuery_multiple_OR() {
+        val item1 = TestUtil.createMail(1, "Linux problem", "Hi - Need help with my linux machine.")
+        val item2 =
+            TestUtil.createMail(
+                2,
+                "Math help needed",
+                "Anyone able to help me with linear algebra?",
+            )
+        val item3 = TestUtil.createMail(3, "Chef needed", "Need a cheeseburger check ASAP")
+        mailDao.insert(listOf(item1, item2, item3))
+        val loaded = mailDao.getMail("linux OR linear")
+        assertThat(loaded).hasSize(2)
+        assertThat(loaded[0]).isEqualTo(item1)
+        assertThat(loaded[1]).isEqualTo(item2)
+    }
+
+    @Test
+    fun prefixQuery_body() {
+        val item1 = TestUtil.createMail(1, "Linux problem", "Hi - Need help with my linux machine.")
+        val item2 =
+            TestUtil.createMail(
+                2,
+                "Math help needed",
+                "Anyone able to help me with linear algebra?",
+            )
+        val item3 = TestUtil.createMail(3, "Chef needed", "Need a cheeseburger check ASAP")
+        mailDao.insert(listOf(item1, item2, item3))
+        val loaded = mailDao.getMailWithBody("subject:help algebra")
+        assertThat(loaded).hasSize(1)
+        assertThat(loaded[0]).isEqualTo(item2)
+    }
+
+    @Test
+    fun prefixQuery_startsWith() {
+        val item = TestUtil.createMail(1, "Hello old friend", "How are you? Wanna grab coffee?")
+        mailDao.insert(item)
+        val loaded = mailDao.getMailWithSubject("^hello")
+        assertThat(loaded[0]).isEqualTo(item)
+    }
+
+    @Test
+    fun phraseQuery() {
+        val item1 = TestUtil.createMail(1, "Linux problem", "Hi - Need help with my linux machine.")
+        val item2 =
+            TestUtil.createMail(
+                2,
+                "Math help needed",
+                "Anyone able to help me with linear algebra?",
+            )
+        mailDao.insert(listOf(item1, item2))
+        val loaded = mailDao.getMail("\"help me\"")
+        assertThat(loaded).hasSize(1)
+        assertThat(loaded[0]).isEqualTo(item2)
+    }
+
+    @Test
+    fun nearQuery() {
+        val item = TestUtil.createMail(1, "Hello old friend", "How are you? Wanna grab coffee?")
+        mailDao.insert(item)
+        val loaded = mailDao.getMail("coffee")
+        assertThat(loaded[0]).isEqualTo(item)
+    }
+
+    @Test
+    fun snippetQuery() {
+        val item1 = TestUtil.createMail(1, "Linux problem", "Hi - Need help with my linux machine.")
+        val item2 =
+            TestUtil.createMail(
+                2,
+                "Math help needed",
+                "Hello dear friends. I am in desperate need for some help. " +
+                    "I've taken a lot of tutorials online but I still don't understand. " +
+                    "Is anyone available to please help with some linear algebra?",
+            )
+        mailDao.insert(listOf(item1, item2))
+        val loaded = mailDao.getMailBodySnippets("help")
+        assertThat(loaded).hasSize(2)
+        assertThat(loaded[0]).isEqualTo("Hi - Need <b>help</b> with my linux machine.")
+        assertThat(loaded[1])
+            .isEqualTo(
+                "<b>...</b>I am in desperate need for some <b>help</b>." +
+                    " I've taken a lot of tutorials<b>...</b>"
+            )
+    }
+
+    @Test
+    fun specialCommand_optimize() {
+        val item = TestUtil.createMail(1, "Hello old friend", "How are you? Wanna grab coffee?")
+        mailDao.insert(item)
+        mailDao.optimizeMail()
+    }
+
+    @Test
+    fun specialCommand_rebuild() {
+        val item = TestUtil.createMail(1, "Hello old friend", "How are you? Wanna grab coffee?")
+        mailDao.insert(item)
+        mailDao.rebuildMail()
+    }
+
+    @Test
+    fun externalContent() {
+        val item1 = Song(1, "Solos (Remix)", "Plan B", "Solos", 225, 2009)
+        val item2 = Song(2, "La Barría", "Wisin & Yandel", "Pa'l Mundo", 177, 2005)
+        songDao.insert(listOf(item1, item2))
+        val descLoaded = songDao.getSongDescriptions("remix")
+        assertThat(descLoaded).hasSize(1)
+        assertThat(descLoaded[0].mTitle).isEqualTo(item1.mTitle)
+        val songLoaded = songDao.getSongs("remix")
+        assertThat(songLoaded).hasSize(1)
+        assertThat(songLoaded[0]).isEqualTo(item1)
+    }
+
+    @Test
+    fun flow() = runTest {
+        val mail = mailDao.getFlowDataMail().produceIn(this)
+        assertThat(mail.receive()).isEmpty()
+
+        val item = TestUtil.createMail(1, "Hello old friend", "How are you? Wanna grab coffee?")
+        mailDao.insert(item)
+        assertThat(mail.receive()).containsExactly(item)
+
+        mail.cancel()
+    }
+
+    @Test
+    fun flow_externalContent() = runTest {
+        val songs = songDao.getFlowSong().produceIn(this)
+        val songDescriptions = songDao.getFlowSongDescription().produceIn(this)
+
+        assertThat(songs.receive()).isEmpty()
+        assertThat(songDescriptions.receive()).isEmpty()
+
+        val song1 = Song(1, "Estamos Bien", "Bad Bunny", "X 100Pre", 208, 2018)
+        songDao.insert(song1)
+
+        assertThat(songs.receive()).containsExactly(song1)
+        assertThat(songDescriptions.receive().map { it.mTitle }).containsExactly(song1.mTitle)
+
+        val song2 = Song(2, "RLNDT", "Bad Bunny", "X 100Pre", 284, 2018)
+        songDao.insert(song2)
+
+        assertThat(songs.receive()).containsExactly(song1, song2)
+        assertThat(songDescriptions.receive().map { it.mTitle })
+            .containsExactly(song1.mTitle, song2.mTitle)
+
+        songs.cancel()
+        songDescriptions.cancel()
+    }
+}
diff --git a/room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/test/FunnyNamedDaoTest.kt b/room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/test/FunnyNamedDaoTest.kt
new file mode 100644
index 0000000..a8c8517
--- /dev/null
+++ b/room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/test/FunnyNamedDaoTest.kt
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2017 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 androidx.room3.integration.kotlintestapp.test
+
+import androidx.kruth.assertThat
+import androidx.room3.integration.kotlintestapp.vo.FunnyNamedEntity
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class FunnyNamedDaoTest : TestDatabaseTest() {
+
+    @Test
+    fun readWrite() {
+        val entity = FunnyNamedEntity(1, "a")
+        database.funnyNamedDao().insert(entity)
+        val loaded = database.funnyNamedDao().load(1)
+        assertThat(loaded).isEqualTo(entity)
+    }
+
+    @Test
+    fun update() {
+        val entity = FunnyNamedEntity(1, "a")
+        database.funnyNamedDao().insert(entity)
+        entity.value = "b"
+        database.funnyNamedDao().update(entity)
+        val loaded = database.funnyNamedDao().load(1)
+        assertThat(loaded!!.value).isEqualTo("b")
+    }
+
+    @Test
+    fun delete() {
+        val entity = FunnyNamedEntity(1, "a")
+        database.funnyNamedDao().insert(entity)
+        assertThat(database.funnyNamedDao().load(1)).isNotNull()
+        database.funnyNamedDao().delete(entity)
+        assertThat(database.funnyNamedDao().load(1)).isNull()
+    }
+}
diff --git a/room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/test/GenericEntityTest.kt b/room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/test/GenericEntityTest.kt
new file mode 100644
index 0000000..6bba294
--- /dev/null
+++ b/room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/test/GenericEntityTest.kt
@@ -0,0 +1,124 @@
+/*
+ * Copyright 2018 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 androidx.room3.integration.kotlintestapp.test
+
+import androidx.kruth.assertThat
+import androidx.room3.Dao
+import androidx.room3.Database
+import androidx.room3.Entity
+import androidx.room3.Insert
+import androidx.room3.PrimaryKey
+import androidx.room3.Query
+import androidx.room3.Room
+import androidx.room3.RoomDatabase
+import androidx.sqlite.driver.AndroidSQLiteDriver
+import androidx.test.core.app.ApplicationProvider
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import org.junit.After
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class GenericEntityTest {
+    private lateinit var db: GenericDb
+    private lateinit var dao: GenericDao
+
+    @Before
+    fun init() {
+        db =
+            Room.inMemoryDatabaseBuilder<GenericDb>(ApplicationProvider.getApplicationContext())
+                .setDriver(AndroidSQLiteDriver())
+                .build()
+        dao = db.getDao()
+    }
+
+    @After
+    fun close() {
+        db.close()
+    }
+
+    @Test
+    fun readWriteEntity() {
+        val item = EntityItem("abc", "def")
+        dao.insert(item)
+        val received = dao.get("abc")
+        assertThat(received).isEqualTo(item)
+    }
+
+    @Test
+    fun readPojo() {
+        val item = EntityItem("abc", "def")
+        dao.insert(item)
+        val received = dao.getPojo("abc")
+        assertThat(received.id).isEqualTo("abc")
+    }
+
+    open class Item<P, F>(@PrimaryKey val id: P) {
+        var field: F? = null
+
+        override fun equals(other: Any?): Boolean {
+            if (this === other) return true
+            if (other !is Item<*, *>) return false
+
+            if (id != other.id) return false
+            if (field != other.field) return false
+
+            return true
+        }
+
+        override fun hashCode(): Int {
+            var result = id?.hashCode() ?: 0
+            result = 31 * result + (field?.hashCode() ?: 0)
+            return result
+        }
+    }
+
+    class PoKoItem(id: String) : Item<String, Int>(id)
+
+    @Entity
+    class EntityItem(id: String, val name: String) : Item<String, Int>(id) {
+        override fun equals(other: Any?): Boolean {
+            if (this === other) return true
+            if (other == null || javaClass != other.javaClass) return false
+            if (!super.equals(other)) return false
+            val that = other as EntityItem
+            return name == that.name
+        }
+
+        override fun hashCode(): Int {
+            var result = super.hashCode()
+            result = 31 * result + name.hashCode()
+            return result
+        }
+    }
+
+    @Dao
+    interface GenericDao {
+        @Insert fun insert(vararg items: EntityItem)
+
+        @Query("SELECT * FROM EntityItem WHERE id = :id") fun get(id: String): EntityItem
+
+        @Query("SELECT id, field FROM EntityItem WHERE id = :id") fun getPojo(id: String): PoKoItem
+    }
+
+    @Database(version = 1, entities = [EntityItem::class], exportSchema = false)
+    abstract class GenericDb : RoomDatabase() {
+        abstract fun getDao(): GenericDao
+    }
+}
diff --git a/room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/test/IndexingTest.kt b/room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/test/IndexingTest.kt
new file mode 100644
index 0000000..7560f2f
--- /dev/null
+++ b/room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/test/IndexingTest.kt
@@ -0,0 +1,120 @@
+/*
+ * Copyright (C) 2017 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 androidx.room3.integration.kotlintestapp.test
+
+import androidx.kruth.assertThat
+import androidx.room3.ColumnInfo
+import androidx.room3.Dao
+import androidx.room3.Database
+import androidx.room3.Entity
+import androidx.room3.Index
+import androidx.room3.Insert
+import androidx.room3.PrimaryKey
+import androidx.room3.Query
+import androidx.room3.Room
+import androidx.room3.RoomDatabase
+import androidx.sqlite.driver.AndroidSQLiteDriver
+import androidx.test.core.app.ApplicationProvider
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class IndexingTest {
+
+    @Entity(
+        tableName = "foo_table",
+        indices =
+            [
+                Index("field1", "field2"),
+                Index(value = ["field2", "id"], unique = true),
+                Index(value = ["field2"], unique = true, name = "customIndex"),
+            ],
+    )
+    data class Entity1(
+        @PrimaryKey val id: Int,
+        val field1: String,
+        val field2: String,
+        @ColumnInfo(index = true, name = "my_field") val field3: String,
+    )
+
+    data class IndexInfo(
+        val name: String,
+        @ColumnInfo(name = "tbl_name") val tableName: String,
+        val sql: String,
+    )
+
+    @Dao
+    internal interface Entity1Dao {
+        @Insert fun insert(item: Entity1)
+
+        @Query("SELECT * FROM foo_table indexed by customIndex where field2 = :inp")
+        fun indexedBy(inp: String): List<Entity1>
+    }
+
+    @Dao
+    internal interface SqlMasterDao {
+        @Query("SELECT name, tbl_name, sql FROM sqlite_master WHERE type = 'index'")
+        fun loadIndices(): List<IndexInfo>
+    }
+
+    @Database(entities = [Entity1::class], version = 1, exportSchema = false)
+    internal abstract class IndexingDb : RoomDatabase() {
+        abstract fun sqlMasterDao(): SqlMasterDao
+
+        abstract fun entity1Dao(): Entity1Dao
+    }
+
+    @Test
+    fun verifyIndices() {
+        val db =
+            Room.inMemoryDatabaseBuilder<IndexingDb>(ApplicationProvider.getApplicationContext())
+                .setDriver(AndroidSQLiteDriver())
+                .build()
+        val indices = db.sqlMasterDao().loadIndices()
+        assertThat(indices).hasSize(4)
+        for (info in indices) {
+            assertThat(info.tableName).isEqualTo("foo_table")
+        }
+        assertThat(indices[0].sql)
+            .isEqualTo(
+                "CREATE INDEX `index_foo_table_field1_field2` ON `foo_table` (`field1`, `field2`)"
+            )
+        assertThat(indices[1].sql)
+            .isEqualTo(
+                "CREATE UNIQUE INDEX `index_foo_table_field2_id` ON `foo_table` (`field2`, `id`)"
+            )
+        assertThat(indices[2].sql)
+            .isEqualTo("CREATE UNIQUE INDEX `customIndex` ON `foo_table` (`field2`)")
+        assertThat(indices[3].sql)
+            .isEqualTo("CREATE INDEX `index_foo_table_my_field` ON `foo_table` (`my_field`)")
+        db.close()
+    }
+
+    @Test
+    fun indexedByQuery() {
+        val db =
+            Room.inMemoryDatabaseBuilder<IndexingDb>(ApplicationProvider.getApplicationContext())
+                .setDriver(AndroidSQLiteDriver())
+                .build()
+        db.entity1Dao().insert(Entity1(1, "a", "b", "c"))
+        val result = db.entity1Dao().indexedBy("b")
+        assertThat(result).hasSize(1)
+        db.close()
+    }
+}
diff --git a/room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/test/InvalidationTest.kt b/room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/test/InvalidationTest.kt
new file mode 100644
index 0000000..6cc721c
--- /dev/null
+++ b/room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/test/InvalidationTest.kt
@@ -0,0 +1,259 @@
+/*
+ * Copyright 2025 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 androidx.room3.integration.kotlintestapp.test
+
+import androidx.kruth.assertThat
+import androidx.room3.immediateTransaction
+import androidx.room3.integration.kotlintestapp.vo.Album
+import androidx.room3.integration.kotlintestapp.vo.Playlist
+import androidx.room3.integration.kotlintestapp.vo.PlaylistSongXRef
+import androidx.room3.integration.kotlintestapp.vo.Song
+import androidx.room3.useWriterConnection
+import androidx.test.filters.SmallTest
+import kotlinx.coroutines.flow.produceIn
+import kotlinx.coroutines.test.runTest
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.Parameterized
+import org.junit.runners.Parameterized.Parameters
+
+@SmallTest
+@RunWith(Parameterized::class)
+class InvalidationTest(driver: UseDriver) :
+    TestDatabaseTest(useDriver = driver, useInMemoryDatabase = false) {
+
+    private companion object {
+        @JvmStatic
+        @Parameters(name = "useDriver={0}")
+        fun parameters() = arrayOf(UseDriver.ANDROID, UseDriver.BUNDLED)
+    }
+
+    @Test
+    fun invalidationOnInsert() = runTest {
+        val publishers = booksDao.getPublishersFlow().produceIn(this)
+        assertThat(publishers.receive()).isEmpty()
+
+        booksDao.addPublishers(TestUtil.PUBLISHER)
+        assertThat(publishers.receive()).containsExactly(TestUtil.PUBLISHER)
+
+        publishers.cancel()
+    }
+
+    @Test
+    fun invalidationOnUpdate() = runTest {
+        booksDao.addPublishers(TestUtil.PUBLISHER)
+
+        val publishers = booksDao.getPublishersFlow().produceIn(this)
+        assertThat(publishers.receive()).containsExactly(TestUtil.PUBLISHER)
+
+        booksDao.updatePublishers(TestUtil.PUBLISHER.copy(name = "updatedName"))
+        assertThat(publishers.receive().single().name).isEqualTo("updatedName")
+
+        publishers.cancel()
+    }
+
+    @Test
+    fun invalidationOnDelete() = runTest {
+        booksDao.addPublishers(TestUtil.PUBLISHER)
+
+        val publishers = booksDao.getPublishersFlow().produceIn(this)
+        assertThat(publishers.receive()).containsExactly(TestUtil.PUBLISHER)
+
+        booksDao.deletePublishers(TestUtil.PUBLISHER)
+        assertThat(publishers.receive()).isEmpty()
+
+        publishers.cancel()
+    }
+
+    @Test
+    fun invalidationUsingWriteConnection() = runTest {
+        val publishers = booksDao.getPublishersFlow().produceIn(this)
+        assertThat(publishers.receive()).isEmpty()
+
+        database.useWriterConnection { connection ->
+            connection.usePrepared("INSERT INTO publisher (publisherId, name) VALUES (?, ?)") { stmt
+                ->
+                stmt.bindText(1, TestUtil.PUBLISHER.publisherId)
+                stmt.bindText(2, TestUtil.PUBLISHER.name)
+                stmt.step()
+            }
+        }
+        assertThat(publishers.receive()).containsExactly(TestUtil.PUBLISHER)
+
+        publishers.cancel()
+    }
+
+    @Test
+    fun invalidationUsingWriteTransaction() = runTest {
+        val publishers = booksDao.getPublishersFlow().produceIn(this)
+        assertThat(publishers.receive()).isEmpty()
+
+        database.useWriterConnection { connection ->
+            connection.immediateTransaction {
+                connection.usePrepared("INSERT INTO publisher (publisherId, name) VALUES (?, ?)") {
+                    stmt ->
+                    stmt.reset()
+                    stmt.bindText(1, TestUtil.PUBLISHER.publisherId)
+                    stmt.bindText(2, TestUtil.PUBLISHER.name)
+                    stmt.step()
+
+                    stmt.reset()
+                    stmt.bindText(1, TestUtil.PUBLISHER2.publisherId)
+                    stmt.bindText(2, TestUtil.PUBLISHER2.name)
+                    stmt.step()
+
+                    stmt.reset()
+                    stmt.bindText(1, TestUtil.PUBLISHER3.publisherId)
+                    stmt.bindText(2, TestUtil.PUBLISHER3.name)
+                    stmt.step()
+                }
+            }
+        }
+        assertThat(publishers.receive())
+            .containsExactly(TestUtil.PUBLISHER, TestUtil.PUBLISHER2, TestUtil.PUBLISHER3)
+
+        publishers.cancel()
+    }
+
+    @Test
+    fun invalidationOfRelationOneToMany() = runTest {
+        database
+            .musicDao()
+            .addAlbums(
+                Album(
+                    mAlbumId = 1,
+                    mAlbumName = "DATA",
+                    mAlbumArtist = "Tainy",
+                    mAlbumReleaseYear = 2023,
+                    mFeaturedArtist = null,
+                )
+            )
+        database
+            .musicDao()
+            .addSongs(
+                Song(
+                    mSongId = 5,
+                    mTitle = "Mojabi Ghost",
+                    mArtist = "Tainy & Bad Bunny",
+                    mAlbum = "DATA",
+                    mLength = 233,
+                    mReleasedYear = 2023,
+                )
+            )
+
+        val album = database.musicDao().getAlbumWithSongsFlow(1).produceIn(this)
+        assertThat(album.receive().songs.map { it.mTitle }).containsExactly("Mojabi Ghost")
+
+        database
+            .musicDao()
+            .addSongs(
+                Song(
+                    mSongId = 6,
+                    mTitle = "11 y Once",
+                    mArtist = "Tainy, Sech & E.VAX",
+                    mAlbum = "DATA",
+                    mLength = 197,
+                    mReleasedYear = 2023,
+                )
+            )
+        assertThat(album.receive().songs.map { it.mTitle })
+            .containsExactly("Mojabi Ghost", "11 y Once")
+
+        album.cancel()
+    }
+
+    @Test
+    fun invalidationOfRelationManyToMany() = runTest {
+        database.musicDao().addPlaylists(Playlist(1))
+        database
+            .musicDao()
+            .addSongs(
+                Song(
+                    mSongId = 787,
+                    mTitle = "Tú Con Él",
+                    mArtist = "Frankie Ruiz",
+                    mAlbum = "Solista pero no solo",
+                    mLength = 301,
+                    mReleasedYear = 1985,
+                )
+            )
+        database.musicDao().addPlaylistSongRelations(PlaylistSongXRef(1, 787))
+
+        val playlist = database.musicDao().getPlaylistsWithSongsFlow(1).produceIn(this)
+        assertThat(playlist.receive().songs.map { it.mArtist }).containsExactly("Frankie Ruiz")
+
+        database
+            .musicDao()
+            .updateSong(
+                Song(
+                    mSongId = 787,
+                    mTitle = "Tú Con Él",
+                    mArtist = "Rauw Alejandro",
+                    mAlbum = "Cosa Nuestra",
+                    mLength = 290,
+                    mReleasedYear = 2024,
+                )
+            )
+        assertThat(playlist.receive().songs.map { it.mArtist }).containsExactly("Rauw Alejandro")
+
+        playlist.cancel()
+    }
+
+    @Test
+    fun invalidationOfRelationManyToManyJunction() = runTest {
+        database.musicDao().addPlaylists(Playlist(1))
+        database
+            .musicDao()
+            .addSongs(
+                Song(
+                    mSongId = 14,
+                    mTitle = "Safaera",
+                    mArtist = "Bad Bunny, Jowell & Randy & Ñengo Flow",
+                    mAlbum = "YHLQMDLG",
+                    mLength = 296,
+                    mReleasedYear = 2020,
+                ),
+                Song(
+                    mSongId = 15,
+                    mTitle = "EoO",
+                    mArtist = "Bad Bunny",
+                    mAlbum = "DeBÍ TiRAR MáS FOToS",
+                    mLength = 205,
+                    mReleasedYear = 2025,
+                ),
+                Song(
+                    mSongId = 10,
+                    mTitle = "COLMILLO",
+                    mArtist = "Tainy, J Balvin & Young Miko (feat. Jowell & Randy)",
+                    mAlbum = "DATA",
+                    mLength = 266,
+                    mReleasedYear = 2023,
+                ),
+            )
+        database.musicDao().addPlaylistSongRelations(PlaylistSongXRef(1, 14))
+        database.musicDao().addPlaylistSongRelations(PlaylistSongXRef(1, 15))
+
+        val playlist = database.musicDao().getPlaylistsWithSongsFlow(1).produceIn(this)
+        assertThat(playlist.receive().songs.map { it.mTitle }).containsExactly("Safaera", "EoO")
+
+        database.musicDao().addPlaylistSongRelations(PlaylistSongXRef(1, 10))
+        assertThat(playlist.receive().songs.map { it.mTitle })
+            .containsExactly("Safaera", "EoO", "COLMILLO")
+
+        playlist.cancel()
+    }
+}
diff --git a/room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/test/LegacyIdentityHashTest.kt b/room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/test/LegacyIdentityHashTest.kt
new file mode 100644
index 0000000..238b59e
--- /dev/null
+++ b/room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/test/LegacyIdentityHashTest.kt
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2024 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 androidx.room3.integration.kotlintestapp.test
+
+import android.content.Context
+import androidx.room3.Database
+import androidx.room3.Entity
+import androidx.room3.PrimaryKey
+import androidx.room3.Room
+import androidx.room3.RoomDatabase
+import androidx.room3.RoomMasterTable
+import androidx.room3.execSQL
+import androidx.room3.useReaderConnection
+import androidx.room3.useWriterConnection
+import androidx.sqlite.driver.AndroidSQLiteDriver
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import androidx.test.platform.app.InstrumentationRegistry
+import kotlinx.coroutines.test.runTest
+import org.junit.After
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class LegacyIdentityHashTest {
+    private val targetContext: Context = InstrumentationRegistry.getInstrumentation().targetContext
+    private val databaseName = "legacy-test.db"
+
+    @Before
+    fun setup() {
+        targetContext.deleteDatabase(databaseName)
+    }
+
+    @After
+    fun teardown() {
+        targetContext.deleteDatabase(databaseName)
+    }
+
+    @Test
+    fun openDatabaseWithLegacyHash() = runTest {
+        val dbBuilder =
+            Room.databaseBuilder<LegacyDatabase>(targetContext, "legacy-test.db")
+                .setDriver(AndroidSQLiteDriver())
+        val newDb = dbBuilder.build()
+        newDb.useWriterConnection {
+            val insertQuery = RoomMasterTable.createInsertQuery("7814fcab45e43fa07f359c1be74bd6c9")
+            it.execSQL(insertQuery)
+        }
+        newDb.close()
+
+        val legacyDb = dbBuilder.build()
+        legacyDb.useReaderConnection {
+            // opens the database
+        }
+        legacyDb.close()
+    }
+
+    @Database(entities = [TestDataEntity::class], version = 1, exportSchema = false)
+    abstract class LegacyDatabase : RoomDatabase()
+
+    @Entity data class TestDataEntity(@PrimaryKey var id: Long? = null)
+}
diff --git a/room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/test/MissingMasterTableTest.kt b/room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/test/MissingMasterTableTest.kt
index 9f09455..2cdcbec 100644
--- a/room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/test/MissingMasterTableTest.kt
+++ b/room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/test/MissingMasterTableTest.kt
@@ -72,7 +72,7 @@
                     }
                 }
             }
-        val user = User("u1", Email("e1", "email address 1"), Email("e2", "email address 2"))
+        val user = User(1, Email("e1", "email address 1"), Email("e2", "email address 2"))
 
         fun openDb(): TestDatabase {
             return Room.databaseBuilder<TestDatabase>(context = context, name = "existingDb.db")
diff --git a/room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/test/ProvidedTypeConverterTest.kt b/room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/test/ProvidedTypeConverterTest.kt
index 3a2a91e..9e48643 100644
--- a/room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/test/ProvidedTypeConverterTest.kt
+++ b/room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/test/ProvidedTypeConverterTest.kt
@@ -62,7 +62,7 @@
                 .setDriver(AndroidSQLiteDriver())
                 .build()
         val pet: Pet = TestUtil.createPet(3)
-        pet.mName = "pet"
+        pet.name = "pet"
         db.petDao().insertOrReplace(pet)
 
         val robot = Robot(UUID.randomUUID(), UUID.randomUUID())
@@ -96,7 +96,7 @@
                     .setDriver(AndroidSQLiteDriver())
                     .build()
             val pet: Pet = TestUtil.createPet(3)
-            pet.mName = "pet"
+            pet.name = "pet"
             db.petDao().insertOrReplace(pet)
             assertWithMessage("Should have thrown an IllegalArgumentException").fail()
         } catch (throwable: Throwable) {
@@ -114,7 +114,7 @@
                     .setDriver(AndroidSQLiteDriver())
                     .build()
             val pet: Pet = TestUtil.createPet(3)
-            pet.mName = "pet"
+            pet.name = "pet"
             db.petDao().insertOrReplace(pet)
             assertWithMessage("Should have thrown an IllegalArgumentException").fail()
         } catch (throwable: Throwable) {
diff --git a/room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/test/TestDatabaseTest.kt b/room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/test/TestDatabaseTest.kt
index 3811251..010a001 100644
--- a/room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/test/TestDatabaseTest.kt
+++ b/room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/test/TestDatabaseTest.kt
@@ -16,6 +16,7 @@
 
 package androidx.room3.integration.kotlintestapp.test
 
+import android.content.Context
 import androidx.arch.core.executor.testing.CountingTaskExecutorRule
 import androidx.room3.Room
 import androidx.room3.integration.kotlintestapp.TestDatabase
@@ -30,19 +31,28 @@
 import org.junit.Before
 import org.junit.Rule
 
-abstract class TestDatabaseTest(protected val useDriver: UseDriver = UseDriver.NONE) {
+abstract class TestDatabaseTest(
+    protected val useDriver: UseDriver = UseDriver.NONE,
+    protected val useInMemoryDatabase: Boolean = true,
+) {
     @get:Rule val countingTaskExecutorRule = CountingTaskExecutorRule()
     protected lateinit var database: TestDatabase
     protected lateinit var booksDao: BooksDao
     protected lateinit var usersDao: UsersDao
 
+    private val context = ApplicationProvider.getApplicationContext<Context>()
+
     @Before
     fun setUp() {
+        if (!useInMemoryDatabase) {
+            context.deleteDatabase("test.db")
+        }
         database =
-            Room.inMemoryDatabaseBuilder(
-                    ApplicationProvider.getApplicationContext(),
-                    TestDatabase::class.java,
-                )
+            if (useInMemoryDatabase) {
+                    Room.inMemoryDatabaseBuilder<TestDatabase>(context)
+                } else {
+                    Room.databaseBuilder(context, "test.db")
+                }
                 .apply {
                     if (useDriver == UseDriver.ANDROID) {
                         setDriver(AndroidSQLiteDriver())
diff --git a/room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/test/TestUtil.kt b/room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/test/TestUtil.kt
index 8897476..4a9db65 100644
--- a/room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/test/TestUtil.kt
+++ b/room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/test/TestUtil.kt
@@ -20,15 +20,22 @@
 import androidx.lifecycle.LifecycleOwner
 import androidx.lifecycle.LiveData
 import androidx.lifecycle.Observer
+import androidx.room3.integration.kotlintestapp.vo.Address
 import androidx.room3.integration.kotlintestapp.vo.Author
 import androidx.room3.integration.kotlintestapp.vo.Book
 import androidx.room3.integration.kotlintestapp.vo.BookAuthor
+import androidx.room3.integration.kotlintestapp.vo.Coordinates
+import androidx.room3.integration.kotlintestapp.vo.Email
 import androidx.room3.integration.kotlintestapp.vo.Lang
+import androidx.room3.integration.kotlintestapp.vo.Mail
 import androidx.room3.integration.kotlintestapp.vo.Pet
 import androidx.room3.integration.kotlintestapp.vo.Publisher
+import androidx.room3.integration.kotlintestapp.vo.School
+import androidx.room3.integration.kotlintestapp.vo.User
 import java.util.Date
 import java.util.UUID
 import java.util.concurrent.FutureTask
+import kotlin.random.Random
 
 class TestUtil {
 
@@ -60,10 +67,49 @@
 
         fun createPet(id: Int): Pet {
             return Pet(
-                mPetId = id,
-                mUserId = id,
-                mName = UUID.randomUUID().toString(),
-                mAdoptionDate = Date(),
+                petId = id,
+                userId = id,
+                name = UUID.randomUUID().toString(),
+                adoptionDate = Date(),
+            )
+        }
+
+        fun createUser(id: Int): User {
+            return User(
+                uId = id,
+                email = Email(id = "e$id", address = "e$id@test.com"),
+                secondaryEmail = null,
+            )
+        }
+
+        fun createSchool(id: Int, managerId: Int): School {
+            return School(
+                id = id,
+                name = UUID.randomUUID().toString(),
+                address = createAddress(),
+                manager = createUser(managerId),
+            )
+        }
+
+        private fun createAddress(): Address {
+            return Address(
+                street = UUID.randomUUID().toString(),
+                state = UUID.randomUUID().toString().substring(0, 2),
+                postCode = Random.Default.nextInt(from = 0, until = 99999),
+                coordinates = createCoordinates(),
+            )
+        }
+
+        private fun createCoordinates(): Coordinates {
+            return Coordinates(Random.Default.nextDouble(), Random.Default.nextDouble())
+        }
+
+        fun createMail(id: Long, subject: String, body: String): Mail {
+            return Mail(
+                rowId = id,
+                subject = subject,
+                body = body,
+                datetime = System.currentTimeMillis(),
             )
         }
     }
diff --git a/room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/vo/Address.kt b/room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/vo/Address.kt
new file mode 100644
index 0000000..e30d8c8
--- /dev/null
+++ b/room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/vo/Address.kt
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2017 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 androidx.room3.integration.kotlintestapp.vo
+
+import androidx.room3.ColumnInfo
+import androidx.room3.Embedded
+
+data class Address(
+    var street: String?,
+    var state: String?,
+    @ColumnInfo(name = "post_code") var postCode: Int?,
+    @Embedded var coordinates: Coordinates?,
+)
diff --git a/room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/vo/Coordinates.kt b/room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/vo/Coordinates.kt
new file mode 100644
index 0000000..44d3138c
--- /dev/null
+++ b/room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/vo/Coordinates.kt
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2025 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 androidx.room3.integration.kotlintestapp.vo
+
+data class Coordinates(var lat: Double, var lng: Double)
diff --git a/room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/vo/FunnyNamedEntity.kt b/room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/vo/FunnyNamedEntity.kt
new file mode 100644
index 0000000..bf83ee0
--- /dev/null
+++ b/room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/vo/FunnyNamedEntity.kt
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2017 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 androidx.room3.integration.kotlintestapp.vo
+
+import androidx.room3.ColumnInfo
+import androidx.room3.Entity
+import androidx.room3.PrimaryKey
+import androidx.room3.integration.kotlintestapp.vo.FunnyNamedEntity.Companion.COLUMN_ID
+import androidx.room3.integration.kotlintestapp.vo.FunnyNamedEntity.Companion.TABLE_NAME
+
+/** An entity that was weird names */
+@Entity(tableName = TABLE_NAME)
+data class FunnyNamedEntity(
+    @PrimaryKey(autoGenerate = true) @ColumnInfo(name = COLUMN_ID) var id: Int,
+    @ColumnInfo(name = COLUMN_VALUE) var value: String?,
+) {
+    companion object {
+        const val TABLE_NAME = "funny but not so funny"
+        const val COLUMN_ID = "_this \$is id$"
+        const val COLUMN_VALUE = "unlikely-Ωşå¨ıünames"
+    }
+}
diff --git a/navigation3/navigation3-runtime/src/androidInstrumentedTest/kotlin/androidx/navigation3/runtime/TestUtil.kt b/room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/vo/GenericBaseClass.kt
similarity index 62%
copy from navigation3/navigation3-runtime/src/androidInstrumentedTest/kotlin/androidx/navigation3/runtime/TestUtil.kt
copy to room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/vo/GenericBaseClass.kt
index 69787e9..3302c08 100644
--- a/navigation3/navigation3-runtime/src/androidInstrumentedTest/kotlin/androidx/navigation3/runtime/TestUtil.kt
+++ b/room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/vo/GenericBaseClass.kt
@@ -14,13 +14,10 @@
  * limitations under the License.
  */
 
-package androidx.navigation3.runtime
+package androidx.room3.integration.kotlintestapp.vo
 
-import androidx.compose.runtime.Composable
+import androidx.room3.Embedded
 
-internal fun <K : Any> createTestNavEntryDecorator(
-    onPop: (contentKey: Any) -> Unit = {},
-    decorateEntry: @Composable (NavEntry<K>) -> Unit = { entry -> entry.Content() },
-): NavEntryDecorator<K> {
-    return NavEntryDecorator(onPop = onPop) { entry -> decorateEntry(entry) }
+open class GenericBaseClass<T> {
+    @Embedded var item: T? = null
 }
diff --git a/room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/vo/Mail.kt b/room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/vo/Mail.kt
new file mode 100644
index 0000000..6f8cb80
--- /dev/null
+++ b/room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/vo/Mail.kt
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2018 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 androidx.room3.integration.kotlintestapp.vo
+
+import androidx.room3.ColumnInfo
+import androidx.room3.Entity
+import androidx.room3.Fts4
+import androidx.room3.PrimaryKey
+
+@Entity
+@Fts4
+data class Mail(
+    @PrimaryKey @ColumnInfo(name = "rowid") val rowId: Long,
+    val subject: String,
+    val body: String,
+    val datetime: Long,
+)
diff --git a/room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/vo/Pet.kt b/room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/vo/Pet.kt
index 82a01ec..dc810a13 100644
--- a/room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/vo/Pet.kt
+++ b/room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/vo/Pet.kt
@@ -22,41 +22,34 @@
 
 @Entity
 class Pet(
-    @PrimaryKey var mPetId: Int,
-    var mUserId: Int,
-    @ColumnInfo(name = "mPetName") var mName: String?,
-    var mAdoptionDate: Date?,
+    @PrimaryKey var petId: Int,
+    var userId: Int,
+    @ColumnInfo(name = "petName") var name: String?,
+    var adoptionDate: Date?,
 ) {
     override fun equals(other: Any?): Boolean {
         if (this === other) return true
-        if (other == null || javaClass != other.javaClass) return false
-        val pet = other as Pet
-        if (mPetId != pet.mPetId) return false
-        if (mUserId != pet.mUserId) return false
-        if (if (mName != null) mName != pet.mName else pet.mName != null) return false
-        return if (mAdoptionDate != null) mAdoptionDate == pet.mAdoptionDate
-        else pet.mAdoptionDate == null
+        if (javaClass != other?.javaClass) return false
+
+        other as Pet
+
+        if (petId != other.petId) return false
+        if (userId != other.userId) return false
+        if (name != other.name) return false
+        if (adoptionDate != other.adoptionDate) return false
+
+        return true
     }
 
     override fun hashCode(): Int {
-        var result = mPetId
-        result = 31 * result + mUserId
-        result = 31 * result + if (mName != null) mName.hashCode() else 0
-        result = 31 * result + if (mAdoptionDate != null) mAdoptionDate.hashCode() else 0
+        var result = petId
+        result = 31 * result + userId
+        result = 31 * result + (name?.hashCode() ?: 0)
+        result = 31 * result + (adoptionDate?.hashCode() ?: 0)
         return result
     }
 
     override fun toString(): String {
-        return ("Pet{" +
-            "mPetId=" +
-            mPetId +
-            ", mUserId=" +
-            mUserId +
-            ", mName='" +
-            mName +
-            '\'' +
-            ", mAdoptionDate=" +
-            mAdoptionDate +
-            '}')
+        return "Pet(petId=$petId, userId=$userId, name=$name, adoptionDate=$adoptionDate)"
     }
 }
diff --git a/room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/vo/PetAndOwner.kt b/room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/vo/PetAndOwner.kt
index abc9ba7..09820dd 100644
--- a/room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/vo/PetAndOwner.kt
+++ b/room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/vo/PetAndOwner.kt
@@ -19,6 +19,6 @@
 import androidx.room3.Relation
 
 class PetAndOwner(
-    @field:Embedded val mPet: Pet,
-    @field:Relation(parentColumn = "mUserId", entityColumn = "mId") val mUser: PetUser,
+    @field:Embedded val pet: Pet,
+    @field:Relation(parentColumn = "userId", entityColumn = "id") val user: PetUser,
 )
diff --git a/room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/vo/PetCouple.kt b/room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/vo/PetCouple.kt
new file mode 100644
index 0000000..af7e553
--- /dev/null
+++ b/room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/vo/PetCouple.kt
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2017 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 androidx.room3.integration.kotlintestapp.vo
+
+import androidx.room3.Embedded
+import androidx.room3.Entity
+import androidx.room3.PrimaryKey
+import androidx.room3.RoomWarnings
+
+@Entity
+@Suppress(RoomWarnings.PRIMARY_KEY_FROM_EMBEDDED_IS_DROPPED)
+data class PetCouple(
+    @PrimaryKey val id: String,
+    @Embedded(prefix = "male_") val male: Pet,
+    @Embedded(prefix = "female_") val female: Pet?,
+)
diff --git a/room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/vo/PetUser.kt b/room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/vo/PetUser.kt
index 9b49332..c1f9c80 100644
--- a/room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/vo/PetUser.kt
+++ b/room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/vo/PetUser.kt
@@ -20,85 +20,57 @@
 import androidx.room3.PrimaryKey
 import androidx.room3.TypeConverters
 import androidx.room3.integration.kotlintestapp.TestDatabase
-import java.lang.Float.floatToIntBits
 import java.util.Date
 
 @Entity
 @TypeConverters(TestDatabase.Converters::class)
 class PetUser {
-    @PrimaryKey var mId = 0
-    var mName: String? = null
-    var mLastName: String? = null
-    var mAge = 0
-    var mAdmin = false
-    var mWeight = 0f
-    var mBirthday: Date? = null
+    @PrimaryKey var id = 0
+    var name: String? = null
+    var lastName: String? = null
+    var age = 0
+    var admin = false
+    var weight = 0f
+    var birthday: Date? = null
 
-    @ColumnInfo(name = "custommm", collate = ColumnInfo.NOCASE) var mCustomField: String? = null
+    @ColumnInfo(name = "custommm", collate = ColumnInfo.NOCASE) var customField: String? = null
 
     // bit flags
-    lateinit var mWorkDays: Set<Day>
+    lateinit var workDays: Set<Day>
 
     override fun equals(other: Any?): Boolean {
         if (this === other) return true
-        if (other == null || javaClass != other.javaClass) return false
-        val user = other as PetUser
-        if (mId != user.mId) return false
-        if (mAge != user.mAge) return false
-        if (mAdmin != user.mAdmin) return false
-        if (user.mWeight.compareTo(mWeight) != 0) return false
-        if (if (mName != null) mName != user.mName else user.mName != null) return false
-        if (if (mLastName != null) mLastName != user.mLastName else user.mLastName != null) {
-            return false
-        }
-        if (if (mBirthday != null) mBirthday != user.mBirthday else user.mBirthday != null) {
-            return false
-        }
-        if (
-            if (mCustomField != null) mCustomField != user.mCustomField
-            else user.mCustomField != null
-        ) {
-            return false
-        }
-        return mWorkDays == user.mWorkDays
+        if (javaClass != other?.javaClass) return false
+
+        other as PetUser
+
+        if (id != other.id) return false
+        if (age != other.age) return false
+        if (admin != other.admin) return false
+        if (weight != other.weight) return false
+        if (name != other.name) return false
+        if (lastName != other.lastName) return false
+        if (birthday != other.birthday) return false
+        if (customField != other.customField) return false
+        if (workDays != other.workDays) return false
+
+        return true
     }
 
     override fun hashCode(): Int {
-        var result = mId
-        result = 31 * result + if (mName != null) mName.hashCode() else 0
-        result = 31 * result + if (mLastName != null) mLastName.hashCode() else 0
-        result = 31 * result + mAge
-        result = 31 * result + if (mAdmin) 1 else 0
-        result = 31 * result + if (mWeight != +0.0f) floatToIntBits(mWeight) else 0
-        result = 31 * result + if (mBirthday != null) mBirthday.hashCode() else 0
-        result = 31 * result + if (mCustomField != null) mCustomField.hashCode() else 0
-        result = 31 * result + mWorkDays.hashCode()
+        var result = id
+        result = 31 * result + age
+        result = 31 * result + admin.hashCode()
+        result = 31 * result + weight.hashCode()
+        result = 31 * result + (name?.hashCode() ?: 0)
+        result = 31 * result + (lastName?.hashCode() ?: 0)
+        result = 31 * result + (birthday?.hashCode() ?: 0)
+        result = 31 * result + (customField?.hashCode() ?: 0)
+        result = 31 * result + workDays.hashCode()
         return result
     }
 
     override fun toString(): String {
-        return ("User{" +
-            "mId=" +
-            mId +
-            ", mName='" +
-            mName +
-            '\'' +
-            ", mLastName='" +
-            mLastName +
-            '\'' +
-            ", mAge=" +
-            mAge +
-            ", mAdmin=" +
-            mAdmin +
-            ", mWeight=" +
-            mWeight +
-            ", mBirthday=" +
-            mBirthday +
-            ", mCustomField='" +
-            mCustomField +
-            '\'' +
-            ", mWorkDays=" +
-            mWorkDays +
-            '}')
+        return "PetUser(id=$id, name=$name, lastName=$lastName, age=$age, admin=$admin, weight=$weight, birthday=$birthday, customField=$customField, workDays=$workDays)"
     }
 }
diff --git a/room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/vo/PetWithToyIds.kt b/room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/vo/PetWithToyIds.kt
index 214a9a3..ace9f02 100644
--- a/room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/vo/PetWithToyIds.kt
+++ b/room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/vo/PetWithToyIds.kt
@@ -20,42 +20,42 @@
 import androidx.room3.Relation
 
 class PetWithToyIds {
-    @Embedded val mPet: Pet?
+    @Embedded val pet: Pet?
 
     @Relation(
-        parentColumn = "mPetId",
-        entityColumn = "mPetId",
-        projection = ["mId"],
+        parentColumn = "petId",
+        entityColumn = "petId",
+        projection = ["id"],
         entity = Toy::class,
     )
-    var mToyIds: List<Int>? = null
+    var toyIds: List<Int>? = null
 
     // for the relation
     constructor(pet: Pet?) {
-        this.mPet = pet
+        this.pet = pet
     }
 
     @Ignore
     constructor(pet: Pet?, toyIds: List<Int>?) {
-        this.mPet = pet
-        this.mToyIds = toyIds
+        this.pet = pet
+        this.toyIds = toyIds
     }
 
     override fun equals(other: Any?): Boolean {
         if (this === other) return true
         if (other == null || javaClass != other.javaClass) return false
         val that = other as PetWithToyIds
-        if (if (mPet != null) !mPet.equals(that.mPet) else that.mPet != null) return false
-        return if (mToyIds != null) mToyIds == that.mToyIds else that.mToyIds == null
+        if (if (pet != null) pet != that.pet else that.pet != null) return false
+        return if (toyIds != null) toyIds == that.toyIds else that.toyIds == null
     }
 
     override fun hashCode(): Int {
-        var result = mPet?.hashCode() ?: 0
-        result = 31 * result + if (mToyIds != null) mToyIds.hashCode() else 0
+        var result = pet?.hashCode() ?: 0
+        result = 31 * result + (toyIds?.hashCode() ?: 0)
         return result
     }
 
     override fun toString(): String {
-        return ("PetWithToyIds{" + "pet=" + mPet + ", toyIds=" + mToyIds + '}')
+        return ("PetWithToyIds{pet=$pet, toyIds=$toyIds}")
     }
 }
diff --git a/room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/vo/PetWithUser.kt b/room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/vo/PetWithUser.kt
index e2829ee..d0b5278 100644
--- a/room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/vo/PetWithUser.kt
+++ b/room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/vo/PetWithUser.kt
@@ -18,5 +18,5 @@
 import androidx.room3.DatabaseView
 import androidx.room3.Embedded
 
-@DatabaseView("SELECT Pet.*, PetUser.* FROM Pet INNER JOIN PetUser ON Pet.mUserId = PetUser.mId")
-data class PetWithUser(@Embedded var mPet: Pet, @Embedded var mUser: PetUser)
+@DatabaseView("SELECT Pet.*, PetUser.* FROM Pet INNER JOIN PetUser ON Pet.userId = PetUser.id")
+data class PetWithUser(@Embedded var pet: Pet, @Embedded var user: PetUser)
diff --git a/room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/vo/School.kt b/room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/vo/School.kt
new file mode 100644
index 0000000..29eede5
--- /dev/null
+++ b/room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/vo/School.kt
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2017 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 androidx.room3.integration.kotlintestapp.vo
+
+import androidx.room3.Embedded
+import androidx.room3.Entity
+import androidx.room3.PrimaryKey
+import androidx.room3.RoomWarnings
+
+@Entity
+open class School(
+    @PrimaryKey var id: Int = 0,
+    var name: String? = null,
+    @Embedded(prefix = "address_") var address: Address? = null,
+    @Suppress(RoomWarnings.PRIMARY_KEY_FROM_EMBEDDED_IS_DROPPED)
+    @Embedded(prefix = "manager_")
+    var manager: User? = null,
+) {
+    override fun equals(other: Any?): Boolean {
+        if (this === other) return true
+        if (other !is School) return false
+
+        if (id != other.id) return false
+        if (name != other.name) return false
+        if (address != other.address) return false
+        if (manager != other.manager) return false
+
+        return true
+    }
+
+    override fun hashCode(): Int {
+        var result = id
+        result = 31 * result + (name?.hashCode() ?: 0)
+        result = 31 * result + (address?.hashCode() ?: 0)
+        result = 31 * result + (manager?.hashCode() ?: 0)
+        return result
+    }
+}
diff --git a/room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/vo/SchoolRef.kt b/room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/vo/SchoolRef.kt
new file mode 100644
index 0000000..bc226e2b
--- /dev/null
+++ b/room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/vo/SchoolRef.kt
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2017 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 liturgical 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 androidx.room3.integration.kotlintestapp.vo
+
+class SchoolRef : School()
diff --git a/room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/vo/SongDescription.kt b/room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/vo/SongDescription.kt
new file mode 100644
index 0000000..c75d123
--- /dev/null
+++ b/room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/vo/SongDescription.kt
@@ -0,0 +1,21 @@
+/*
+ * Copyright 2018 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 androidx.room3.integration.kotlintestapp.vo
+
+import androidx.room3.Entity
+import androidx.room3.Fts4
+
+@Entity @Fts4(contentEntity = Song::class) data class SongDescription(val mTitle: String?)
diff --git a/room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/vo/Toy.kt b/room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/vo/Toy.kt
index 4d04803..e59264a 100644
--- a/room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/vo/Toy.kt
+++ b/room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/vo/Toy.kt
@@ -22,31 +22,15 @@
 
 /** The toys of a pet. */
 @Entity(
-    indices = [Index(value = ["mName"], unique = true), Index(value = ["mPetId"])],
+    indices = [Index(value = ["name"], unique = true), Index(value = ["petId"])],
     foreignKeys =
         [
             ForeignKey(
                 entity = Pet::class,
-                parentColumns = ["mPetId"],
-                childColumns = ["mPetId"],
+                parentColumns = ["petId"],
+                childColumns = ["petId"],
                 deferred = true,
             )
         ],
 )
-data class Toy(@PrimaryKey(autoGenerate = true) val mId: Int, var mName: String?, var mPetId: Int) {
-    override fun equals(other: Any?): Boolean {
-        if (this === other) return true
-        if (other == null || javaClass != other.javaClass) return false
-        val toy = other as Toy
-        if (mId != toy.mId) return false
-        if (mPetId != toy.mPetId) return false
-        return if (mName != null) mName == toy.mName else toy.mName == null
-    }
-
-    override fun hashCode(): Int {
-        var result = mId
-        result = 31 * result + if (mName != null) mName.hashCode() else 0
-        result = 31 * result + mPetId
-        return result
-    }
-}
+data class Toy(@PrimaryKey(autoGenerate = true) val id: Int, var name: String?, var petId: Int)
diff --git a/room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/vo/User.kt b/room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/vo/User.kt
index 082fb11..2150eba 100644
--- a/room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/vo/User.kt
+++ b/room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/vo/User.kt
@@ -22,7 +22,7 @@
 
 @Entity
 data class User(
-    @PrimaryKey var userId: String,
-    @Embedded(prefix = "email_") var email: Email,
+    @PrimaryKey var uId: Int,
+    @Embedded(prefix = "email_") var email: Email?,
     @Embedded(prefix = "secondary_email_") var secondaryEmail: Email?,
 )
diff --git a/navigation3/navigation3-runtime/src/androidInstrumentedTest/kotlin/androidx/navigation3/runtime/TestUtil.kt b/room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/vo/UserAndGenericPet.kt
similarity index 62%
rename from navigation3/navigation3-runtime/src/androidInstrumentedTest/kotlin/androidx/navigation3/runtime/TestUtil.kt
rename to room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/vo/UserAndGenericPet.kt
index 69787e9..0330463 100644
--- a/navigation3/navigation3-runtime/src/androidInstrumentedTest/kotlin/androidx/navigation3/runtime/TestUtil.kt
+++ b/room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/vo/UserAndGenericPet.kt
@@ -14,13 +14,10 @@
  * limitations under the License.
  */
 
-package androidx.navigation3.runtime
+package androidx.room3.integration.kotlintestapp.vo
 
-import androidx.compose.runtime.Composable
+import androidx.room3.Embedded
 
-internal fun <K : Any> createTestNavEntryDecorator(
-    onPop: (contentKey: Any) -> Unit = {},
-    decorateEntry: @Composable (NavEntry<K>) -> Unit = { entry -> entry.Content() },
-): NavEntryDecorator<K> {
-    return NavEntryDecorator(onPop = onPop) { entry -> decorateEntry(entry) }
+class UserAndGenericPet : GenericBaseClass<Pet>() {
+    @Embedded var user: User? = null
 }
diff --git a/navigation3/navigation3-runtime/src/androidInstrumentedTest/kotlin/androidx/navigation3/runtime/TestUtil.kt b/room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/vo/UserAndPet.kt
similarity index 62%
copy from navigation3/navigation3-runtime/src/androidInstrumentedTest/kotlin/androidx/navigation3/runtime/TestUtil.kt
copy to room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/vo/UserAndPet.kt
index 69787e9..54d44fe 100644
--- a/navigation3/navigation3-runtime/src/androidInstrumentedTest/kotlin/androidx/navigation3/runtime/TestUtil.kt
+++ b/room3/integration-tests/kotlintestapp/src/androidTest/java/androidx/room3/integration/kotlintestapp/vo/UserAndPet.kt
@@ -14,13 +14,8 @@
  * limitations under the License.
  */
 
-package androidx.navigation3.runtime
+package androidx.room3.integration.kotlintestapp.vo
 
-import androidx.compose.runtime.Composable
+import androidx.room3.Embedded
 
-internal fun <K : Any> createTestNavEntryDecorator(
-    onPop: (contentKey: Any) -> Unit = {},
-    decorateEntry: @Composable (NavEntry<K>) -> Unit = { entry -> entry.Content() },
-): NavEntryDecorator<K> {
-    return NavEntryDecorator(onPop = onPop) { entry -> decorateEntry(entry) }
-}
+data class UserAndPet(@Embedded val user: User?, @Embedded val pet: Pet?)
diff --git a/room3/integration-tests/multiplatformtestapp/build.gradle b/room3/integration-tests/multiplatformtestapp/build.gradle
index b5ce401..4078da8f 100644
--- a/room3/integration-tests/multiplatformtestapp/build.gradle
+++ b/room3/integration-tests/multiplatformtestapp/build.gradle
@@ -119,7 +119,7 @@
 dependencies {
     def roomCompilerDependency = project(":room3:room3-compiler")
     add("kspAndroidInstrumentedTest", roomCompilerDependency) // Android instrumentation test
-    add("kspAndroidUnitTest", roomCompilerDependency) // Android unit test
+    add("kspAndroidHostTest", roomCompilerDependency) // Android unit test
     add("kspJvmTest", roomCompilerDependency)
     add("kspLinuxX64Test", roomCompilerDependency)
     if (KmpPlatformsKt.enableMac(project)) {
diff --git a/room3/integration-tests/testapp/src/androidTest/java/androidx/room3/integration/testapp/TestDatabase.java b/room3/integration-tests/testapp/src/androidTest/java/androidx/room3/integration/testapp/TestDatabase.java
index a294a70..9bfe37a 100644
--- a/room3/integration-tests/testapp/src/androidTest/java/androidx/room3/integration/testapp/TestDatabase.java
+++ b/room3/integration-tests/testapp/src/androidTest/java/androidx/room3/integration/testapp/TestDatabase.java
@@ -21,7 +21,6 @@
 import androidx.room3.TypeConverter;
 import androidx.room3.TypeConverters;
 import androidx.room3.integration.testapp.dao.BlobEntityDao;
-import androidx.room3.integration.testapp.dao.FunnyNamedDao;
 import androidx.room3.integration.testapp.dao.LibraryItemDao;
 import androidx.room3.integration.testapp.dao.PagingSourceOnlyUserDao;
 import androidx.room3.integration.testapp.dao.PetCoupleDao;
@@ -39,7 +38,6 @@
 import androidx.room3.integration.testapp.vo.BlobEntity;
 import androidx.room3.integration.testapp.vo.Day;
 import androidx.room3.integration.testapp.vo.FriendsJunction;
-import androidx.room3.integration.testapp.vo.FunnyNamedEntity;
 import androidx.room3.integration.testapp.vo.Hivemind;
 import androidx.room3.integration.testapp.vo.House;
 import androidx.room3.integration.testapp.vo.Pet;
@@ -59,7 +57,7 @@
 import java.util.UUID;
 
 @Database(entities = {User.class, Pet.class, School.class, PetCouple.class, Toy.class,
-        BlobEntity.class, Product.class, FunnyNamedEntity.class, House.class,
+        BlobEntity.class, Product.class, House.class,
         FriendsJunction.class, Hivemind.class, Robot.class, RoomLibraryPojo.class},
         views = {PetWithUser.class},
         version = 1, exportSchema = false)
@@ -76,7 +74,6 @@
     public abstract ProductDao getProductDao();
     public abstract SpecificDogDao getSpecificDogDao();
     public abstract WithClauseDao getWithClauseDao();
-    public abstract FunnyNamedDao getFunnyNamedDao();
     public abstract RawDao getRawDao();
     public abstract UserHouseDao getUserHouseDao();
     public abstract RobotsDao getRobotsDao();
diff --git a/room3/integration-tests/testapp/src/androidTest/java/androidx/room3/integration/testapp/dao/FunnyNamedDao.java b/room3/integration-tests/testapp/src/androidTest/java/androidx/room3/integration/testapp/dao/FunnyNamedDao.java
deleted file mode 100644
index dd8b2f4..0000000
--- a/room3/integration-tests/testapp/src/androidTest/java/androidx/room3/integration/testapp/dao/FunnyNamedDao.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright (C) 2017 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 androidx.room3.integration.testapp.dao;
-
-import static androidx.room3.integration.testapp.vo.FunnyNamedEntity.COLUMN_ID;
-import static androidx.room3.integration.testapp.vo.FunnyNamedEntity.TABLE_NAME;
-
-import androidx.lifecycle.LiveData;
-import androidx.room3.Dao;
-import androidx.room3.Delete;
-import androidx.room3.Insert;
-import androidx.room3.Query;
-import androidx.room3.Update;
-import androidx.room3.integration.testapp.vo.FunnyNamedEntity;
-
-import java.util.List;
-
-@Dao
-public interface FunnyNamedDao {
-    String SELECT_ONE = "select * from \"" +  TABLE_NAME + "\" WHERE \"" + COLUMN_ID + "\" = :id";
-    @Insert
-    void insert(FunnyNamedEntity... entities);
-    @Delete
-    void delete(FunnyNamedEntity... entities);
-    @Update
-    void update(FunnyNamedEntity... entities);
-
-    @Query("select * from \"" +  TABLE_NAME + "\" WHERE \"" + COLUMN_ID + "\" IN (:ids)")
-    List<FunnyNamedEntity> loadAll(int... ids);
-
-    @Query(SELECT_ONE)
-    LiveData<FunnyNamedEntity> observableOne(int id);
-
-    @Query(SELECT_ONE)
-    FunnyNamedEntity load(int id);
-}
diff --git a/room3/integration-tests/testapp/src/androidTest/java/androidx/room3/integration/testapp/test/AutoClosingRoomOpenHelperTest.java b/room3/integration-tests/testapp/src/androidTest/java/androidx/room3/integration/testapp/test/AutoClosingRoomOpenHelperTest.java
index e1a6bf7..bfe32fe 100644
--- a/room3/integration-tests/testapp/src/androidTest/java/androidx/room3/integration/testapp/test/AutoClosingRoomOpenHelperTest.java
+++ b/room3/integration-tests/testapp/src/androidTest/java/androidx/room3/integration/testapp/test/AutoClosingRoomOpenHelperTest.java
@@ -57,8 +57,7 @@
     public CountingTaskExecutorRule mExecutorRule = new CountingTaskExecutorRule();
     private UserDao mUserDao;
     private TestDatabase mDb;
-    private final DatabaseCallbackTest.TestDatabaseCallback mCallback =
-            new DatabaseCallbackTest.TestDatabaseCallback();
+    private final TestDatabaseCallback mCallback = new TestDatabaseCallback();
 
     @Before
     public void createDb() throws TimeoutException, InterruptedException {
@@ -352,4 +351,26 @@
             mInvalidationCallback.run();
         }
     }
+
+    public static class TestDatabaseCallback extends RoomDatabase.Callback {
+
+        boolean mCreated;
+        boolean mOpened;
+        boolean mDestructivelyMigrated;
+
+        @Override
+        public void onCreate(@NonNull SupportSQLiteDatabase db) {
+            mCreated = true;
+        }
+
+        @Override
+        public void onOpen(@NonNull SupportSQLiteDatabase db) {
+            mOpened = true;
+        }
+
+        @Override
+        public void onDestructiveMigration(@NonNull SupportSQLiteDatabase db) {
+            mDestructivelyMigrated = true;
+        }
+    }
 }
diff --git a/room3/integration-tests/testapp/src/androidTest/java/androidx/room3/integration/testapp/test/ClearAllTablesTest.java b/room3/integration-tests/testapp/src/androidTest/java/androidx/room3/integration/testapp/test/ClearAllTablesTest.java
deleted file mode 100644
index 37b13ae..0000000
--- a/room3/integration-tests/testapp/src/androidTest/java/androidx/room3/integration/testapp/test/ClearAllTablesTest.java
+++ /dev/null
@@ -1,248 +0,0 @@
-/*
- * Copyright 2018 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 androidx.room3.integration.testapp.test;
-
-import static org.hamcrest.CoreMatchers.containsString;
-import static org.hamcrest.CoreMatchers.equalTo;
-import static org.hamcrest.CoreMatchers.hasItem;
-import static org.hamcrest.CoreMatchers.is;
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.hamcrest.collection.IsCollectionWithSize.hasSize;
-import static org.junit.Assert.fail;
-
-import android.content.Context;
-import android.database.Cursor;
-
-import androidx.room3.Dao;
-import androidx.room3.Database;
-import androidx.room3.Entity;
-import androidx.room3.ForeignKey;
-import androidx.room3.Index;
-import androidx.room3.Insert;
-import androidx.room3.InvalidationTracker;
-import androidx.room3.PrimaryKey;
-import androidx.room3.Query;
-import androidx.room3.Room;
-import androidx.room3.RoomDatabase;
-import androidx.test.core.app.ApplicationProvider;
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.test.filters.MediumTest;
-import androidx.test.filters.SmallTest;
-import androidx.test.platform.app.InstrumentationRegistry;
-
-import org.jspecify.annotations.NonNull;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.nio.charset.Charset;
-import java.util.Set;
-import java.util.UUID;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-
-@SuppressWarnings("WeakerAccess")
-@RunWith(AndroidJUnit4.class)
-public class ClearAllTablesTest {
-
-    @Database(version = 1, entities = {Parent.class, Child.class}, exportSchema = false)
-    public abstract static class ClearAllTablesDatabase extends RoomDatabase {
-        abstract ClearAllTablesDao dao();
-    }
-
-    @Entity
-    public static class Parent {
-        @PrimaryKey
-        public long id;
-        public String name;
-
-        public Parent(long id, String name) {
-            this.id = id;
-            this.name = name;
-        }
-    }
-
-    @Entity(foreignKeys = {
-            @ForeignKey(entity = Parent.class, parentColumns = "id", childColumns = "parentId")},
-            indices = {@Index("parentId")})
-    public static class Child {
-        @PrimaryKey
-        public long id;
-        public String name;
-        public long parentId;
-
-        public Child(long id, String name, long parentId) {
-            this.id = id;
-            this.name = name;
-            this.parentId = parentId;
-        }
-    }
-
-    @Dao
-    public interface ClearAllTablesDao {
-        @Insert
-        void insertParent(Parent parent);
-
-        @Insert
-        void insertChild(Child child);
-
-        @Query("SELECT COUNT(*) FROM Parent")
-        int countParent();
-
-        @Query("SELECT COUNT(*) FROM Child")
-        int countChild();
-    }
-
-    private ClearAllTablesDatabase mDatabase;
-    private ClearAllTablesDao mDao;
-
-    @Before
-    public void setUp() {
-        final Context context = ApplicationProvider.getApplicationContext();
-        mDatabase = Room.inMemoryDatabaseBuilder(context, ClearAllTablesDatabase.class).build();
-        mDao = mDatabase.dao();
-    }
-
-    @After
-    public void closeDatabase() {
-        mDatabase.close();
-    }
-
-    @Test
-    @SmallTest
-    public void simple() {
-        mDao.insertParent(new Parent(1, "A"));
-        assertThat(mDao.countParent(), is(1));
-        mDatabase.clearAllTables();
-        assertThat(mDao.countParent(), is(0));
-    }
-
-    @Test
-    @SmallTest
-    public void inTransaction() {
-        mDao.insertParent(new Parent(1, "A"));
-        assertThat(mDao.countParent(), is(1));
-        // Running clearAllTables in a transaction is not recommended, but we should not crash.
-        mDatabase.runInTransaction(() -> mDatabase.clearAllTables());
-        assertThat(mDao.countParent(), is(0));
-    }
-
-    @Test
-    @SmallTest
-    public void inMainThread() {
-        InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
-            try {
-                mDatabase.clearAllTables();
-                fail("Was expecting an exception");
-            } catch (IllegalStateException e) {
-                assertThat(e.getMessage(), containsString("main thread"));
-            }
-        });
-    }
-
-    @Test
-    @SmallTest
-    public void foreignKey() {
-        mDao.insertParent(new Parent(1, "A"));
-        mDao.insertChild(new Child(1, "a", 1));
-        assertThat(mDao.countParent(), is(1));
-        assertThat(mDao.countChild(), is(1));
-        mDatabase.clearAllTables();
-        assertThat(mDao.countParent(), is(0));
-        assertThat(mDao.countChild(), is(0));
-    }
-
-    @Test
-    @SmallTest
-    public void observer() throws InterruptedException {
-        mDao.insertParent(new Parent(1, "A"));
-        assertThat(mDao.countParent(), is(1));
-        final CountDownLatch latch = new CountDownLatch(1);
-        mDatabase.getInvalidationTracker().addObserver(new InvalidationTracker.Observer("Parent") {
-            @Override
-            public void onInvalidated(@NonNull Set<String> tables) {
-                assertThat(tables, hasSize(1));
-                assertThat(tables, hasItem("Parent"));
-                assertThat(mDao.countParent(), is(0));
-                latch.countDown();
-            }
-        });
-        mDatabase.clearAllTables();
-        assertThat(latch.await(3000, TimeUnit.MILLISECONDS), is(true));
-    }
-
-    @Test
-    @MediumTest
-    public void clearsDataFromDiskTruncate() throws IOException {
-        clearsDataFromDisk(RoomDatabase.JournalMode.TRUNCATE);
-    }
-
-    @Test
-    @MediumTest
-    public void clearsDataFromDiskWal() throws IOException {
-        clearsDataFromDisk(RoomDatabase.JournalMode.WRITE_AHEAD_LOGGING);
-    }
-
-    private void clearsDataFromDisk(RoomDatabase.JournalMode journalMode) throws IOException {
-        final Context context = ApplicationProvider.getApplicationContext();
-        final String dbName = "clear.db";
-        context.deleteDatabase(dbName);
-        ClearAllTablesDatabase db;
-        db = Room.databaseBuilder(context, ClearAllTablesDatabase.class, dbName)
-                .setJournalMode(journalMode).build();
-        final File file = context.getDatabasePath(dbName);
-        final String uuid = UUID.randomUUID().toString();
-        db.dao().insertParent(new Parent(1, uuid));
-        assertThat(queryEncoding(db), is(equalTo("UTF-8")));
-        db.close();
-        assertThat(fileContainsString(file, uuid), is(true));
-        db = Room.databaseBuilder(context, ClearAllTablesDatabase.class, dbName)
-                .setJournalMode(journalMode).build();
-        db.clearAllTables();
-        db.close();
-        assertThat(fileContainsString(file, uuid), is(false));
-    }
-
-    private String queryEncoding(RoomDatabase db) {
-        Cursor c = null;
-        try {
-            c = db.query("PRAGMA encoding", null);
-            c.moveToFirst();
-            return c.getString(0);
-        } finally {
-            if (c != null) {
-                c.close();
-            }
-        }
-    }
-
-    private boolean fileContainsString(File file, String s) throws IOException {
-        final byte[] content = new byte[(int) file.length()];
-        final FileInputStream stream = new FileInputStream(file);
-        //noinspection TryFinallyCanBeTryWithResources
-        try {
-            assertThat(stream.read(content), is(content.length));
-            return new String(content, Charset.forName("UTF-8")).indexOf(s) > 0;
-        } finally {
-            stream.close();
-        }
-    }
-}
diff --git a/room3/integration-tests/testapp/src/androidTest/java/androidx/room3/integration/testapp/test/CollationTest.java b/room3/integration-tests/testapp/src/androidTest/java/androidx/room3/integration/testapp/test/CollationTest.java
deleted file mode 100644
index e0531f9..0000000
--- a/room3/integration-tests/testapp/src/androidTest/java/androidx/room3/integration/testapp/test/CollationTest.java
+++ /dev/null
@@ -1,187 +0,0 @@
-/*
- * Copyright 2018 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 androidx.room3.integration.testapp.test;
-
-import static org.hamcrest.MatcherAssert.assertThat;
-
-import androidx.room3.ColumnInfo;
-import androidx.room3.Dao;
-import androidx.room3.Database;
-import androidx.room3.Insert;
-import androidx.room3.PrimaryKey;
-import androidx.room3.Query;
-import androidx.room3.Room;
-import androidx.room3.RoomDatabase;
-import androidx.test.core.app.ApplicationProvider;
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.test.filters.SmallTest;
-
-import org.hamcrest.CoreMatchers;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.util.Arrays;
-import java.util.List;
-import java.util.Locale;
-
-@SmallTest
-@RunWith(AndroidJUnit4.class)
-public class CollationTest {
-    private CollateDb mDb;
-    private CollateDao mDao;
-    private Locale mDefaultLocale;
-    private final CollateEntity mItem1 = new CollateEntity(1, "abı");
-    private final CollateEntity mItem2 = new CollateEntity(2, "abi");
-    private final CollateEntity mItem3 = new CollateEntity(3, "abj");
-    private final CollateEntity mItem4 = new CollateEntity(4, "abç");
-
-    @Before
-    public void init() {
-        mDefaultLocale = Locale.getDefault();
-    }
-
-    private void initDao(Locale systemLocale) {
-        Locale.setDefault(systemLocale);
-        mDb = Room.inMemoryDatabaseBuilder(ApplicationProvider.getApplicationContext(),
-                CollateDb.class).build();
-        mDao = mDb.dao();
-        mDao.insert(mItem1);
-        mDao.insert(mItem2);
-        mDao.insert(mItem3);
-        mDao.insert(mItem4);
-    }
-
-    @After
-    public void closeDb() {
-        mDb.close();
-        Locale.setDefault(mDefaultLocale);
-    }
-
-    @Test
-    public void localized() {
-        initDao(new Locale("tr", "TR"));
-        List<CollateEntity> result = mDao.sortedByLocalized();
-        assertThat(result, CoreMatchers.is(Arrays.asList(
-                mItem4, mItem1, mItem2, mItem3
-        )));
-    }
-
-    @Test
-    public void localized_asUnicode() {
-        initDao(Locale.getDefault());
-        List<CollateEntity> result = mDao.sortedByLocalizedAsUnicode();
-        assertThat(result, CoreMatchers.is(Arrays.asList(
-                mItem4, mItem2, mItem1, mItem3
-        )));
-    }
-
-    @Test
-    public void unicode_asLocalized() {
-        initDao(new Locale("tr", "TR"));
-        List<CollateEntity> result = mDao.sortedByUnicodeAsLocalized();
-        assertThat(result, CoreMatchers.is(Arrays.asList(
-                mItem4, mItem1, mItem2, mItem3
-        )));
-    }
-
-    @Test
-    public void unicode() {
-        initDao(Locale.getDefault());
-        List<CollateEntity> result = mDao.sortedByUnicode();
-        assertThat(result, CoreMatchers.is(Arrays.asList(
-                mItem4, mItem2, mItem1, mItem3
-        )));
-    }
-
-    @SuppressWarnings("WeakerAccess")
-    @androidx.room3.Entity
-    static class CollateEntity {
-        @PrimaryKey
-        public final int id;
-        @ColumnInfo(collate = ColumnInfo.LOCALIZED)
-        public final String localizedName;
-        @ColumnInfo(collate = ColumnInfo.UNICODE)
-        public final String unicodeName;
-
-        CollateEntity(int id, String name) {
-            this.id = id;
-            this.localizedName = name;
-            this.unicodeName = name;
-        }
-
-        CollateEntity(int id, String localizedName, String unicodeName) {
-            this.id = id;
-            this.localizedName = localizedName;
-            this.unicodeName = unicodeName;
-        }
-
-        @SuppressWarnings("SimplifiableIfStatement")
-        @Override
-        public boolean equals(Object o) {
-            if (this == o) return true;
-            if (o == null || getClass() != o.getClass()) return false;
-
-            CollateEntity that = (CollateEntity) o;
-
-            if (id != that.id) return false;
-            if (!localizedName.equals(that.localizedName)) return false;
-            return unicodeName.equals(that.unicodeName);
-        }
-
-        @Override
-        public int hashCode() {
-            int result = id;
-            result = 31 * result + localizedName.hashCode();
-            result = 31 * result + unicodeName.hashCode();
-            return result;
-        }
-
-        @Override
-        public String toString() {
-            return "CollateEntity{"
-                    + "id=" + id
-                    + ", localizedName='" + localizedName + '\''
-                    + ", unicodeName='" + unicodeName + '\''
-                    + '}';
-        }
-    }
-
-    @Dao
-    interface CollateDao {
-        @Query("SELECT * FROM CollateEntity ORDER BY localizedName ASC")
-        List<CollateEntity> sortedByLocalized();
-
-        @Query("SELECT * FROM CollateEntity ORDER BY localizedName COLLATE UNICODE ASC")
-        List<CollateEntity> sortedByLocalizedAsUnicode();
-
-        @Query("SELECT * FROM CollateEntity ORDER BY unicodeName ASC")
-        List<CollateEntity> sortedByUnicode();
-
-        @Query("SELECT * FROM CollateEntity ORDER BY unicodeName COLLATE LOCALIZED ASC")
-        List<CollateEntity> sortedByUnicodeAsLocalized();
-
-        @Insert
-        void insert(CollateEntity... entities);
-    }
-
-    @Database(entities = CollateEntity.class, version = 1, exportSchema = false)
-    abstract static class CollateDb extends RoomDatabase {
-        abstract CollateDao dao();
-    }
-}
diff --git a/room3/integration-tests/testapp/src/androidTest/java/androidx/room3/integration/testapp/test/ConstructorTest.java b/room3/integration-tests/testapp/src/androidTest/java/androidx/room3/integration/testapp/test/ConstructorTest.java
deleted file mode 100644
index 7d622f6..0000000
--- a/room3/integration-tests/testapp/src/androidTest/java/androidx/room3/integration/testapp/test/ConstructorTest.java
+++ /dev/null
@@ -1,263 +0,0 @@
-/*
- * Copyright (C) 2017 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 androidx.room3.integration.testapp.test;
-
-import static org.hamcrest.CoreMatchers.is;
-import static org.hamcrest.MatcherAssert.assertThat;
-
-import androidx.room3.Dao;
-import androidx.room3.Database;
-import androidx.room3.Embedded;
-import androidx.room3.Entity;
-import androidx.room3.Insert;
-import androidx.room3.PrimaryKey;
-import androidx.room3.Query;
-import androidx.room3.Room;
-import androidx.room3.RoomDatabase;
-import androidx.test.core.app.ApplicationProvider;
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.test.filters.SmallTest;
-
-import org.jspecify.annotations.NonNull;
-import org.jspecify.annotations.Nullable;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-@RunWith(AndroidJUnit4.class)
-@SuppressWarnings("SqlNoDataSourceInspection")
-@SmallTest
-public class ConstructorTest {
-    @Database(version = 1, entities = {FullConstructor.class, PartialConstructor.class,
-            EntityWithAnnotations.class},
-            exportSchema = false)
-    abstract static class MyDb extends RoomDatabase {
-        abstract MyDao dao();
-    }
-
-    @Dao
-    interface MyDao {
-        @Insert
-        void insertFull(FullConstructor... full);
-
-        @Query("SELECT * FROM fc WHERE a = :a")
-        FullConstructor loadFull(int a);
-
-        @Insert
-        void insertPartial(PartialConstructor... partial);
-
-        @Query("SELECT * FROM pc WHERE a = :a")
-        PartialConstructor loadPartial(int a);
-
-        @Insert
-        void insertEntityWithAnnotations(EntityWithAnnotations... items);
-
-        @Query("SELECT * FROM EntityWithAnnotations")
-        EntityWithAnnotations getEntitiWithAnnotations();
-    }
-
-    @SuppressWarnings("WeakerAccess")
-    @Entity(tableName = "fc")
-    static class FullConstructor {
-        @PrimaryKey
-        public final int a;
-        public final int b;
-        @Embedded
-        public final MyEmbedded embedded;
-
-        FullConstructor(int a, int b, MyEmbedded embedded) {
-            this.a = a;
-            this.b = b;
-            this.embedded = embedded;
-        }
-
-        @Override
-        public boolean equals(Object o) {
-            if (this == o) return true;
-            if (o == null || getClass() != o.getClass()) return false;
-
-            FullConstructor that = (FullConstructor) o;
-
-            if (a != that.a) return false;
-            //noinspection SimplifiableIfStatement
-            if (b != that.b) return false;
-            return embedded != null ? embedded.equals(that.embedded)
-                    : that.embedded == null;
-        }
-
-        @Override
-        public int hashCode() {
-            int result = a;
-            result = 31 * result + b;
-            result = 31 * result + (embedded != null ? embedded.hashCode() : 0);
-            return result;
-        }
-    }
-
-    @SuppressWarnings("WeakerAccess")
-    @Entity(tableName = "pc")
-    static class PartialConstructor {
-        @PrimaryKey
-        public final int a;
-        public int b;
-        @Embedded
-        private MyEmbedded mEmbedded;
-
-        PartialConstructor(int a) {
-            this.a = a;
-        }
-
-        public MyEmbedded getEmbedded() {
-            return mEmbedded;
-        }
-
-        public void setEmbedded(MyEmbedded embedded) {
-            mEmbedded = embedded;
-        }
-
-        @Override
-        public boolean equals(Object o) {
-            if (this == o) return true;
-            if (o == null || getClass() != o.getClass()) return false;
-
-            PartialConstructor that = (PartialConstructor) o;
-
-            if (a != that.a) return false;
-            //noinspection SimplifiableIfStatement
-            if (b != that.b) return false;
-            return mEmbedded != null ? mEmbedded.equals(that.mEmbedded)
-                    : that.mEmbedded == null;
-        }
-
-        @Override
-        public int hashCode() {
-            int result = a;
-            result = 31 * result + b;
-            result = 31 * result + (mEmbedded != null ? mEmbedded.hashCode() : 0);
-            return result;
-        }
-    }
-
-    @SuppressWarnings("WeakerAccess")
-    static class MyEmbedded {
-        public final String text;
-
-        MyEmbedded(String text) {
-            this.text = text;
-        }
-
-        @Override
-        public boolean equals(Object o) {
-            if (this == o) return true;
-            if (o == null || getClass() != o.getClass()) return false;
-
-            MyEmbedded that = (MyEmbedded) o;
-
-            return text != null ? text.equals(that.text) : that.text == null;
-        }
-
-        @Override
-        public int hashCode() {
-            return text != null ? text.hashCode() : 0;
-        }
-    }
-
-    @SuppressWarnings("WeakerAccess")
-    @Entity
-    static class EntityWithAnnotations {
-        @PrimaryKey
-        // This project is tested against a version of the room compiler that doesn't recognize
-        // JSpecify for primary keys
-        @SuppressWarnings("JSpecifyNullness")
-        @androidx.annotation.NonNull
-        public final String id;
-
-        public final @NonNull String username;
-
-        public final @Nullable String displayName;
-
-        EntityWithAnnotations(
-                @NonNull String id,
-                @NonNull String username,
-                @Nullable String displayName) {
-            this.id = id;
-            this.username = username;
-            this.displayName = displayName;
-        }
-
-        @Override
-        public boolean equals(Object o) {
-            if (this == o) return true;
-            if (o == null || getClass() != o.getClass()) return false;
-
-            EntityWithAnnotations that = (EntityWithAnnotations) o;
-
-            if (!id.equals(that.id)) return false;
-            if (!username.equals(that.username)) return false;
-            return displayName != null ? displayName.equals(that.displayName)
-                    : that.displayName == null;
-        }
-
-        @Override
-        public int hashCode() {
-            int result = id.hashCode();
-            result = 31 * result + username.hashCode();
-            result = 31 * result + (displayName != null ? displayName.hashCode() : 0);
-            return result;
-        }
-    }
-
-    private MyDb mDb;
-    private MyDao mDao;
-
-    @Before
-    public void init() {
-        mDb = Room.inMemoryDatabaseBuilder(ApplicationProvider.getApplicationContext(), MyDb.class)
-                .build();
-        mDao = mDb.dao();
-    }
-
-    @After
-    public void teardown() {
-        mDb.close();
-    }
-
-    @Test
-    public void insertAndReadFullConstructor() {
-        FullConstructor inserted = new FullConstructor(1, 2, null);
-        mDao.insertFull(inserted);
-        final FullConstructor load = mDao.loadFull(1);
-        assertThat(load, is(inserted));
-    }
-
-    @Test
-    public void insertAndReadPartial() {
-        PartialConstructor item = new PartialConstructor(3);
-        item.b = 7;
-        mDao.insertPartial(item);
-        PartialConstructor load = mDao.loadPartial(3);
-        assertThat(load, is(item));
-    }
-
-    @Test // for bug b/69562125
-    public void entityWithAnnotations() {
-        EntityWithAnnotations item = new EntityWithAnnotations("a", "b", null);
-        mDao.insertEntityWithAnnotations(item);
-        assertThat(mDao.getEntitiWithAnnotations(), is(item));
-    }
-}
diff --git a/room3/integration-tests/testapp/src/androidTest/java/androidx/room3/integration/testapp/test/CustomDatabaseTest.java b/room3/integration-tests/testapp/src/androidTest/java/androidx/room3/integration/testapp/test/CustomDatabaseTest.java
deleted file mode 100644
index 2681ae9..0000000
--- a/room3/integration-tests/testapp/src/androidTest/java/androidx/room3/integration/testapp/test/CustomDatabaseTest.java
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * Copyright (C) 2017 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 androidx.room3.integration.testapp.test;
-
-import static org.mockito.AdditionalAnswers.delegatesTo;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.doAnswer;
-import static org.mockito.Mockito.mock;
-
-import android.content.Context;
-import android.database.Cursor;
-import android.database.sqlite.SQLiteException;
-import android.os.SystemClock;
-
-import androidx.room3.Room;
-import androidx.room3.RoomDatabase;
-import androidx.room3.integration.testapp.database.Customer;
-import androidx.room3.integration.testapp.database.SampleDatabase;
-import androidx.sqlite.db.SupportSQLiteDatabase;
-import androidx.sqlite.db.SupportSQLiteOpenHelper;
-import androidx.sqlite.db.SupportSQLiteQuery;
-import androidx.sqlite.db.framework.FrameworkSQLiteOpenHelperFactory;
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.test.filters.LargeTest;
-import androidx.test.platform.app.InstrumentationRegistry;
-
-import org.jspecify.annotations.NonNull;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.invocation.InvocationOnMock;
-import org.mockito.stubbing.Answer;
-
-@LargeTest
-@RunWith(AndroidJUnit4.class)
-public class CustomDatabaseTest {
-
-    @Test
-    public void invalidationTrackerAfterClose() {
-        final String databaseName = "custom.db";
-        Context context = InstrumentationRegistry.getInstrumentation().getTargetContext();
-        context.deleteDatabase(databaseName);
-        RoomDatabase.Builder<SampleDatabase> builder =
-                Room.databaseBuilder(context, SampleDatabase.class, databaseName)
-                        .openHelperFactory(new RethrowExceptionFactory());
-        Customer customer = new Customer();
-        for (int i = 0; i < 100; i++) {
-            SampleDatabase db = builder.build();
-            db.getCustomerDao().insert(customer);
-            // Give InvalidationTracker enough time to start #mRefreshRunnable and pass the
-            // initialization check.
-            SystemClock.sleep(1);
-            // InvalidationTracker#mRefreshRunnable will cause race condition if its database query
-            // happens after close.
-            db.close();
-        }
-    }
-
-    /**
-     * This is mostly {@link FrameworkSQLiteOpenHelperFactory}, but the returned {@link
-     * SupportSQLiteDatabase} fails with {@link RuntimeException} instead of {@link
-     * IllegalStateException} or {@link SQLiteException}. This way, we can simulate custom database
-     * implementation that throws its own exception types.
-     */
-    private static class RethrowExceptionFactory implements SupportSQLiteOpenHelper.Factory {
-
-        @Override
-        public @NonNull SupportSQLiteOpenHelper create(
-                SupportSQLiteOpenHelper.@NonNull Configuration configuration) {
-            final FrameworkSQLiteOpenHelperFactory factory = new FrameworkSQLiteOpenHelperFactory();
-            final SupportSQLiteOpenHelper helper = factory.create(configuration);
-            SupportSQLiteOpenHelper helperMock = mock(SupportSQLiteOpenHelper.class,
-                    delegatesTo(helper));
-            // Inject mocks to the object hierarchy.
-            doAnswer(new Answer() {
-                @Override
-                public SupportSQLiteDatabase answer(InvocationOnMock invocation)
-                        throws Throwable {
-                    final SupportSQLiteDatabase db = helper.getWritableDatabase();
-                    SupportSQLiteDatabase dbMock = mock(SupportSQLiteDatabase.class,
-                            delegatesTo(db));
-                    doAnswer(new Answer() {
-                        @Override
-                        public Cursor answer(InvocationOnMock invocation) throws Throwable {
-                            SupportSQLiteQuery query = invocation.getArgument(0);
-                            try {
-                                return db.query(query);
-                            } catch (IllegalStateException | SQLiteException e) {
-                                // Rethrow the exception in order to simulate the way custom
-                                // database implementation throws its own exception types.
-                                throw new RuntimeException("closed", e);
-                            }
-                        }
-                    }).when(dbMock).query(any(SupportSQLiteQuery.class));
-                    return dbMock;
-                }
-            }).when(helperMock).getWritableDatabase();
-            return helperMock;
-        }
-    }
-}
diff --git a/room3/integration-tests/testapp/src/androidTest/java/androidx/room3/integration/testapp/test/CustomFTSTokenizerTest.java b/room3/integration-tests/testapp/src/androidTest/java/androidx/room3/integration/testapp/test/CustomFTSTokenizerTest.java
deleted file mode 100644
index 329564c..0000000
--- a/room3/integration-tests/testapp/src/androidTest/java/androidx/room3/integration/testapp/test/CustomFTSTokenizerTest.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright 2018 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 androidx.room3.integration.testapp.test;
-
-import androidx.room3.Dao;
-import androidx.room3.Database;
-import androidx.room3.Entity;
-import androidx.room3.Fts4;
-import androidx.room3.FtsOptions;
-import androidx.room3.Query;
-import androidx.room3.RoomDatabase;
-
-/**
- * Not an actual JUnit test class, but it is here so that we can test that room-compiler will
- * correctly verify a table create query that contains a custom tokenizer.
- */
-public class CustomFTSTokenizerTest {
-
-    @Database(
-            entities = {TheEntity.class, TheEntityWithICU.class},
-            version = 1,
-            exportSchema = false
-    )
-    abstract static class CustomTokDatabase extends RoomDatabase  {
-        public abstract TheDao getDao();
-    }
-
-    @Entity
-    @Fts4(tokenizer = "customICU", tokenizerArgs = "en_AU")
-    static class TheEntity {
-        public String data;
-    }
-
-    // For b/201753224
-    @Entity
-    @Fts4(tokenizer = FtsOptions.TOKENIZER_ICU)
-    static class TheEntityWithICU {
-        public String data;
-    }
-
-    @Dao
-    interface TheDao {
-        @Query("SELECT * FROM TheEntity WHERE data MATCH :term")
-        TheEntity search(String term);
-    }
-}
diff --git a/room3/integration-tests/testapp/src/androidTest/java/androidx/room3/integration/testapp/test/DaoConflictStrategyTest.java b/room3/integration-tests/testapp/src/androidTest/java/androidx/room3/integration/testapp/test/DaoConflictStrategyTest.java
deleted file mode 100644
index aa2fb08..0000000
--- a/room3/integration-tests/testapp/src/androidTest/java/androidx/room3/integration/testapp/test/DaoConflictStrategyTest.java
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- * Copyright 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package androidx.room3.integration.testapp.test;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.content.Context;
-
-import androidx.room3.Room;
-import androidx.room3.integration.testapp.TestDatabase;
-import androidx.room3.integration.testapp.dao.PetDao;
-import androidx.room3.integration.testapp.dao.ToyDao;
-import androidx.room3.integration.testapp.vo.Pet;
-import androidx.room3.integration.testapp.vo.Toy;
-import androidx.test.core.app.ApplicationProvider;
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.test.filters.SmallTest;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-@SmallTest
-@RunWith(AndroidJUnit4.class)
-public class DaoConflictStrategyTest {
-    private TestDatabase mDb;
-    private ToyDao mToyDao;
-    private Toy mOriginalToy;
-    private PetDao mPetDao;
-    private Pet mPet;
-
-    @Before
-    public void createDbAndSetUpToys() {
-        Context context = ApplicationProvider.getApplicationContext();
-        mDb = Room.inMemoryDatabaseBuilder(context, TestDatabase.class).build();
-        mToyDao = mDb.getToyDao();
-        mPetDao = mDb.getPetDao();
-
-        mPet = TestUtil.createPet(1);
-        mOriginalToy = new Toy();
-        mOriginalToy.setId(10);
-        mOriginalToy.setName("originalToy");
-        mOriginalToy.setPetId(1);
-
-        mPetDao.insertOrReplace(mPet);
-        mToyDao.insert(mOriginalToy);
-    }
-
-    @After
-    public void closeDb() {
-        mDb.close();
-    }
-
-    @Test
-    public void testInsertOnConflictReplace() {
-        Toy newToy = new Toy();
-        newToy.setId(10);
-        newToy.setName("newToy");
-        newToy.setPetId(1);
-        mToyDao.insertOrReplace(newToy);
-
-        Toy output = mToyDao.getToy(10);
-        assertThat(output).isNotNull();
-        assertThat(output.getName()).isEqualTo(newToy.getName());
-    }
-
-    @Test
-    public void testInsertOnConflictIgnore() {
-        Toy newToy = new Toy();
-        newToy.setId(10);
-        newToy.setName("newToy");
-        newToy.setPetId(1);
-        mToyDao.insertOrIgnore(newToy);
-
-        Toy output = mToyDao.getToy(10);
-        assertThat(output).isNotNull();
-        assertThat(output.getName()).isEqualTo(mOriginalToy.getName());
-    }
-
-    @Test
-    public void testUpdateOnConflictReplace() {
-        Toy newToy = new Toy();
-        newToy.setId(11);
-        newToy.setName("newToy");
-        newToy.setPetId(1);
-        mToyDao.insert(newToy);
-
-        Toy conflictToy = new Toy();
-        conflictToy.setId(11);
-        conflictToy.setName("originalToy");
-        conflictToy.setPetId(1);
-        mToyDao.updateOrReplace(conflictToy);
-
-        // Conflicting row is deleted
-        assertThat(mToyDao.getToy(10)).isNull();
-
-        // Row is updated
-        Toy output = mToyDao.getToy(11);
-        assertThat(output).isNotNull();
-        assertThat(output.getName()).isEqualTo(conflictToy.getName());
-    }
-
-    @Test
-    public void testUpdateOnConflictIgnore() {
-        Toy newToy = new Toy();
-        newToy.setId(11);
-        newToy.setName("newToy");
-        newToy.setPetId(1);
-        mToyDao.insert(newToy);
-
-        Toy conflictToy = new Toy();
-        conflictToy.setId(11);
-        conflictToy.setName("originalToy");
-        conflictToy.setPetId(1);
-        mToyDao.updateOrIgnore(conflictToy);
-
-        // Conflicting row is kept
-        assertThat(mToyDao.getToy(10)).isNotNull();
-
-        // Row is not updated
-        Toy output = mToyDao.getToy(11);
-        assertThat(output).isNotNull();
-        assertThat(output.getName()).isEqualTo(newToy.getName());
-    }
-}
-
diff --git a/room3/integration-tests/testapp/src/androidTest/java/androidx/room3/integration/testapp/test/DaoNameConflictTest.java b/room3/integration-tests/testapp/src/androidTest/java/androidx/room3/integration/testapp/test/DaoNameConflictTest.java
deleted file mode 100644
index d345e19..0000000
--- a/room3/integration-tests/testapp/src/androidTest/java/androidx/room3/integration/testapp/test/DaoNameConflictTest.java
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
- * Copyright 2018 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 androidx.room3.integration.testapp.test;
-
-import static org.hamcrest.CoreMatchers.is;
-import static org.hamcrest.MatcherAssert.assertThat;
-
-import androidx.room3.Dao;
-import androidx.room3.Database;
-import androidx.room3.Entity;
-import androidx.room3.Insert;
-import androidx.room3.PrimaryKey;
-import androidx.room3.Query;
-import androidx.room3.Room;
-import androidx.room3.RoomDatabase;
-import androidx.test.core.app.ApplicationProvider;
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.test.filters.SmallTest;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-@RunWith(AndroidJUnit4.class)
-@SmallTest
-public class DaoNameConflictTest {
-    private ConflictDatabase mDb;
-    @Before
-    public void init() {
-        mDb = Room.inMemoryDatabaseBuilder(
-                ApplicationProvider.getApplicationContext(),
-                ConflictDatabase.class
-        ).build();
-    }
-
-    @After
-    public void close() {
-        mDb.close();
-    }
-
-    @Test
-    public void readFromItem1() {
-        Item1 item1 = new Item1(1, "a");
-        mDb.item1Dao().insert(item1);
-        Item2 item2 = new Item2(2, "b");
-        mDb.item2Dao().insert(item2);
-        assertThat(mDb.item1Dao().get(), is(item1));
-        assertThat(mDb.item2Dao().get(), is(item2));
-    }
-
-    @Entity
-    static class Item1 {
-        @PrimaryKey
-        public int id;
-        public String name;
-
-        Item1(int id, String name) {
-            this.id = id;
-            this.name = name;
-        }
-
-        @Dao
-        public interface Store {
-            @Query("SELECT * FROM Item1 LIMIT 1")
-            Item1 get();
-            @Insert
-            void insert(Item1... items);
-        }
-
-        @Override
-        public boolean equals(Object o) {
-            if (this == o) return true;
-            if (o == null || getClass() != o.getClass()) return false;
-            Item1 item1 = (Item1) o;
-
-            //noinspection SimplifiableIfStatement
-            if (id != item1.id) return false;
-            return name != null ? name.equals(item1.name) : item1.name == null;
-        }
-
-        @Override
-        public int hashCode() {
-            int result = id;
-            result = 31 * result + (name != null ? name.hashCode() : 0);
-            return result;
-        }
-    }
-
-    @Entity
-    static class Item2 {
-        @PrimaryKey
-        public int id;
-        public String name;
-
-        Item2(int id, String name) {
-            this.id = id;
-            this.name = name;
-        }
-
-        @Dao
-        public interface Store {
-            @Query("SELECT * FROM Item2 LIMIT 1")
-            Item2 get();
-            @Insert
-            void insert(Item2... items);
-        }
-
-        @Override
-        public boolean equals(Object o) {
-            if (this == o) return true;
-            if (o == null || getClass() != o.getClass()) return false;
-            Item2 item2 = (Item2) o;
-
-            //noinspection SimplifiableIfStatement
-            if (id != item2.id) return false;
-            return name != null ? name.equals(item2.name) : item2.name == null;
-        }
-
-        @Override
-        public int hashCode() {
-            int result = id;
-            result = 31 * result + (name != null ? name.hashCode() : 0);
-            return result;
-        }
-    }
-
-    @Database(version = 1, exportSchema = false, entities = {Item1.class, Item2.class})
-    public abstract static class ConflictDatabase extends RoomDatabase {
-        public abstract Item1.Store item1Dao();
-        public abstract Item2.Store item2Dao();
-    }
-}
diff --git a/room3/integration-tests/testapp/src/androidTest/java/androidx/room3/integration/testapp/test/DatabaseCallbackTest.java b/room3/integration-tests/testapp/src/androidTest/java/androidx/room3/integration/testapp/test/DatabaseCallbackTest.java
deleted file mode 100644
index 6b81225..0000000
--- a/room3/integration-tests/testapp/src/androidTest/java/androidx/room3/integration/testapp/test/DatabaseCallbackTest.java
+++ /dev/null
@@ -1,237 +0,0 @@
-/*
- * Copyright (C) 2017 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 androidx.room3.integration.testapp.test;
-
-import static org.hamcrest.CoreMatchers.is;
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.hamcrest.Matchers.empty;
-import static org.hamcrest.core.IsCollectionContaining.hasItem;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
-import android.content.ContentValues;
-import android.content.Context;
-import android.database.Cursor;
-import android.database.sqlite.SQLiteDatabase;
-import android.database.sqlite.SQLiteException;
-
-import androidx.room3.Database;
-import androidx.room3.Room;
-import androidx.room3.RoomDatabase;
-import androidx.room3.integration.testapp.TestDatabase;
-import androidx.room3.integration.testapp.dao.ProductDao;
-import androidx.room3.integration.testapp.vo.Product;
-import androidx.room3.integration.testapp.vo.User;
-import androidx.sqlite.db.SupportSQLiteDatabase;
-import androidx.test.core.app.ApplicationProvider;
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.test.filters.MediumTest;
-
-import org.jspecify.annotations.NonNull;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.io.File;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-
-@MediumTest
-@RunWith(AndroidJUnit4.class)
-public class DatabaseCallbackTest {
-
-    @Test
-    public void createAndOpen() {
-        Context context = ApplicationProvider.getApplicationContext();
-        TestDatabaseCallback callback1 = new TestDatabaseCallback();
-        TestDatabase db1 = null;
-        TestDatabase db2 = null;
-        try {
-            db1 = Room.databaseBuilder(context, TestDatabase.class, "test")
-                    .addCallback(callback1)
-                    .build();
-            assertFalse(callback1.mCreated);
-            assertFalse(callback1.mOpened);
-            User user1 = TestUtil.createUser(3);
-            user1.setName("george");
-            db1.getUserDao().insert(user1);
-            assertTrue(callback1.mCreated);
-            assertTrue(callback1.mOpened);
-            TestDatabaseCallback callback2 = new TestDatabaseCallback();
-            db2 = Room.databaseBuilder(context, TestDatabase.class, "test")
-                    .addCallback(callback2)
-                    .build();
-            assertFalse(callback2.mCreated);
-            assertFalse(callback2.mOpened);
-            User user2 = db2.getUserDao().load(3);
-            assertThat(user2.getName(), is("george"));
-            assertFalse(callback2.mCreated); // Not called; already created by db1
-            assertTrue(callback2.mOpened);
-        } finally {
-            if (db1 != null) {
-                db1.close();
-            }
-            if (db2 != null) {
-                db2.close();
-            }
-            assertTrue(context.deleteDatabase("test"));
-        }
-    }
-
-    @Test
-    public void writeOnCreate() {
-        Context context = ApplicationProvider.getApplicationContext();
-        TestDatabase db = Room.inMemoryDatabaseBuilder(context, TestDatabase.class)
-                .addCallback(new RoomDatabase.Callback() {
-                    @Override
-                    public void onCreate(@NonNull SupportSQLiteDatabase db) {
-                        Cursor cursor = null;
-                        try {
-                            cursor = db.query(
-                                    "SELECT name FROM sqlite_master WHERE type = 'table'");
-                            ArrayList<String> names = new ArrayList<>();
-                            while (cursor.moveToNext()) {
-                                names.add(cursor.getString(0));
-                            }
-                            assertThat(names, hasItem("User"));
-                        } finally {
-                            if (cursor != null) {
-                                cursor.close();
-                            }
-                        }
-                    }
-                })
-                .build();
-        List<Integer> ids = db.getUserDao().loadIds();
-        assertThat(ids, is(empty()));
-        db.close();
-    }
-
-    @Test
-    public void exceptionOnCreate() {
-        Context context = ApplicationProvider.getApplicationContext();
-        TestDatabase db = Room.inMemoryDatabaseBuilder(context, TestDatabase.class)
-                .addCallback(new RoomDatabase.Callback() {
-                    boolean mIsBadInsertDone;
-
-                    @Override
-                    public void onCreate(@NonNull SupportSQLiteDatabase db) {
-                        if (!mIsBadInsertDone) {
-                            mIsBadInsertDone = true;
-                            db.insert("fake_table",
-                                    SQLiteDatabase.CONFLICT_NONE,
-                                    new ContentValues());
-                        }
-                    }
-                })
-                .build();
-
-        try {
-            db.getUserDao().loadIds();
-        } catch (SQLiteException e) {
-            // Simulate user catching DB exceptions.
-        }
-
-        // Should not throw an "IllegalStateException: attempt to re-open an already-closed"
-        List<Integer> ids = db.getUserDao().loadIds();
-        assertThat(ids, is(empty()));
-
-        db.close();
-    }
-
-    @Test
-    public void corruptExceptionOnCreate() throws IOException {
-        Context context = ApplicationProvider.getApplicationContext();
-
-        TestDatabaseCallback callback = new TestDatabaseCallback();
-
-        // Create fake DB files that will cause a SQLiteDatabaseCorruptException: SQLITE_NOTADB.
-        String[] dbFiles = new String[]{"corrupted", "corrupted-shm", "corrupted-wal"};
-        for (String fileName : dbFiles) {
-            File dbFile = context.getDatabasePath(fileName);
-            try (FileWriter fileWriter = new FileWriter(dbFile)) {
-                fileWriter.write(new char[]{'p', 'o', 'i', 's', 'o', 'n'});
-            }
-        }
-
-        TestDatabase db = Room.databaseBuilder(context, TestDatabase.class, "corrupted")
-                .addCallback(callback)
-                .build();
-
-        assertFalse(callback.mCreated);
-        assertFalse(callback.mOpened);
-
-        // Should not throw a SQLiteDatabaseCorruptException, i.e. default onCorruption() was
-        // executed and DB file was re-created.
-        List<Integer> ids = db.getUserDao().loadIds();
-        db.close();
-        assertThat(ids, is(empty()));
-
-        assertTrue(callback.mCreated);
-        assertTrue(callback.mOpened);
-    }
-
-    @Test
-    public void onDestructiveMigration_calledOnUpgrade() {
-        Context context = ApplicationProvider.getApplicationContext();
-        context.deleteDatabase("products.db");
-        TestDatabaseCallback callback = new TestDatabaseCallback();
-        ProductsDatabase_v2 database = Room.databaseBuilder(
-                context, ProductsDatabase_v2.class, "products.db")
-                .createFromAsset("databases/products_v1.db")
-                .addCallback(callback)
-                .fallbackToDestructiveMigration(false)
-                .build();
-
-        assertFalse(callback.mDestructivelyMigrated);
-
-        // Use the database to trigger the opening and migration of the database
-        ProductDao dao = database.getProductDao();
-        dao.countProducts();
-
-        assertTrue(callback.mDestructivelyMigrated);
-        database.close();
-    }
-
-    @Database(entities = Product.class, version = 2, exportSchema = false)
-    abstract static class ProductsDatabase_v2 extends RoomDatabase {
-        abstract ProductDao getProductDao();
-    }
-
-    public static class TestDatabaseCallback extends RoomDatabase.Callback {
-
-        boolean mCreated;
-        boolean mOpened;
-        boolean mDestructivelyMigrated;
-
-        @Override
-        public void onCreate(@NonNull SupportSQLiteDatabase db) {
-            mCreated = true;
-        }
-
-        @Override
-        public void onOpen(@NonNull SupportSQLiteDatabase db) {
-            mOpened = true;
-        }
-
-        @Override
-        public void onDestructiveMigration(@NonNull SupportSQLiteDatabase db) {
-            mDestructivelyMigrated = true;
-        }
-    }
-}
diff --git a/room3/integration-tests/testapp/src/androidTest/java/androidx/room3/integration/testapp/test/DatabaseViewTest.java b/room3/integration-tests/testapp/src/androidTest/java/androidx/room3/integration/testapp/test/DatabaseViewTest.java
deleted file mode 100644
index 121a555..0000000
--- a/room3/integration-tests/testapp/src/androidTest/java/androidx/room3/integration/testapp/test/DatabaseViewTest.java
+++ /dev/null
@@ -1,470 +0,0 @@
-/*
- * Copyright 2018 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 androidx.room3.integration.testapp.test;
-
-import static org.hamcrest.CoreMatchers.equalTo;
-import static org.hamcrest.CoreMatchers.is;
-import static org.hamcrest.CoreMatchers.nullValue;
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.hamcrest.collection.IsCollectionWithSize.hasSize;
-import static org.mockito.ArgumentMatchers.argThat;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.reset;
-import static org.mockito.Mockito.timeout;
-import static org.mockito.Mockito.verify;
-
-import android.content.Context;
-
-import androidx.arch.core.executor.testing.CountingTaskExecutorRule;
-import androidx.lifecycle.LiveData;
-import androidx.lifecycle.Observer;
-import androidx.room3.Dao;
-import androidx.room3.Database;
-import androidx.room3.DatabaseView;
-import androidx.room3.Embedded;
-import androidx.room3.Entity;
-import androidx.room3.ForeignKey;
-import androidx.room3.Index;
-import androidx.room3.Insert;
-import androidx.room3.PrimaryKey;
-import androidx.room3.Query;
-import androidx.room3.Relation;
-import androidx.room3.Room;
-import androidx.room3.RoomDatabase;
-import androidx.room3.Transaction;
-import androidx.test.core.app.ApplicationProvider;
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.test.filters.MediumTest;
-import androidx.test.filters.SmallTest;
-import androidx.test.platform.app.InstrumentationRegistry;
-
-import org.jspecify.annotations.NonNull;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.util.List;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.TimeoutException;
-
-@RunWith(AndroidJUnit4.class)
-public class DatabaseViewTest {
-
-    @Entity(
-            foreignKeys = {
-                    @ForeignKey(
-                            entity = Employee.class,
-                            childColumns = {"managerId"},
-                            parentColumns = {"id"}),
-                    @ForeignKey(
-                            entity = Team.class,
-                            childColumns = {"teamId"},
-                            parentColumns = {"id"})},
-            indices = {
-                    @Index("managerId"),
-                    @Index("teamId")})
-    static class Employee {
-        @PrimaryKey
-        public long id;
-        public String name;
-        public Long managerId;
-        public long teamId;
-
-        Employee(long id, String name, Long managerId, long teamId) {
-            this.id = id;
-            this.name = name;
-            this.managerId = managerId;
-            this.teamId = teamId;
-        }
-    }
-
-    @DatabaseView("SELECT"
-            + "  employee.id"
-            + ", employee.name"
-            + ", employee.teamId"
-            + ", manager.id AS manager_id"
-            + ", manager.name AS manager_name"
-            + ", manager.managerId AS manager_managerId"
-            + ", manager.teamId AS manager_teamId"
-            + " FROM Employee AS employee LEFT JOIN Employee AS manager"
-            + " ON employee.managerId = manager.id")
-    static class EmployeeWithManager {
-        public long id;
-        public String name;
-        public long teamId;
-        @Embedded(prefix = "manager_")
-        public Employee manager;
-    }
-
-    @DatabaseView("SELECT"
-            + "  employee.id"
-            + ", employee.name"
-            + ", employee.manager_id"
-            + ", employee.manager_name"
-            + ", employee.manager_managerId"
-            + ", employee.manager_teamId"
-            + ", team.id AS team_id"
-            + ", team.name AS team_name"
-            + ", team.departmentId AS team_departmentId"
-            + ", team.departmentName AS team_departmentName"
-            + " FROM EmployeeWithManager AS employee"
-            + " LEFT JOIN TeamDetail AS team ON employee.teamId = team.id")
-    static class EmployeeDetail {
-        public long id;
-        public String name;
-        @Embedded(prefix = "manager_")
-        public Employee manager;
-        @Embedded(prefix = "team_")
-        public TeamDetail team;
-    }
-
-    static class TeamWithMembers {
-        @Embedded
-        public TeamDetail teamDetail;
-        @Relation(parentColumn = "id", entityColumn = "teamId")
-        public List<EmployeeWithManager> members;
-    }
-
-    @Entity(
-            foreignKeys = {
-                    @ForeignKey(
-                            entity = Department.class,
-                            childColumns = {"departmentId"},
-                            parentColumns = {"id"})},
-            indices = {
-                    @Index("departmentId")})
-    static class Team {
-        @PrimaryKey
-        public long id;
-        public long departmentId;
-        public String name;
-
-        Team(long id, long departmentId, String name) {
-            this.id = id;
-            this.departmentId = departmentId;
-            this.name = name;
-        }
-
-        @Override
-        public @NonNull String toString() {
-            return name + " (" + id + ", " + departmentId + ")";
-        }
-    }
-
-    @Entity
-    static class Department {
-        @PrimaryKey
-        public long id;
-        public String name;
-
-        Department(long id, String name) {
-            this.id = id;
-            this.name = name;
-        }
-    }
-
-    @DatabaseView(
-            "SELECT Team.id, Team.name, Team.departmentId, Department.name AS departmentName "
-                    + "FROM Team INNER JOIN Department ON Team.departmentId = Department.id ")
-    static class TeamDetail {
-        public long id;
-        public String name;
-        public long departmentId;
-        public String departmentName;
-    }
-
-    @DatabaseView(
-            "SELECT Team.*, dep.id AS department_id, dep.name as department_name FROM Team "
-                    + "INNER JOIN Department AS dep "
-                    + "ON Team.departmentId = dep.id"
-    )
-    static class TeamDetail2 {
-        @Embedded
-        public Team team;
-        @Embedded(prefix = "department_")
-        public Department department;
-    }
-
-    @DatabaseView("SELECT td1.id AS first_id, td1.name AS first_name, "
-            + "td1.departmentId AS first_departmentId, td1.departmentName AS first_departmentName, "
-            + "td2.id AS second_id, td2.name AS second_name, "
-            + "td2.departmentId AS second_departmentId, "
-            + "td2.departmentName AS second_departmentName "
-            + "FROM TeamDetail AS td1, TeamDetail AS td2 WHERE td1.id <> td2.id")
-    static class TeamPair {
-        @Embedded(prefix = "first_")
-        public TeamDetail first;
-        @Embedded(prefix = "second_")
-        public TeamDetail second;
-    }
-
-    @Dao
-    interface EmployeeDao {
-        @Insert
-        long insert(Employee employee);
-
-        @Query("UPDATE Employee SET managerId = :managerId WHERE id = :id")
-        void updateReport(long id, long managerId);
-
-        @Query("SELECT * FROM EmployeeWithManager WHERE id = :id")
-        EmployeeWithManager withManagerById(long id);
-
-        @Query("SELECT * FROM EmployeeDetail WHERE id = :id")
-        EmployeeDetail detailById(long id);
-
-        @Query("SELECT * FROM EmployeeDetail WHERE id = :id")
-        LiveData<EmployeeDetail> liveDetailById(long id);
-    }
-
-    @Dao
-    interface TeamDao {
-        @Insert
-        long insert(Team team);
-
-        @Query("SELECT * FROM TeamDetail WHERE id = :id")
-        TeamDetail detailById(long id);
-
-        @Query("SELECT * FROM TeamDetail")
-        LiveData<List<TeamDetail>> liveDetail();
-
-        @Transaction
-        @Query("SELECT * FROM TeamDetail WHERE id = :id")
-        TeamWithMembers withMembers(long id);
-
-        @Query("SELECT * FROM TeamDetail2 WHERE id = :id")
-        TeamDetail2 detail2ById(long id);
-
-        @Query("SELECT * FROM TeamPair WHERE first_id = :id")
-        List<TeamPair> roundRobinById(long id);
-    }
-
-    @Dao
-    interface DepartmentDao {
-        @Insert
-        long insert(Department department);
-
-        @Query("UPDATE Department SET name = :name WHERE id = :id")
-        void rename(long id, String name);
-    }
-
-    @Database(
-            entities = {
-                    Department.class,
-                    Team.class,
-                    Employee.class,
-            },
-            views = {
-                    TeamDetail.class,
-                    TeamDetail2.class,
-                    TeamPair.class,
-                    EmployeeWithManager.class,
-                    EmployeeDetail.class,
-            },
-            version = 1,
-            exportSchema = false)
-    abstract static class CompanyDatabase extends RoomDatabase {
-
-        abstract DepartmentDao department();
-
-        abstract TeamDao team();
-
-        abstract EmployeeDao employee();
-    }
-
-    @Rule
-    public CountingTaskExecutorRule executorRule = new CountingTaskExecutorRule();
-
-    private CompanyDatabase getDatabase() {
-        final Context context = ApplicationProvider.getApplicationContext();
-        return Room.inMemoryDatabaseBuilder(context, CompanyDatabase.class).build();
-    }
-
-    @Test
-    @SmallTest
-    public void basic() {
-        final CompanyDatabase db = getDatabase();
-        db.department().insert(new Department(1L, "Sales"));
-        db.department().insert(new Department(2L, "IT"));
-        db.team().insert(new Team(1L, 1L, "Books"));
-        db.team().insert(new Team(2L, 2L, "Backend"));
-        final TeamDetail team1 = db.team().detailById(1L);
-        assertThat(team1.name, is(equalTo("Books")));
-        assertThat(team1.departmentName, is(equalTo("Sales")));
-        final TeamDetail team2 = db.team().detailById(2L);
-        assertThat(team2.name, is(equalTo("Backend")));
-        assertThat(team2.departmentName, is(equalTo("IT")));
-        db.close();
-    }
-
-    @Test
-    @SmallTest
-    public void embedded() {
-        final CompanyDatabase db = getDatabase();
-        db.department().insert(new Department(1, "Sales"));
-        db.team().insert(new Team(1L, 1L, "Books"));
-        db.employee().insert(new Employee(1L, "CEO", null, 1L));
-        db.employee().insert(new Employee(2L, "John", 1L, 1L));
-        db.employee().insert(new Employee(3L, "Jane", 2L, 1L));
-        assertThat(db.employee().withManagerById(1L).manager, is(nullValue()));
-        assertThat(db.employee().withManagerById(2L).manager.name, is(equalTo("CEO")));
-        assertThat(db.employee().withManagerById(3L).manager.name, is(equalTo("John")));
-        db.close();
-    }
-
-    @Test
-    @MediumTest
-    public void liveData() throws TimeoutException, InterruptedException {
-        final CompanyDatabase db = getDatabase();
-        db.department().insert(new Department(1L, "Shop"));
-        final LiveData<List<TeamDetail>> teams = db.team().liveDetail();
-        @SuppressWarnings("unchecked") final Observer<List<TeamDetail>> observer =
-                mock(Observer.class);
-        InstrumentationRegistry.getInstrumentation().runOnMainSync(() ->
-                teams.observeForever(observer));
-        db.team().insert(new Team(1L, 1L, "Books"));
-        executorRule.drainTasks(3000, TimeUnit.MILLISECONDS);
-        verify(observer, timeout(300L).atLeastOnce()).onChanged(argThat((list) ->
-                list.size() == 1
-                        && list.get(0).departmentName.equals("Shop")
-                        && list.get(0).name.equals("Books")));
-        resetMock(observer);
-        db.department().rename(1L, "Sales");
-        executorRule.drainTasks(3000, TimeUnit.MILLISECONDS);
-        verify(observer, timeout(300L).atLeastOnce()).onChanged(argThat((list) ->
-                list.size() == 1
-                        && list.get(0).departmentName.equals("Sales")
-                        && list.get(0).name.equals("Books")));
-        InstrumentationRegistry.getInstrumentation().runOnMainSync(() ->
-                teams.removeObserver(observer));
-        db.close();
-    }
-
-    @Test
-    @SmallTest
-    public void nested() {
-        final CompanyDatabase db = getDatabase();
-        db.department().insert(new Department(1L, "Shop"));
-        db.team().insert(new Team(1L, 1L, "Books"));
-        db.employee().insert(new Employee(1L, "CEO", null, 1L));
-        db.employee().insert(new Employee(2L, "John", 1L, 1L));
-
-        final EmployeeDetail employee = db.employee().detailById(2L);
-        assertThat(employee.name, is(equalTo("John")));
-        assertThat(employee.manager.name, is(equalTo("CEO")));
-        assertThat(employee.team.name, is(equalTo("Books")));
-        assertThat(employee.team.departmentName, is(equalTo("Shop")));
-        db.close();
-    }
-
-    @Test
-    @MediumTest
-    public void nestedLive() throws TimeoutException, InterruptedException {
-        final CompanyDatabase db = getDatabase();
-        final LiveData<EmployeeDetail> employee = db.employee().liveDetailById(2L);
-        @SuppressWarnings("unchecked") final Observer<EmployeeDetail> observer =
-                mock(Observer.class);
-        InstrumentationRegistry.getInstrumentation().runOnMainSync(() ->
-                employee.observeForever(observer));
-
-        db.department().insert(new Department(1L, "Shop"));
-        db.team().insert(new Team(1L, 1L, "Books"));
-        db.employee().insert(new Employee(1L, "CEO", null, 1L));
-        db.employee().insert(new Employee(2L, "Jane", 1L, 1L));
-        executorRule.drainTasks(3000, TimeUnit.MILLISECONDS);
-
-        verify(observer, timeout(300L).atLeastOnce()).onChanged(argThat(e ->
-                e != null
-                        && e.name.equals("Jane")
-                        && e.manager.name.equals("CEO")
-                        && e.team.name.equals("Books")
-                        && e.team.departmentName.equals("Shop")));
-
-        resetMock(observer);
-        db.runInTransaction(() -> {
-            db.department().rename(1L, "Sales");
-            db.employee().insert(new Employee(3L, "John", 1L, 1L));
-            db.employee().updateReport(2L, 3L);
-        });
-
-        executorRule.drainTasks(3000, TimeUnit.MILLISECONDS);
-        verify(observer, timeout(300L).atLeastOnce()).onChanged(argThat(e ->
-                e != null
-                        && e.name.equals("Jane")
-                        && e.manager.name.equals("John")
-                        && e.team.name.equals("Books")
-                        && e.team.departmentName.equals("Sales")));
-
-        InstrumentationRegistry.getInstrumentation().runOnMainSync(() ->
-                employee.removeObserver(observer));
-        db.close();
-    }
-
-    @Test
-    @MediumTest
-    public void viewInRelation() {
-        final CompanyDatabase db = getDatabase();
-        db.department().insert(new Department(1L, "Shop"));
-        db.team().insert(new Team(1L, 1L, "Books"));
-        db.employee().insert(new Employee(1L, "CEO", null, 1L));
-        db.employee().insert(new Employee(2L, "John", 1L, 1L));
-
-        TeamWithMembers teamWithMembers = db.team().withMembers(1L);
-        assertThat(teamWithMembers.teamDetail.name, is(equalTo("Books")));
-        assertThat(teamWithMembers.teamDetail.departmentName, is(equalTo("Shop")));
-        assertThat(teamWithMembers.members, hasSize(2));
-        assertThat(teamWithMembers.members.get(0).name, is(equalTo("CEO")));
-        assertThat(teamWithMembers.members.get(1).name, is(equalTo("John")));
-        assertThat(teamWithMembers.members.get(1).manager.name, is(equalTo("CEO")));
-        db.close();
-    }
-
-    @SuppressWarnings("unchecked")
-    private static <T> void resetMock(T mock) {
-        reset(mock);
-    }
-
-    @Test
-    @MediumTest
-    public void expandedProjection() {
-        final CompanyDatabase db = getDatabase();
-        db.department().insert(new Department(3L, "Sales"));
-        db.team().insert(new Team(5L, 3L, "Books"));
-        final TeamDetail2 detail = db.team().detail2ById(5L);
-        assertThat(detail.team.id, is(equalTo(5L)));
-        assertThat(detail.team.name, is(equalTo("Books")));
-        assertThat(detail.team.departmentId, is(equalTo(3L)));
-        assertThat(detail.department.id, is(equalTo(3L)));
-        assertThat(detail.department.name, is(equalTo("Sales")));
-        db.close();
-    }
-
-    @Test
-    @MediumTest
-    public void expandedProjection_embedView() {
-        final CompanyDatabase db = getDatabase();
-        db.department().insert(new Department(3L, "Sales"));
-        db.team().insert(new Team(5L, 3L, "Books"));
-        db.team().insert(new Team(7L, 3L, "Toys"));
-        List<TeamPair> pairs = db.team().roundRobinById(5L);
-        assertThat(pairs, hasSize(1));
-        assertThat(pairs.get(0).first.name, is(equalTo("Books")));
-        assertThat(pairs.get(0).first.departmentName, is(equalTo("Sales")));
-        assertThat(pairs.get(0).second.name, is(equalTo("Toys")));
-        assertThat(pairs.get(0).second.departmentName, is(equalTo("Sales")));
-        db.close();
-    }
-}
\ No newline at end of file
diff --git a/room3/integration-tests/testapp/src/androidTest/java/androidx/room3/integration/testapp/test/DefaultValueTest.java b/room3/integration-tests/testapp/src/androidTest/java/androidx/room3/integration/testapp/test/DefaultValueTest.java
deleted file mode 100644
index 04a32dc..0000000
--- a/room3/integration-tests/testapp/src/androidTest/java/androidx/room3/integration/testapp/test/DefaultValueTest.java
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- * Copyright 2018 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 androidx.room3.integration.testapp.test;
-
-import static org.hamcrest.CoreMatchers.equalTo;
-import static org.hamcrest.CoreMatchers.is;
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.hamcrest.Matchers.closeTo;
-
-import android.content.Context;
-
-import androidx.room3.ColumnInfo;
-import androidx.room3.Dao;
-import androidx.room3.Database;
-import androidx.room3.Entity;
-import androidx.room3.Insert;
-import androidx.room3.PrimaryKey;
-import androidx.room3.Query;
-import androidx.room3.Room;
-import androidx.room3.RoomDatabase;
-import androidx.room3.TypeConverter;
-import androidx.room3.TypeConverters;
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.test.filters.MediumTest;
-import androidx.test.platform.app.InstrumentationRegistry;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.text.ParseException;
-import java.text.SimpleDateFormat;
-import java.util.Date;
-import java.util.TimeZone;
-
-@MediumTest
-@RunWith(AndroidJUnit4.class)
-public class DefaultValueTest {
-
-    @SuppressWarnings("unused")
-    public static class TimestampConverter {
-
-        private static final SimpleDateFormat FORMAT = new SimpleDateFormat("yyyy-MM-dd kk:mm:ss");
-
-        static {
-            FORMAT.setTimeZone(TimeZone.getTimeZone("UTC"));
-        }
-
-        @TypeConverter
-        public String toTimestamp(Date date) {
-            return FORMAT.format(date);
-        }
-
-        @TypeConverter
-        public Date fromTimestamp(String timestamp) {
-            try {
-                return FORMAT.parse(timestamp);
-            } catch (ParseException e) {
-                throw new RuntimeException(e);
-            }
-        }
-    }
-
-    @SuppressWarnings("WeakerAccess")
-    @Entity
-    public static class Sample {
-        @PrimaryKey
-        public long id;
-        public String name;
-        @ColumnInfo(defaultValue = "No description")
-        public String description;
-        @ColumnInfo(defaultValue = "1")
-        public boolean available;
-        @ColumnInfo(defaultValue = "0")
-        public int serial;
-        @ColumnInfo(defaultValue = "CURRENT_TIMESTAMP")
-        @TypeConverters(TimestampConverter.class)
-        public Date timestamp;
-    }
-
-    public static class NameAndId {
-        public long id;
-        public String name;
-
-        public NameAndId(long id, String name) {
-            this.id = id;
-            this.name = name;
-        }
-    }
-
-    @Dao
-    public interface SampleDao {
-        @Query("INSERT INTO Sample (name) VALUES (:name)")
-        long insert(String name);
-
-        @Insert(entity = Sample.class)
-        void insertName(NameAndId nameAndId);
-
-        @Query("SELECT * FROM Sample WHERE id = :id")
-        Sample byId(long id);
-    }
-
-    @Database(entities = {Sample.class}, version = 1, exportSchema = false)
-    public abstract static class DefaultValueDatabase extends RoomDatabase {
-        public abstract SampleDao dao();
-    }
-
-    private DefaultValueDatabase openDatabase() {
-        final Context context = InstrumentationRegistry.getInstrumentation().getTargetContext();
-        return Room.inMemoryDatabaseBuilder(context, DefaultValueDatabase.class).build();
-    }
-
-    @Test
-    public void defaultValues() {
-        final DefaultValueDatabase db = openDatabase();
-        final long id = db.dao().insert("A");
-        final long now = System.currentTimeMillis();
-        final Sample sample = db.dao().byId(id);
-        assertThat(sample.name, is(equalTo("A")));
-        assertThat(sample.description, is(equalTo("No description")));
-        assertThat(sample.available, is(true));
-        assertThat(sample.serial, is(0));
-        assertThat((double) sample.timestamp.getTime(), is(closeTo(now, 3000)));
-        db.close();
-    }
-
-    @Test
-    public void defaultValues_partialEntity() {
-        final DefaultValueDatabase db = openDatabase();
-        final NameAndId nameAndId = new NameAndId(1, "A");
-        db.dao().insertName(nameAndId);
-        final long now = System.currentTimeMillis();
-        final Sample sample = db.dao().byId(1);
-        assertThat(sample.name, is(equalTo("A")));
-        assertThat(sample.description, is(equalTo("No description")));
-        assertThat(sample.available, is(true));
-        assertThat(sample.serial, is(0));
-        assertThat((double) sample.timestamp.getTime(), is(closeTo(now, 3000)));
-        db.close();
-    }
-}
diff --git a/room3/integration-tests/testapp/src/androidTest/java/androidx/room3/integration/testapp/test/EmbeddedTest.java b/room3/integration-tests/testapp/src/androidTest/java/androidx/room3/integration/testapp/test/EmbeddedTest.java
deleted file mode 100644
index a495d54..0000000
--- a/room3/integration-tests/testapp/src/androidTest/java/androidx/room3/integration/testapp/test/EmbeddedTest.java
+++ /dev/null
@@ -1,268 +0,0 @@
-/*
- * Copyright (C) 2017 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 androidx.room3.integration.testapp.test;
-
-import static org.hamcrest.CoreMatchers.is;
-import static org.hamcrest.CoreMatchers.notNullValue;
-import static org.hamcrest.CoreMatchers.nullValue;
-import static org.hamcrest.MatcherAssert.assertThat;
-
-import android.content.Context;
-
-import androidx.room3.Room;
-import androidx.room3.integration.testapp.TestDatabase;
-import androidx.room3.integration.testapp.dao.PetCoupleDao;
-import androidx.room3.integration.testapp.dao.PetDao;
-import androidx.room3.integration.testapp.dao.SchoolDao;
-import androidx.room3.integration.testapp.dao.UserDao;
-import androidx.room3.integration.testapp.dao.UserPetDao;
-import androidx.room3.integration.testapp.vo.Coordinates;
-import androidx.room3.integration.testapp.vo.Pet;
-import androidx.room3.integration.testapp.vo.PetCouple;
-import androidx.room3.integration.testapp.vo.School;
-import androidx.room3.integration.testapp.vo.SchoolRef;
-import androidx.room3.integration.testapp.vo.User;
-import androidx.room3.integration.testapp.vo.UserAndGenericPet;
-import androidx.room3.integration.testapp.vo.UserAndPet;
-import androidx.room3.integration.testapp.vo.UserAndPetNonNull;
-import androidx.test.core.app.ApplicationProvider;
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.test.filters.SmallTest;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.Callable;
-
-@SmallTest
-@RunWith(AndroidJUnit4.class)
-public class EmbeddedTest {
-    private TestDatabase mDb;
-    private UserDao mUserDao;
-    private PetDao mPetDao;
-    private UserPetDao mUserPetDao;
-    private SchoolDao mSchoolDao;
-    private PetCoupleDao mPetCoupleDao;
-
-    @Before
-    public void createDb() {
-        Context context = ApplicationProvider.getApplicationContext();
-        mDb = Room.inMemoryDatabaseBuilder(context, TestDatabase.class).build();
-        mUserDao = mDb.getUserDao();
-        mPetDao = mDb.getPetDao();
-        mUserPetDao = mDb.getUserPetDao();
-        mSchoolDao = mDb.getSchoolDao();
-        mPetCoupleDao = mDb.getPetCoupleDao();
-    }
-
-    @After
-    public void closeDb() {
-        mDb.close();
-    }
-
-    @Test
-    public void loadAll() {
-        Pet pet = TestUtil.createPet(1);
-        User user = TestUtil.createUser(2);
-        pet.setUserId(user.getId());
-        mUserDao.insert(user);
-        mPetDao.insertOrReplace(pet);
-        List<UserAndPet> all = mUserPetDao.loadAll();
-        assertThat(all.size(), is(1));
-        assertThat(all.get(0).getUser(), is(user));
-        assertThat(all.get(0).getPet(), is(pet));
-    }
-
-    @Test
-    public void loadAllGeneric() {
-        Pet pet = TestUtil.createPet(1);
-        User user = TestUtil.createUser(2);
-        pet.setUserId(user.getId());
-        mUserDao.insert(user);
-        mPetDao.insertOrReplace(pet);
-        List<UserAndGenericPet> all = mUserPetDao.loadAllGeneric();
-        assertThat(all.size(), is(1));
-        assertThat(all.get(0).user, is(user));
-        assertThat(all.get(0).item, is(pet));
-    }
-
-    @Test
-    public void loadFromUsers() {
-        Pet pet = TestUtil.createPet(1);
-        User user = TestUtil.createUser(2);
-        pet.setUserId(user.getId());
-        mUserDao.insert(user);
-        mPetDao.insertOrReplace(pet);
-        List<UserAndPet> all = mUserPetDao.loadUsers();
-        assertThat(all.size(), is(1));
-        assertThat(all.get(0).getUser(), is(user));
-        assertThat(all.get(0).getPet(), is(pet));
-    }
-
-    @Test
-    public void loadFromUsersWithNullPet() {
-        User user = TestUtil.createUser(2);
-        mUserDao.insert(user);
-        List<UserAndPet> all = mUserPetDao.loadUsers();
-        assertThat(all.size(), is(1));
-        assertThat(all.get(0).getUser(), is(user));
-        assertThat(all.get(0).getPet(), is(nullValue()));
-    }
-
-    @Test
-    public void loadFromUsersWithNonNullPet() {
-        User user = TestUtil.createUser(2);
-        mUserDao.insert(user);
-        List<UserAndPetNonNull> all = mUserPetDao.loadUsersWithNonNullPet();
-        assertThat(all.size(), is(1));
-        assertThat(all.get(0).getUser(), is(user));
-        assertThat(all.get(0).getPet(), is(new Pet()));
-    }
-
-    @Test
-    public void loadFromPets() {
-        Pet pet = TestUtil.createPet(1);
-        User user = TestUtil.createUser(2);
-        pet.setUserId(user.getId());
-        mUserDao.insert(user);
-        mPetDao.insertOrReplace(pet);
-        List<UserAndPet> all = mUserPetDao.loadPets();
-        assertThat(all.size(), is(1));
-        assertThat(all.get(0).getUser(), is(user));
-        assertThat(all.get(0).getPet(), is(pet));
-    }
-
-    @Test
-    public void loadFromPetsWithNullUser() {
-        Pet pet = TestUtil.createPet(1);
-        mPetDao.insertOrReplace(pet);
-        List<UserAndPet> all = mUserPetDao.loadPets();
-        assertThat(all.size(), is(1));
-        assertThat(all.get(0).getUser(), is(nullValue()));
-        assertThat(all.get(0).getPet(), is(pet));
-    }
-
-    @Test
-    public void findSchoolByStreet() {
-        School school = TestUtil.createSchool(3, 5);
-        school.getAddress().setStreet("foo");
-        mSchoolDao.insert(school);
-        List<School> result = mSchoolDao.findByStreet("foo");
-        assertThat(result.size(), is(1));
-        assertThat(result.get(0), is(school));
-    }
-
-    @Test
-    public void loadSubFieldsAsPojo() throws Exception {
-        loadSubFieldsTest(new Callable<List<School>>() {
-            @Override
-            public List<School> call() throws Exception {
-                List<School> result = new ArrayList<>();
-                for (SchoolRef ref : mSchoolDao.schoolAndManagerNamesAsPojo()) {
-                    result.add(ref);
-                }
-                return result;
-            }
-        });
-    }
-
-    @Test
-    public void loadSubFieldsAsEntity() throws Exception {
-        loadSubFieldsTest(new Callable<List<School>>() {
-            @Override
-            public List<School> call() throws Exception {
-                return mSchoolDao.schoolAndManagerNames();
-            }
-        });
-    }
-
-    public void loadSubFieldsTest(Callable<List<School>> loader) throws Exception {
-        School school = TestUtil.createSchool(3, 5);
-        school.setName("MTV High");
-        school.getManager().setName("chet");
-        mSchoolDao.insert(school);
-
-        School school2 = TestUtil.createSchool(4, 6);
-        school2.setName("MTV Low");
-        school2.setManager(null);
-        mSchoolDao.insert(school2);
-
-        List<School> schools = loader.call();
-        assertThat(schools.size(), is(2));
-        assertThat(schools.get(0).getName(), is("MTV High"));
-        assertThat(schools.get(1).getName(), is("MTV Low"));
-        assertThat(schools.get(0).address, nullValue());
-        assertThat(schools.get(1).address, nullValue());
-        assertThat(schools.get(0).getManager(), notNullValue());
-        assertThat(schools.get(1).getManager(), nullValue());
-        assertThat(schools.get(0).getManager().getName(), is("chet"));
-    }
-
-    @Test
-    public void loadNestedSub() {
-        School school = TestUtil.createSchool(3, 5);
-        school.getAddress().getCoordinates().lat = 3.;
-        school.getAddress().getCoordinates().lng = 4.;
-        mSchoolDao.insert(school);
-        Coordinates coordinates = mSchoolDao.loadCoordinates(3);
-        assertThat(coordinates.lat, is(3.));
-        assertThat(coordinates.lng, is(4.));
-
-        School asSchool = mSchoolDao.loadCoordinatesAsSchool(3);
-        assertThat(asSchool.address.getCoordinates().lat, is(3.));
-        assertThat(asSchool.address.getCoordinates().lng, is(4.));
-        // didn't as for it so don't load
-        assertThat(asSchool.getManager(), nullValue());
-        assertThat(asSchool.address.getStreet(), nullValue());
-    }
-
-    @Test
-    public void sameFieldType() {
-        Pet male = TestUtil.createPet(3);
-        Pet female = TestUtil.createPet(5);
-        PetCouple petCouple = new PetCouple();
-        petCouple.id = "foo";
-        petCouple.male = male;
-        petCouple.setFemale(female);
-        mPetCoupleDao.insert(petCouple);
-        List<PetCouple> petCouples = mPetCoupleDao.loadAll();
-        assertThat(petCouples.size(), is(1));
-        PetCouple loaded = petCouples.get(0);
-        assertThat(loaded.id, is("foo"));
-        assertThat(loaded.male, is(male));
-        assertThat(loaded.getFemale(), is(female));
-    }
-
-    @Test
-    public void sameFieldOneNull() {
-        Pet loneWolf = TestUtil.createPet(3);
-        PetCouple petCouple = new PetCouple();
-        petCouple.id = "foo";
-        petCouple.male = loneWolf;
-        mPetCoupleDao.insert(petCouple);
-        List<PetCouple> petCouples = mPetCoupleDao.loadAll();
-        assertThat(petCouples.size(), is(1));
-        PetCouple loaded = petCouples.get(0);
-        assertThat(loaded.id, is("foo"));
-        assertThat(loaded.male, is(loneWolf));
-        assertThat(loaded.getFemale(), is(nullValue()));
-    }
-}
diff --git a/room3/integration-tests/testapp/src/androidTest/java/androidx/room3/integration/testapp/test/EntityUpsertionAdapterTest.java b/room3/integration-tests/testapp/src/androidTest/java/androidx/room3/integration/testapp/test/EntityUpsertionAdapterTest.java
deleted file mode 100644
index 8bedc10..0000000
--- a/room3/integration-tests/testapp/src/androidTest/java/androidx/room3/integration/testapp/test/EntityUpsertionAdapterTest.java
+++ /dev/null
@@ -1,326 +0,0 @@
-/*
- * Copyright 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package androidx.room3.integration.testapp.test;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.database.sqlite.SQLiteConstraintException;
-
-import androidx.room3.EntityDeletionOrUpdateAdapter;
-import androidx.room3.EntityInsertionAdapter;
-import androidx.room3.EntityUpsertionAdapter;
-import androidx.room3.Room;
-import androidx.room3.integration.testapp.TestDatabase;
-import androidx.room3.integration.testapp.dao.PetDao;
-import androidx.room3.integration.testapp.dao.ToyDao;
-import androidx.room3.integration.testapp.vo.Pet;
-import androidx.room3.integration.testapp.vo.Toy;
-import androidx.sqlite.db.SupportSQLiteStatement;
-import androidx.test.core.app.ApplicationProvider;
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.test.filters.MediumTest;
-
-import org.jspecify.annotations.NonNull;
-import org.jspecify.annotations.Nullable;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.util.Date;
-import java.util.List;
-import java.util.UUID;
-
-@RunWith(AndroidJUnit4.class)
-@MediumTest
-public class EntityUpsertionAdapterTest{
-    private TestDatabase mTestDatabase;
-    private PetDao mPetDao;
-
-    private ToyDao mToyDao;
-
-    private EntityInsertionAdapter<Pet> mInsertionAdapter;
-
-    private EntityInsertionAdapter<Toy> mInsertionAdapterToy;
-
-    private EntityDeletionOrUpdateAdapter<Pet> mUpdateAdapter;
-
-    private EntityDeletionOrUpdateAdapter<Toy> mUpdateAdapterToy;
-
-    private EntityUpsertionAdapter<Pet> mUpsertionAdapter;
-
-    private EntityUpsertionAdapter<Toy> mUpsertionAdapterToy;
-
-    @Before
-    public void setUp() {
-        mTestDatabase = Room.inMemoryDatabaseBuilder(
-                        ApplicationProvider.getApplicationContext(),
-                        TestDatabase.class).build();
-        mPetDao = mTestDatabase.getPetDao();
-        mInsertionAdapter =
-                new EntityInsertionAdapter<Pet>(mTestDatabase) {
-                    @Override
-                    protected void bind(@Nullable SupportSQLiteStatement statement, Pet entity) {
-                        statement.bindLong(1, entity.getPetId());
-                        statement.bindLong(2, entity.getUserId());
-                        statement.bindString(3, entity.getName());
-                        statement.bindString(4, entity.getAdoptionDate().toString());
-                    }
-
-                    @Override
-                    protected @NonNull String createQuery() {
-                        return "INSERT INTO `Pet` (`mPetId`, `mUserId`, `mPetName`,`mAdoptionDate`)"
-                                + " VALUES (?,?,?,?)";
-                    }
-                };
-        mUpdateAdapter =
-                new EntityDeletionOrUpdateAdapter<Pet>(mTestDatabase) {
-                    @Override
-                    protected @NonNull String createQuery() {
-                        return "UPDATE `Pet` SET `mPetName` = ?, `mAdoptionDate` = ? WHERE `mPetId`"
-                                + " = ?";
-                    }
-
-                    @Override
-                    protected void bind(@NonNull SupportSQLiteStatement statement, Pet entity) {
-                        statement.bindString(1, entity.getName());
-                        statement.bindString(2, entity.getAdoptionDate().toString());
-                        statement.bindLong(3, entity.getPetId());
-                    }
-                };
-        mUpsertionAdapter =
-                new EntityUpsertionAdapter<>(mInsertionAdapter, mUpdateAdapter);
-        mInsertionAdapterToy = new EntityInsertionAdapter<Toy>(mTestDatabase) {
-            @Override
-            protected void bind(@Nullable SupportSQLiteStatement statement, Toy entity) {
-                statement.bindLong(1, entity.getId());
-                statement.bindString(2, entity.getName());
-                statement.bindLong(3, entity.getPetId());
-            }
-
-            @Override
-            protected @NonNull String createQuery() {
-                return "INSERT INTO `TOY` (`mId`, `mName`, `mPetId`)"
-                        + " VALUES (?,?,?)";
-            }
-        };
-
-        mUpdateAdapterToy = new EntityDeletionOrUpdateAdapter<Toy>(mTestDatabase) {
-            @Override
-            protected @NonNull String createQuery() {
-                return "UPDATE `Toy` SET `mName` = ?, `mPetId` = ? WHERE `mId`"
-                        + " = ?";
-            }
-
-            @Override
-            protected void bind(@NonNull SupportSQLiteStatement statement, Toy entity) {
-                statement.bindString(1, entity.getName());
-                statement.bindLong(2, entity.getPetId());
-                statement.bindLong(3, entity.getId());
-            }
-        };
-
-        mUpsertionAdapterToy = new EntityUpsertionAdapter<>(mInsertionAdapterToy,
-                mUpdateAdapterToy);
-    }
-
-    @After
-    public void tearDown() {
-        mTestDatabase.close();
-    }
-
-    @Test
-    public void testUpsert() {
-        Pet newPet = new Pet();
-        Date newDate = new Date(123456);
-        Date testDate = new Date(123458);
-        newPet.setPetId(1);
-        newPet.setName("petname");
-        newPet.setAdoptionDate(newDate);
-
-        Pet testPet = new Pet();
-        testPet.setPetId(1);
-        testPet.setName("anotherName");
-        testPet.setAdoptionDate(testDate);
-
-        mInsertionAdapter.insert(newPet);
-        mUpsertionAdapter.upsert(testPet);
-
-        assertThat(testPet.getName()).isEqualTo(mPetDao.petWithId(1).getName());
-    }
-
-    @Test
-    public void testUpsertList() {
-        Pet[] testPets = TestUtil.createPetsForUser(0, 3, 9);
-        Pet[] petArray = TestUtil.createPetsForUser(0, 1, 10);
-        mInsertionAdapter.insert(petArray);
-        mUpsertionAdapter.upsert(testPets);
-        assertThat(mPetDao.petWithId(2).getName()).isEqualTo(petArray[1].getName());
-        assertThat(mPetDao.petWithId(7).getName()).isEqualTo(testPets[4].getName());
-        assertThat(mPetDao.count()).isEqualTo(11);
-    }
-
-    @Test
-    public void testUpsertReturnId() {
-        Pet testPet = TestUtil.createPet(343562);
-        Pet testPet2 = TestUtil.createPet(343562);
-        long resultId = mUpsertionAdapter.upsertAndReturnId(testPet);
-        long result2 = mUpsertionAdapter.upsertAndReturnId(testPet2);
-        assertThat(resultId).isEqualTo(343562);
-        assertThat(result2).isEqualTo(-1);
-        assertThat(mPetDao.petWithId(343562).getName()).isEqualTo(testPet2.getName());
-    }
-
-    @Test
-    public void testUpsertReturnIds() {
-        Pet[] testPets = TestUtil.createPetsForUser(0, 1, 10);
-        Pet[] testPets2 = TestUtil.createPetsForUser(0, 5, 9);
-        long[] result = mUpsertionAdapter.upsertAndReturnIdsArray(testPets);
-        long[] check = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
-        assertThat(result[3]).isEqualTo(check[3]);
-        long[] testResult = mUpsertionAdapter.upsertAndReturnIdsArray(testPets2);
-        assertThat(testResult[8]).isEqualTo(13);
-        assertThat(testResult[2]).isEqualTo(-1);
-    }
-
-    @Test
-    public void testUpsertReturnList() {
-        Pet[] testPets = TestUtil.createPetsForUser(0, 1, 10);
-        List<Long> result = mUpsertionAdapter.upsertAndReturnIdsList(testPets);
-        assertThat(result.get(3)).isEqualTo(4);
-    }
-
-    @Test
-    public void testInsertReturnBox() {
-        Pet[] testPets = TestUtil.createPetsForUser(0, 1, 10);
-        Long[] result = mInsertionAdapter.insertAndReturnIdsArrayBox(testPets);
-        assertThat(result[3]).isEqualTo(4);
-    }
-
-    @Test
-    public void upsertReturnIdError() {
-        Pet testPet = TestUtil.createPet(232);
-        Toy testToy = new Toy();
-        testToy.setId(1);
-        testToy.setName("toy name");
-        testToy.setPetId(234);
-        mInsertionAdapter.insert(testPet);
-        testPet.setName("change Pet name");
-        mUpsertionAdapter.upsertAndReturnId(testPet);
-        assertThat(mPetDao.petWithId(232).getName()).isEqualTo("change Pet name");
-        try {
-            mUpsertionAdapterToy.upsertAndReturnId(testToy);
-        } catch (SQLiteConstraintException ex) {
-            assertThat(ex.toString()).contains("FOREIGN KEY");
-        }
-    }
-
-    @Test
-    public void upsertFKUnique2067Error() {
-        Pet pet = new Pet();
-        pet.setPetId(232);
-        pet.setName(UUID.randomUUID().toString());
-        pet.setAdoptionDate(new Date());
-        mInsertionAdapter.insert(pet);
-
-        Toy testToy = new Toy();
-        testToy.setId(2);
-        testToy.setName("toy name");
-        testToy.setPetId(232);
-
-        Toy testToy2 = new Toy();
-        testToy2.setId(3);
-        testToy2.setName("toy name");
-        testToy2.setPetId(232);
-
-        mUpsertionAdapter.upsertAndReturnId(pet);
-        mUpsertionAdapterToy.upsertAndReturnId(testToy);
-        try {
-            mUpsertionAdapterToy.upsertAndReturnId(testToy2);
-        } catch (SQLiteConstraintException ex) {
-            assertThat(ex.toString()).contains("2067");
-        }
-    }
-
-    @Test
-    public void testUpsertWithoutTryCatch() {
-        Pet testPet = TestUtil.createPet(232);
-        Pet testPet2 = TestUtil.createPet(232);
-        Pet testPet3 = TestUtil.createPet(454);
-        EntityInsertionAdapter<Pet> insertionAdapter =
-                new EntityInsertionAdapter<Pet>(mTestDatabase) {
-            @Override
-            protected void bind(@Nullable SupportSQLiteStatement statement, Pet entity) {
-                statement.bindLong(1, entity.getPetId());
-                statement.bindLong(2, entity.getUserId());
-                statement.bindString(3, entity.getName());
-                statement.bindString(4, entity.getAdoptionDate().toString());
-            }
-
-            @Override
-            protected @NonNull String createQuery() {
-                return "INSERT OR IGNORE INTO `Pet` (`mPetId`, `mUserId`, `mPetName`,"
-                        + "`mAdoptionDate`)"
-                        + " VALUES (?,?,?,?)";
-            }
-        };
-        insertionAdapter.insertAndReturnId(testPet);
-        long result = insertionAdapter.insertAndReturnId(testPet2);
-        if (result == -1) {
-            mUpdateAdapter.handle(testPet2);
-        }
-        insertionAdapter.insertAndReturnId(testPet3);
-        assertThat(mPetDao.count()).isEqualTo(2);
-        assertThat(mPetDao.petWithId(232).getName()).isEqualTo(testPet2.getName());
-    }
-
-    @Test
-    public void testUpsertWithMultipleEntity() {
-        Pet[] testPets = TestUtil.createPetsForUser(0, 1, 10);
-        Pet[] testPets2 = TestUtil.createPetsForUser(0, 5, 10);
-        long[] resultArray;
-        long[] resultArray2 = new long[10];
-        EntityInsertionAdapter<Pet> insertionAdapter =
-                new EntityInsertionAdapter<Pet>(mTestDatabase) {
-                    @Override
-                    protected void bind(@Nullable SupportSQLiteStatement statement, Pet entity) {
-                        statement.bindLong(1, entity.getPetId());
-                        statement.bindLong(2, entity.getUserId());
-                        statement.bindString(3, entity.getName());
-                        statement.bindString(4, entity.getAdoptionDate().toString());
-                    }
-
-                    @Override
-                    protected @NonNull String createQuery() {
-                        return "INSERT OR IGNORE INTO `Pet` (`mPetId`, `mUserId`, `mPetName`,"
-                                + "`mAdoptionDate`)"
-                                + " VALUES (?,?,?,?)";
-                    }
-                };
-        resultArray = insertionAdapter.insertAndReturnIdsArray(testPets);
-        assertThat(resultArray[4]).isEqualTo(5);
-        for (int i = 0; i < 10; i++) {
-            resultArray2[i] = insertionAdapter.insertAndReturnId(testPets2[i]);
-            if (resultArray2[i] == -1) {
-                mUpdateAdapter.handle(testPets2[i]);
-            }
-        }
-        assertThat(resultArray2[4]).isEqualTo(-1);
-        assertThat(resultArray2[7]).isEqualTo(12);
-        assertThat(mPetDao.petWithId(6).getName()).isEqualTo(testPets2[1].getName());
-    }
-}
diff --git a/room3/integration-tests/testapp/src/androidTest/java/androidx/room3/integration/testapp/test/EnumColumnTypeAdapterTest.java b/room3/integration-tests/testapp/src/androidTest/java/androidx/room3/integration/testapp/test/EnumColumnTypeAdapterTest.java
deleted file mode 100644
index 115a191..0000000
--- a/room3/integration-tests/testapp/src/androidTest/java/androidx/room3/integration/testapp/test/EnumColumnTypeAdapterTest.java
+++ /dev/null
@@ -1,178 +0,0 @@
-/*
- * Copyright 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package androidx.room3.integration.testapp.test;
-
-import static org.hamcrest.CoreMatchers.equalTo;
-import static org.hamcrest.CoreMatchers.is;
-import static org.hamcrest.MatcherAssert.assertThat;
-
-import android.content.Context;
-
-import androidx.room3.Dao;
-import androidx.room3.Database;
-import androidx.room3.Entity;
-import androidx.room3.PrimaryKey;
-import androidx.room3.Query;
-import androidx.room3.Room;
-import androidx.room3.RoomDatabase;
-import androidx.room3.TypeConverter;
-import androidx.room3.TypeConverters;
-import androidx.test.core.app.ApplicationProvider;
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.test.filters.SmallTest;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-@SmallTest
-@RunWith(AndroidJUnit4.class)
-public class EnumColumnTypeAdapterTest {
-
-    private EnumColumnTypeAdapterDatabase mDb;
-
-    @Entity
-    public static class EntityWithEnum {
-        @PrimaryKey
-        public Long id;
-        public Fruit fruit;
-    }
-
-    @Entity
-    public static class EntityWithOneWayEnum {
-        @PrimaryKey
-        public Long id;
-        public Color color;
-    }
-
-    @Entity
-    public static class ComplexEntityWithEnum {
-        @PrimaryKey
-        public Long id;
-        public Season mSeason;
-    }
-
-    public enum Color {
-        RED,
-        GREEN
-    }
-
-    public enum Fruit {
-        BANANA,
-        STRAWBERRY,
-        WILDBERRY
-    }
-
-    public enum Season {
-        SUMMER("Sunny"),
-        SPRING("Warm"),
-        WINTER("Cold"),
-        AUTUMN("Rainy");
-
-        private final String mSeason;
-
-        Season(String mSeason) {
-            this.mSeason = mSeason;
-        }
-    }
-
-    @Dao
-    public interface SampleDao {
-        @Query("INSERT INTO EntityWithEnum (id, fruit) VALUES (:id, :fruit)")
-        long insert(long id, Fruit fruit);
-
-        @Query("SELECT * FROM EntityWithEnum WHERE id = :id")
-        EntityWithEnum getValueWithId(long id);
-    }
-
-    @Dao
-    public interface SampleDaoWithOneWayConverter {
-        @Query("INSERT INTO EntityWithOneWayEnum (id, color) VALUES (:id, :colorInt)")
-        long insert(long id, int colorInt);
-
-        @Query("SELECT * FROM EntityWithOneWayEnum WHERE id = :id")
-        EntityWithOneWayEnum getValueWithId(long id);
-    }
-
-    public static class ColorTypeConverter {
-        @TypeConverter
-        public Color fromIntToColorEnum(int colorInt) {
-            if (colorInt == 1) {
-                return Color.RED;
-            } else {
-                return Color.GREEN;
-            }
-        }
-    }
-
-    @Dao
-    public interface SampleDaoWithComplexEnum {
-        @Query("INSERT INTO ComplexEntityWithEnum (id, mSeason) VALUES (:id, :season)")
-        long insertComplex(long id, Season season);
-
-        @Query("SELECT * FROM ComplexEntityWithEnum WHERE id = :id")
-        ComplexEntityWithEnum getComplexValueWithId(long id);
-    }
-
-    @Database(entities = {EntityWithEnum.class, ComplexEntityWithEnum.class,
-            EntityWithOneWayEnum.class}, version = 1,
-            exportSchema = false)
-    @TypeConverters(ColorTypeConverter.class)
-    public abstract static class EnumColumnTypeAdapterDatabase extends RoomDatabase {
-        public abstract EnumColumnTypeAdapterTest.SampleDao dao();
-        public abstract EnumColumnTypeAdapterTest.SampleDaoWithOneWayConverter oneWayDao();
-        public abstract EnumColumnTypeAdapterTest.SampleDaoWithComplexEnum complexDao();
-    }
-
-    @Before
-    public void initDb() {
-        Context context = ApplicationProvider.getApplicationContext();
-        mDb = Room.inMemoryDatabaseBuilder(
-                context,
-                EnumColumnTypeAdapterDatabase.class)
-                .build();
-    }
-
-    @After
-    public void teardown() {
-        mDb.close();
-    }
-
-    @Test
-    public void readAndWriteEnumToDatabase() {
-        final long id1 = mDb.dao().insert(1, Fruit.BANANA);
-        final long id2 = mDb.dao().insert(2, Fruit.STRAWBERRY);
-
-        assertThat(mDb.dao().getValueWithId(1).fruit, is(equalTo(Fruit.BANANA)));
-        assertThat(mDb.dao().getValueWithId(2).fruit, is(equalTo(Fruit.STRAWBERRY)));
-    }
-
-    @Test
-    public void writeOneWayEnumToDatabase() {
-        final long id2 = mDb.oneWayDao().insert(1, 1);
-        assertThat(mDb.oneWayDao().getValueWithId(1).color, is(equalTo(Color.RED)));
-
-    }
-
-    @Test
-    public void filterOutComplexEnumTest() {
-        final long id1 = mDb.complexDao().insertComplex(1, Season.AUTUMN);
-        assertThat(mDb.complexDao().getComplexValueWithId(1).mSeason,
-                is(equalTo(Season.AUTUMN)));
-    }
-}
diff --git a/room3/integration-tests/testapp/src/androidTest/java/androidx/room3/integration/testapp/test/ForeignKeyTest.java b/room3/integration-tests/testapp/src/androidTest/java/androidx/room3/integration/testapp/test/ForeignKeyTest.java
deleted file mode 100644
index d6eecf4..0000000
--- a/room3/integration-tests/testapp/src/androidTest/java/androidx/room3/integration/testapp/test/ForeignKeyTest.java
+++ /dev/null
@@ -1,437 +0,0 @@
-/*
- * Copyright (C) 2017 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 androidx.room3.integration.testapp.test;
-
-import static org.hamcrest.CoreMatchers.both;
-import static org.hamcrest.CoreMatchers.containsString;
-import static org.hamcrest.CoreMatchers.either;
-import static org.hamcrest.CoreMatchers.equalTo;
-import static org.hamcrest.CoreMatchers.instanceOf;
-import static org.hamcrest.CoreMatchers.notNullValue;
-import static org.hamcrest.CoreMatchers.nullValue;
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.hamcrest.core.Is.is;
-
-import android.database.sqlite.SQLiteException;
-
-import androidx.room3.Dao;
-import androidx.room3.Database;
-import androidx.room3.Delete;
-import androidx.room3.Entity;
-import androidx.room3.ForeignKey;
-import androidx.room3.Ignore;
-import androidx.room3.Index;
-import androidx.room3.Insert;
-import androidx.room3.PrimaryKey;
-import androidx.room3.Query;
-import androidx.room3.Room;
-import androidx.room3.RoomDatabase;
-import androidx.test.core.app.ApplicationProvider;
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.test.filters.SmallTest;
-
-import org.hamcrest.Matcher;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.util.Locale;
-
-@RunWith(AndroidJUnit4.class)
-@SmallTest
-public class ForeignKeyTest {
-    @Database(version = 1, entities = {A.class, B.class, C.class, D.class, E.class},
-            exportSchema = false)
-    abstract static class ForeignKeyDb extends RoomDatabase {
-        abstract FkDao dao();
-    }
-
-    @SuppressWarnings({"SqlNoDataSourceInspection", "SameParameterValue"})
-    @Dao
-    interface FkDao {
-        @Insert
-        void insert(A... a);
-
-        @Insert
-        void insert(B... b);
-
-        @Insert
-        void insert(C... c);
-
-        @Insert
-        void insert(D... d);
-
-        @Query("SELECT * FROM A WHERE id = :id")
-        A loadA(int id);
-
-        @Query("SELECT * FROM B WHERE id = :id")
-        B loadB(int id);
-
-        @Query("SELECT * FROM C WHERE id = :id")
-        C loadC(int id);
-
-        @Query("SELECT * FROM D WHERE id = :id")
-        D loadD(int id);
-
-        @Query("SELECT * FROM E WHERE id = :id")
-        E loadE(int id);
-
-        @Delete
-        void delete(A... a);
-
-        @Delete
-        void delete(B... b);
-
-        @Delete
-        void delete(C... c);
-
-        @Query("UPDATE A SET name = :newName WHERE id = :id")
-        void changeNameA(int id, String newName);
-
-        @Insert
-        void insert(E... e);
-
-
-    }
-
-    @Entity(indices = {@Index(value = "name", unique = true),
-            @Index(value = {"name", "lastName"}, unique = true)})
-    static class A {
-        @PrimaryKey(autoGenerate = true)
-        public int id;
-        public String name;
-        public String lastName;
-
-        A(String name) {
-            this.name = name;
-        }
-
-        @Ignore
-        A(String name, String lastName) {
-            this.name = name;
-            this.lastName = lastName;
-        }
-    }
-
-    @SuppressWarnings("WeakerAccess")
-    @Entity(foreignKeys = {
-            @ForeignKey(entity = A.class,
-                    parentColumns = "name",
-                    childColumns = "aName")},
-            indices = {@Index("aName")})
-    static class B {
-        @PrimaryKey(autoGenerate = true)
-        public int id;
-        public String aName;
-
-        B(String aName) {
-            this.aName = aName;
-        }
-    }
-
-    @SuppressWarnings("WeakerAccess")
-    @Entity(foreignKeys = {
-            @ForeignKey(entity = A.class,
-                    parentColumns = "name",
-                    childColumns = "aName",
-                    deferred = true)},
-            indices = {@Index("aName")})
-    static class C {
-        @PrimaryKey(autoGenerate = true)
-        public int id;
-        public String aName;
-
-        C(String aName) {
-            this.aName = aName;
-        }
-    }
-
-    @SuppressWarnings("WeakerAccess")
-    @Entity(foreignKeys = {
-            @ForeignKey(entity = A.class,
-                    parentColumns = "name",
-                    childColumns = "aName",
-                    onDelete = ForeignKey.CASCADE,
-                    onUpdate = ForeignKey.CASCADE)},
-            indices = {@Index("aName")})
-    static class D {
-        @PrimaryKey(autoGenerate = true)
-        public int id;
-        public String aName;
-
-        D(String aName) {
-            this.aName = aName;
-        }
-    }
-
-    @SuppressWarnings("WeakerAccess")
-    @Entity(foreignKeys = {
-            @ForeignKey(entity = A.class,
-                    parentColumns = {"name", "lastName"},
-                    childColumns = {"aName", "aLastName"},
-                    onDelete = ForeignKey.SET_NULL,
-                    onUpdate = ForeignKey.CASCADE)},
-            indices = {@Index({"aName", "aLastName"})})
-    static class E {
-        @PrimaryKey(autoGenerate = true)
-        public int id;
-        public String aName;
-        public String aLastName;
-
-        E() {
-        }
-
-        @Ignore
-        E(String aName, String aLastName) {
-            this.aName = aName;
-            this.aLastName = aLastName;
-        }
-    }
-
-
-    private ForeignKeyDb mDb;
-    private FkDao mDao;
-
-    @Before
-    public void openDb() {
-        mDb = Room.inMemoryDatabaseBuilder(ApplicationProvider.getApplicationContext(),
-                ForeignKeyDb.class).build();
-        mDao = mDb.dao();
-    }
-
-    @After
-    public void closeDb() {
-        mDb.close();
-    }
-
-    @Test
-    public void simpleForeignKeyFailure() {
-        Throwable t = catchException(new ThrowingRunnable() {
-            @Override
-            public void run() throws Exception {
-                mDao.insert(new B("foo"));
-            }
-        });
-        assertThat(t, instanceOf(SQLiteException.class));
-        assertThat(t.getMessage().toUpperCase(Locale.US), is(foreignKeyErrorMessage()));
-    }
-
-    @Test
-    public void simpleForeignKeyDeferredFailure() {
-        Throwable t = catchException(new ThrowingRunnable() {
-            @Override
-            public void run() throws Exception {
-                mDao.insert(new C("foo"));
-            }
-        });
-        assertThat(t, instanceOf(SQLiteException.class));
-        assertThat(t.getMessage().toUpperCase(Locale.US), is(foreignKeyErrorMessage()));
-    }
-
-    @Test
-    public void immediateForeignKeyFailure() {
-        Throwable t = catchException(new ThrowingRunnable() {
-            @SuppressWarnings("deprecation")
-            @Override
-            public void run() throws Exception {
-                try {
-                    mDb.beginTransaction();
-                    mDao.insert(new B("foo"));
-                    mDao.insert(new A("foo"));
-                    mDb.setTransactionSuccessful();
-                } finally {
-                    mDb.endTransaction();
-                }
-            }
-        });
-        assertThat(t, instanceOf(SQLiteException.class));
-    }
-
-    @SuppressWarnings("deprecation")
-    @Test
-    public void deferredForeignKeySuccess() {
-        try {
-            mDb.beginTransaction();
-            mDao.insert(new C("foo"));
-            mDao.insert(new A("foo"));
-            mDb.setTransactionSuccessful();
-        } finally {
-            mDb.endTransaction();
-        }
-        assertThat(mDao.loadA(1), notNullValue());
-        assertThat(mDao.loadC(1), notNullValue());
-    }
-
-    @Test
-    public void onDelete_noAction() {
-        mDao.insert(new A("a1"));
-        final A a = mDao.loadA(1);
-        mDao.insert(new B("a1"));
-        Throwable t = catchException(new ThrowingRunnable() {
-            @Override
-            public void run() throws Exception {
-                mDao.delete(a);
-            }
-        });
-        assertThat(t, instanceOf(SQLiteException.class));
-        assertThat(t.getMessage().toUpperCase(Locale.US), is(foreignKeyErrorMessage()));
-    }
-
-    @Test
-    public void onDelete_noAction_withTransaction() {
-        mDao.insert(new A("a1"));
-        final A a = mDao.loadA(1);
-        mDao.insert(new B("a1"));
-        final B b = mDao.loadB(1);
-        Throwable t = catchException(new ThrowingRunnable() {
-            @Override
-            public void run() throws Exception {
-                deleteInTransaction(a, b);
-            }
-        });
-        assertThat(t, instanceOf(SQLiteException.class));
-        assertThat(t.getMessage().toUpperCase(Locale.US), is(foreignKeyErrorMessage()));
-    }
-
-    @Test
-    public void onDelete_noAction_deferred() {
-        mDao.insert(new A("a1"));
-        final A a = mDao.loadA(1);
-        mDao.insert(new C("a1"));
-        Throwable t = catchException(new ThrowingRunnable() {
-            @Override
-            public void run() throws Exception {
-                mDao.delete(a);
-            }
-        });
-        assertThat(t, instanceOf(SQLiteException.class));
-        assertThat(t.getMessage().toUpperCase(Locale.US), is(foreignKeyErrorMessage()));
-    }
-
-    @Test
-    public void onDelete_noAction__deferredWithTransaction() {
-        mDao.insert(new A("a1"));
-        final A a = mDao.loadA(1);
-        mDao.insert(new C("a1"));
-        final C c = mDao.loadC(1);
-        deleteInTransaction(a, c);
-    }
-
-    @Test
-    public void onDelete_cascade() {
-        mDao.insert(new A("a1"));
-        final A a = mDao.loadA(1);
-        mDao.insert(new D("a1"));
-        final D d = mDao.loadD(1);
-        assertThat("test sanity", d, notNullValue());
-        mDao.delete(a);
-        assertThat(mDao.loadD(1), nullValue());
-    }
-
-    @Test
-    public void onUpdate_cascade() {
-        mDao.insert(new A("a1"));
-        mDao.insert(new D("a1"));
-        final D d = mDao.loadD(1);
-        assertThat("test sanity", d, notNullValue());
-        mDao.changeNameA(1, "bla");
-        assertThat(mDao.loadD(1).aName, equalTo("bla"));
-        assertThat(mDao.loadA(1).name, equalTo("bla"));
-    }
-
-    @Test
-    public void multipleReferences() {
-        mDao.insert(new A("a1", "a2"));
-        final A a = mDao.loadA(1);
-        assertThat("test sanity", a, notNullValue());
-        Throwable t = catchException(new ThrowingRunnable() {
-            @Override
-            public void run() throws Exception {
-                mDao.insert(new E("a1", "dsa"));
-            }
-        });
-        assertThat(t.getMessage().toUpperCase(Locale.US), is(foreignKeyErrorMessage()));
-    }
-
-    @Test
-    public void onDelete_setNull_multipleReferences() {
-        mDao.insert(new A("a1", "a2"));
-        final A a = mDao.loadA(1);
-        mDao.insert(new E("a1", "a2"));
-        assertThat(mDao.loadE(1), notNullValue());
-        mDao.delete(a);
-        E e = mDao.loadE(1);
-        assertThat(e, notNullValue());
-        assertThat(e.aName, nullValue());
-        assertThat(e.aLastName, nullValue());
-    }
-
-    @Test
-    public void onUpdate_cascade_multipleReferences() {
-        mDao.insert(new A("a1", "a2"));
-        final A a = mDao.loadA(1);
-        mDao.insert(new E("a1", "a2"));
-        assertThat(mDao.loadE(1), notNullValue());
-        mDao.changeNameA(1, "foo");
-        assertThat(mDao.loadE(1), notNullValue());
-        assertThat(mDao.loadE(1).aName, equalTo("foo"));
-        assertThat(mDao.loadE(1).aLastName, equalTo("a2"));
-    }
-
-    private static Matcher<String> foreignKeyErrorMessage() {
-        return either(containsString("FOREIGN KEY"))
-                .or(both(containsString("CODE 19")).and(containsString("CONSTRAINT FAILED")));
-    }
-
-    @SuppressWarnings({"Duplicates", "deprecation"})
-    private void deleteInTransaction(A a, B b) {
-        mDb.beginTransaction();
-        try {
-            mDao.delete(a);
-            mDao.delete(b);
-            mDb.setTransactionSuccessful();
-        } finally {
-            mDb.endTransaction();
-        }
-    }
-
-    @SuppressWarnings({"Duplicates", "deprecation"})
-    private void deleteInTransaction(A a, C c) {
-        mDb.beginTransaction();
-        try {
-            mDao.delete(a);
-            mDao.delete(c);
-            mDb.setTransactionSuccessful();
-        } finally {
-            mDb.endTransaction();
-        }
-    }
-
-    private static Throwable catchException(ThrowingRunnable throwingRunnable) {
-        try {
-            throwingRunnable.run();
-        } catch (Throwable t) {
-            return t;
-        }
-        throw new RuntimeException("didn't throw an exception");
-    }
-
-    private interface ThrowingRunnable {
-        void run() throws Exception;
-    }
-}
diff --git a/room3/integration-tests/testapp/src/androidTest/java/androidx/room3/integration/testapp/test/FtsTableTest.java b/room3/integration-tests/testapp/src/androidTest/java/androidx/room3/integration/testapp/test/FtsTableTest.java
deleted file mode 100644
index 729be1d..0000000
--- a/room3/integration-tests/testapp/src/androidTest/java/androidx/room3/integration/testapp/test/FtsTableTest.java
+++ /dev/null
@@ -1,271 +0,0 @@
-/*
- * Copyright 2018 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 androidx.room3.integration.testapp.test;
-
-import static org.hamcrest.CoreMatchers.is;
-import static org.hamcrest.MatcherAssert.assertThat;
-
-import android.content.Context;
-
-import androidx.room3.Room;
-import androidx.room3.integration.testapp.FtsTestDatabase;
-import androidx.room3.integration.testapp.dao.MailDao;
-import androidx.room3.integration.testapp.dao.SongDao;
-import androidx.room3.integration.testapp.vo.Mail;
-import androidx.room3.integration.testapp.vo.Song;
-import androidx.room3.integration.testapp.vo.SongDescription;
-import androidx.test.core.app.ApplicationProvider;
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.test.filters.SmallTest;
-
-import com.google.common.collect.Lists;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.util.List;
-
-@RunWith(AndroidJUnit4.class)
-@SmallTest
-public class FtsTableTest {
-
-    private FtsTestDatabase mDatabase;
-    private MailDao mMailDao;
-    private SongDao mSongDao;
-
-    @Before
-    public void setup() {
-        Context context = ApplicationProvider.getApplicationContext();
-        mDatabase = Room.inMemoryDatabaseBuilder(context, FtsTestDatabase.class).build();
-        mMailDao = mDatabase.getMailDao();
-        mSongDao = mDatabase.getSongDao();
-    }
-
-    @After
-    public void teardown() {
-        mDatabase.close();
-    }
-
-    @Test
-    public void readWrite() {
-        Mail item = TestUtil.createMail(1,
-                "Hello old friend",
-                "How are you? Wanna grab coffee?");
-
-        mMailDao.insert(item);
-
-        List<Mail> loaded = mMailDao.getMail("coffee");
-        assertThat(loaded.get(0), is(item));
-    }
-
-    @Test
-    public void prefixQuery() {
-        Mail item1 = TestUtil.createMail(1,
-                "Linux problem",
-                "Hi - Need help with my linux machine.");
-
-        Mail item2 = TestUtil.createMail(2,
-                "Math help needed",
-                "Anyone able to help me with linear algebra?");
-
-        Mail item3 = TestUtil.createMail(3,
-                "Chef needed",
-                "Need a cheeseburger check ASAP");
-
-        mMailDao.insert(Lists.newArrayList(item1, item2, item3));
-
-        List<Mail> loaded = mMailDao.getMail("lin*");
-        assertThat(loaded.size(), is(2));
-        assertThat(loaded.get(0), is(item1));
-        assertThat(loaded.get(1), is(item2));
-    }
-
-    @Test
-    public void prefixQuery_multiple() {
-        Mail item1 = TestUtil.createMail(1,
-                "Linux problem",
-                "Hi - Need help with my linux machine.");
-
-        Mail item2 = TestUtil.createMail(2,
-                "Math help needed",
-                "Anyone able to help me with linear algebra?");
-
-        Mail item3 = TestUtil.createMail(3,
-                "Chef needed",
-                "Need a cheeseburger check ASAP");
-
-        mMailDao.insert(Lists.newArrayList(item1, item2, item3));
-
-        List<Mail> loaded = mMailDao.getMail("help linux");
-        assertThat(loaded.size(), is(1));
-        assertThat(loaded.get(0), is(item1));
-    }
-
-    @Test
-    public void prefixQuery_multiple_OR() {
-        Mail item1 = TestUtil.createMail(1,
-                "Linux problem",
-                "Hi - Need help with my linux machine.");
-
-        Mail item2 = TestUtil.createMail(2,
-                "Math help needed",
-                "Anyone able to help me with linear algebra?");
-
-        Mail item3 = TestUtil.createMail(3,
-                "Chef needed",
-                "Need a cheeseburger check ASAP");
-
-        mMailDao.insert(Lists.newArrayList(item1, item2, item3));
-
-        List<Mail> loaded = mMailDao.getMail("linux OR linear");
-        assertThat(loaded.size(), is(2));
-        assertThat(loaded.get(0), is(item1));
-        assertThat(loaded.get(1), is(item2));
-    }
-
-    @Test
-    public void prefixQuery_body() {
-        Mail item1 = TestUtil.createMail(1,
-                "Linux problem",
-                "Hi - Need help with my linux machine.");
-
-        Mail item2 = TestUtil.createMail(2,
-                "Math help needed",
-                "Anyone able to help me with linear algebra?");
-
-        Mail item3 = TestUtil.createMail(3,
-                "Chef needed",
-                "Need a cheeseburger check ASAP");
-
-        mMailDao.insert(Lists.newArrayList(item1, item2, item3));
-
-        List<Mail> loaded = mMailDao.getMailWithBody("subject:help algebra");
-        assertThat(loaded.size(), is(1));
-        assertThat(loaded.get(0), is(item2));
-    }
-
-    @Test
-    public void prefixQuery_startsWith() {
-        Mail item = TestUtil.createMail(1,
-                "Hello old friend",
-                "How are you? Wanna grab coffee?");
-
-        mMailDao.insert(item);
-
-        List<Mail> loaded = mMailDao.getMailWithSubject("^hello");
-        assertThat(loaded.get(0), is(item));
-    }
-
-    @Test
-    public void phraseQuery() {
-        Mail item1 = TestUtil.createMail(1,
-                "Linux problem",
-                "Hi - Need help with my linux machine.");
-        Mail item2 = TestUtil.createMail(2,
-                "Math help needed",
-                "Anyone able to help me with linear algebra?");
-
-        mMailDao.insert(Lists.newArrayList(item1, item2));
-
-        List<Mail> loaded = mMailDao.getMail("\"help me\"");
-        assertThat(loaded.size(), is(1));
-        assertThat(loaded.get(0), is(item2));
-    }
-
-    @Test
-    public void nearQuery() {
-        Mail item = TestUtil.createMail(1,
-                "Hello old friend",
-                "How are you? Wanna grab coffee?");
-
-        mMailDao.insert(item);
-
-        List<Mail> loaded = mMailDao.getMail("coffee");
-        assertThat(loaded.get(0), is(item));
-    }
-
-    @Test
-    public void snippetQuery() {
-        Mail item1 = TestUtil.createMail(1,
-                "Linux problem",
-                "Hi - Need help with my linux machine.");
-
-        Mail item2 = TestUtil.createMail(2,
-                "Math help needed",
-                "Hello dear friends. I am in desperate need for some help. "
-                        + "I've taken a lot of tutorials online but I still don't understand. "
-                        + "Is anyone available to please help with some linear algebra?");
-        mMailDao.insert(Lists.newArrayList(item1, item2));
-
-        List<String> loaded = mMailDao.getMailBodySnippets("help");
-        assertThat(loaded.size(), is(2));
-        assertThat(loaded.get(0), is("Hi - Need <b>help</b> with my linux machine."));
-        assertThat(loaded.get(1), is("<b>...</b>I am in desperate need for some <b>help</b>."
-                + " I've taken a lot of tutorials<b>...</b>"));
-    }
-
-    @Test
-    public void specialCommand_optimize() {
-        Mail item = TestUtil.createMail(1,
-                "Hello old friend",
-                "How are you? Wanna grab coffee?");
-
-        mMailDao.insert(item);
-        mMailDao.optimizeMail();
-    }
-
-    @Test
-    public void specialCommand_rebuild() {
-        Mail item = TestUtil.createMail(1,
-                "Hello old friend",
-                "How are you? Wanna grab coffee?");
-
-        mMailDao.insert(item);
-        mMailDao.rebuildMail();
-    }
-
-    @Test
-    public void externalContent() {
-        Song item1 = new Song(
-                1,
-                "Solos (Remix)",
-                "Plan B",
-                "Solos",
-                225,
-                2009);
-
-        Song item2 = new Song(
-                2,
-                "La Barría",
-                "Wisin & Yandel",
-                "Pa'l Mundo",
-                177,
-                2005);
-
-        mSongDao.insert(Lists.newArrayList(item1, item2));
-
-        List<SongDescription> descLoaded = mSongDao.getSongDescriptions("remix");
-        assertThat(descLoaded.size(), is(1));
-        assertThat(descLoaded.get(0).mTitle, is(item1.mTitle));
-
-        List<Song> songLoaded = mSongDao.getSongs("remix");
-        assertThat(songLoaded.size(), is(1));
-        assertThat(songLoaded.get(0), is(item1));
-    }
-}
diff --git a/room3/integration-tests/testapp/src/androidTest/java/androidx/room3/integration/testapp/test/FunnyNamedDaoTest.java b/room3/integration-tests/testapp/src/androidTest/java/androidx/room3/integration/testapp/test/FunnyNamedDaoTest.java
deleted file mode 100644
index 01beaa3..0000000
--- a/room3/integration-tests/testapp/src/androidTest/java/androidx/room3/integration/testapp/test/FunnyNamedDaoTest.java
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Copyright (C) 2017 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 androidx.room3.integration.testapp.test;
-
-import static org.hamcrest.CoreMatchers.is;
-import static org.hamcrest.CoreMatchers.notNullValue;
-import static org.hamcrest.CoreMatchers.nullValue;
-import static org.hamcrest.MatcherAssert.assertThat;
-
-import androidx.arch.core.executor.testing.CountingTaskExecutorRule;
-import androidx.room3.integration.testapp.vo.FunnyNamedEntity;
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.test.filters.SmallTest;
-import androidx.test.platform.app.InstrumentationRegistry;
-
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.TimeoutException;
-
-@RunWith(AndroidJUnit4.class)
-@SmallTest
-public class FunnyNamedDaoTest extends TestDatabaseTest {
-    @Rule
-    public CountingTaskExecutorRule mExecutorRule = new CountingTaskExecutorRule();
-
-    @Test
-    public void readWrite() {
-        FunnyNamedEntity entity = new FunnyNamedEntity(1, "a");
-        mFunnyNamedDao.insert(entity);
-        FunnyNamedEntity loaded = mFunnyNamedDao.load(1);
-        assertThat(loaded, is(entity));
-    }
-
-    @Test
-    public void update() {
-        FunnyNamedEntity entity = new FunnyNamedEntity(1, "a");
-        mFunnyNamedDao.insert(entity);
-        entity.setValue("b");
-        mFunnyNamedDao.update(entity);
-        FunnyNamedEntity loaded = mFunnyNamedDao.load(1);
-        assertThat(loaded.getValue(), is("b"));
-    }
-
-    @Test
-    public void delete() {
-        FunnyNamedEntity entity = new FunnyNamedEntity(1, "a");
-        mFunnyNamedDao.insert(entity);
-        assertThat(mFunnyNamedDao.load(1), notNullValue());
-        mFunnyNamedDao.delete(entity);
-        assertThat(mFunnyNamedDao.load(1), nullValue());
-    }
-
-    @Test
-    public void observe() throws TimeoutException, InterruptedException {
-        final FunnyNamedEntity[] item = new FunnyNamedEntity[1];
-        InstrumentationRegistry.getInstrumentation().runOnMainSync(
-                () -> mFunnyNamedDao.observableOne(2).observeForever(
-                        funnyNamedEntity -> item[0] = funnyNamedEntity));
-
-        FunnyNamedEntity entity = new FunnyNamedEntity(1, "a");
-        mFunnyNamedDao.insert(entity);
-        mExecutorRule.drainTasks(1, TimeUnit.MINUTES);
-        assertThat(item[0], nullValue());
-
-        final FunnyNamedEntity entity2 = new FunnyNamedEntity(2, "b");
-        mFunnyNamedDao.insert(entity2);
-        mExecutorRule.drainTasks(1, TimeUnit.MINUTES);
-        assertThat(item[0], is(entity2));
-
-        final FunnyNamedEntity entity3 = new FunnyNamedEntity(2, "c");
-        mFunnyNamedDao.update(entity3);
-        mExecutorRule.drainTasks(1, TimeUnit.MINUTES);
-        assertThat(item[0], is(entity3));
-    }
-}
diff --git a/room3/integration-tests/testapp/src/androidTest/java/androidx/room3/integration/testapp/test/GenericEntityTest.java b/room3/integration-tests/testapp/src/androidTest/java/androidx/room3/integration/testapp/test/GenericEntityTest.java
deleted file mode 100644
index 3187419..0000000
--- a/room3/integration-tests/testapp/src/androidTest/java/androidx/room3/integration/testapp/test/GenericEntityTest.java
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
- * Copyright 2018 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 androidx.room3.integration.testapp.test;
-
-import static org.hamcrest.CoreMatchers.is;
-import static org.hamcrest.MatcherAssert.assertThat;
-
-import androidx.room3.Dao;
-import androidx.room3.Database;
-import androidx.room3.Entity;
-import androidx.room3.Insert;
-import androidx.room3.PrimaryKey;
-import androidx.room3.Query;
-import androidx.room3.Room;
-import androidx.room3.RoomDatabase;
-import androidx.test.core.app.ApplicationProvider;
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.test.filters.SmallTest;
-
-import org.jspecify.annotations.NonNull;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-@RunWith(AndroidJUnit4.class)
-@SmallTest
-public class GenericEntityTest {
-    private GenericDb mDb;
-    private GenericDao mDao;
-
-    @Before
-    public void init() {
-        mDb = Room.inMemoryDatabaseBuilder(
-                ApplicationProvider.getApplicationContext(),
-                GenericDb.class
-        ).build();
-        mDao = mDb.getDao();
-    }
-
-    @After
-    public void close() {
-        mDb.close();
-    }
-
-    @Test
-    public void readWriteEntity() {
-        EntityItem item = new EntityItem("abc", "def");
-        mDao.insert(item);
-        EntityItem received = mDao.get("abc");
-        assertThat(received, is(item));
-    }
-
-    @Test
-    public void readPojo() {
-        EntityItem item = new EntityItem("abc", "def");
-        mDao.insert(item);
-        PojoItem received = mDao.getPojo("abc");
-        assertThat(received.id, is("abc"));
-    }
-
-    static class Item<P, F> {
-        @PrimaryKey
-        // This project is tested against a version of the room compiler that doesn't recognize
-        // JSpecify for primary keys
-        @SuppressWarnings("JSpecifyNullness")
-        @androidx.annotation.NonNull
-        public final P id;
-        private F mField;
-
-        Item(@NonNull P id) {
-            this.id = id;
-        }
-
-        public F getField() {
-            return mField;
-        }
-
-        public void setField(F field) {
-            mField = field;
-        }
-
-        @Override
-        public boolean equals(Object o) {
-            if (this == o) return true;
-            if (o == null || getClass() != o.getClass()) return false;
-            Item<?, ?> item = (Item<?, ?>) o;
-            //noinspection SimplifiableIfStatement
-            if (!id.equals(item.id)) return false;
-            return mField != null ? mField.equals(item.mField) : item.mField == null;
-        }
-
-        @Override
-        public int hashCode() {
-            int result = id.hashCode();
-            result = 31 * result + (mField != null ? mField.hashCode() : 0);
-            return result;
-        }
-    }
-
-    static class PojoItem extends Item<String, Integer> {
-        PojoItem(String id) {
-            super(id);
-        }
-    }
-
-    @Entity
-    static class EntityItem extends Item<String, Integer> {
-        public final String name;
-
-        EntityItem(String id, String name) {
-            super(id);
-            this.name = name;
-        }
-
-        @Override
-        public boolean equals(Object o) {
-            if (this == o) return true;
-            if (o == null || getClass() != o.getClass()) return false;
-            if (!super.equals(o)) return false;
-            EntityItem that = (EntityItem) o;
-            return name != null ? name.equals(that.name) : that.name == null;
-        }
-
-        @Override
-        public int hashCode() {
-            int result = super.hashCode();
-            result = 31 * result + (name != null ? name.hashCode() : 0);
-            return result;
-        }
-    }
-
-    @Dao
-    public interface GenericDao {
-        @Insert
-        void insert(EntityItem... items);
-
-        @Query("SELECT * FROM EntityItem WHERE id = :id")
-        EntityItem get(String id);
-
-        @Query("SELECT id, mField FROM EntityItem WHERE id = :id")
-        PojoItem getPojo(String id);
-    }
-
-    @Database(version = 1, entities = {EntityItem.class}, exportSchema = false)
-    public abstract static class GenericDb extends RoomDatabase {
-        abstract GenericDao getDao();
-    }
-}
diff --git a/room3/integration-tests/testapp/src/androidTest/java/androidx/room3/integration/testapp/test/IdentityDetectionTest.java b/room3/integration-tests/testapp/src/androidTest/java/androidx/room3/integration/testapp/test/IdentityDetectionTest.java
deleted file mode 100644
index 9626cd6..0000000
--- a/room3/integration-tests/testapp/src/androidTest/java/androidx/room3/integration/testapp/test/IdentityDetectionTest.java
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * Copyright (C) 2017 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 androidx.room3.integration.testapp.test;
-
-import static org.hamcrest.CoreMatchers.instanceOf;
-import static org.hamcrest.CoreMatchers.is;
-import static org.hamcrest.MatcherAssert.assertThat;
-
-import android.util.Log;
-
-import androidx.room3.Room;
-import androidx.room3.integration.testapp.TestDatabase;
-import androidx.room3.integration.testapp.vo.User;
-import androidx.sqlite.db.SupportSQLiteDatabase;
-import androidx.test.core.app.ApplicationProvider;
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.test.filters.MediumTest;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.io.File;
-
-@RunWith(AndroidJUnit4.class)
-@MediumTest
-public class IdentityDetectionTest {
-    static final String TAG = "IdentityDetectionTest";
-    static final String DB_FILE_NAME = "identity_test_db";
-    TestDatabase mTestDatabase;
-    @Before
-    public void createTestDatabase() {
-        deleteDbFile();
-    }
-
-    @Test
-    public void reOpenWithoutIssues() {
-        openDb();
-        mTestDatabase.getUserDao().insert(TestUtil.createUser(3));
-        closeDb();
-        openDb();
-        User[] users = mTestDatabase.getUserDao().loadByIds(3);
-        assertThat(users.length, is(1));
-    }
-
-    @Test
-    public void reOpenChangedHash() {
-        openDb();
-        mTestDatabase.getUserDao().insert(TestUtil.createUser(3));
-        // change the hash
-        SupportSQLiteDatabase db = mTestDatabase.getOpenHelper().getWritableDatabase();
-        db.execSQL("UPDATE " + Room.MASTER_TABLE_NAME + " SET `identity_hash` = ?"
-                + " WHERE id = 42", new String[]{"bad hash"});
-        closeDb();
-        Throwable[] exceptions = new Throwable[1];
-        try {
-            openDb();
-            mTestDatabase.getUserDao().loadByIds(3);
-        } catch (Throwable t) {
-            exceptions[0] = t;
-            mTestDatabase = null;
-        }
-        assertThat(exceptions[0], instanceOf(IllegalStateException.class));
-    }
-
-    @Test
-    public void reOpenMasterTableDropped() {
-        openDb();
-        mTestDatabase.getUserDao().insert(TestUtil.createUser(3));
-        // drop the master table
-        SupportSQLiteDatabase db = mTestDatabase.getOpenHelper().getWritableDatabase();
-        db.execSQL("DROP TABLE " + Room.MASTER_TABLE_NAME);
-        closeDb();
-
-        openDb();
-        mTestDatabase.getUserDao().loadByIds(3);
-    }
-
-    private void closeDb() {
-        mTestDatabase.close();
-    }
-
-    private void openDb() {
-        mTestDatabase = Room.databaseBuilder(ApplicationProvider.getApplicationContext(),
-                TestDatabase.class, DB_FILE_NAME).build();
-    }
-
-    @After
-    public void clear() {
-        try {
-            if (mTestDatabase != null) {
-                closeDb();
-            }
-            deleteDbFile();
-        } catch (Throwable t) {
-            Log.e(TAG, "could not close test database", t);
-            throw t;
-        }
-    }
-
-    private void deleteDbFile() {
-        File testDb = ApplicationProvider.getApplicationContext().getDatabasePath(DB_FILE_NAME);
-        testDb.delete();
-    }
-}
diff --git a/room3/integration-tests/testapp/src/androidTest/java/androidx/room3/integration/testapp/test/IndexingTest.java b/room3/integration-tests/testapp/src/androidTest/java/androidx/room3/integration/testapp/test/IndexingTest.java
deleted file mode 100644
index a93afa1..0000000
--- a/room3/integration-tests/testapp/src/androidTest/java/androidx/room3/integration/testapp/test/IndexingTest.java
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * Copyright (C) 2017 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 androidx.room3.integration.testapp.test;
-
-import static org.hamcrest.CoreMatchers.is;
-import static org.hamcrest.MatcherAssert.assertThat;
-
-import android.content.Context;
-
-import androidx.room3.ColumnInfo;
-import androidx.room3.Dao;
-import androidx.room3.Database;
-import androidx.room3.Entity;
-import androidx.room3.Index;
-import androidx.room3.Insert;
-import androidx.room3.PrimaryKey;
-import androidx.room3.Query;
-import androidx.room3.Room;
-import androidx.room3.RoomDatabase;
-import androidx.test.core.app.ApplicationProvider;
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.test.filters.SmallTest;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.util.List;
-
-@SmallTest
-@RunWith(AndroidJUnit4.class)
-public class IndexingTest {
-    @Entity(
-            tableName = "foo_table",
-            indices = {
-                    @Index({"field1", "field2"}),
-                    @Index(value = {"field2", "mId"}, unique = true),
-                    @Index(value = {"field2"}, unique = true, name = "customIndex"),
-            })
-    static class Entity1 {
-        @PrimaryKey
-        public int mId;
-        public String field1;
-        public String field2;
-        @ColumnInfo(index = true, name = "my_field")
-        public String field3;
-
-        Entity1(int mId, String field1, String field2, String field3) {
-            this.mId = mId;
-            this.field1 = field1;
-            this.field2 = field2;
-            this.field3 = field3;
-        }
-    }
-
-    static class IndexInfo {
-        public String name;
-        @ColumnInfo(name = "tbl_name")
-        public String tableName;
-        public String sql;
-    }
-
-    @Dao
-    public interface Entity1Dao {
-        @Insert
-        void insert(Entity1 item);
-        @Query("SELECT * FROM foo_table indexed by customIndex where field2 = :inp")
-        List<Entity1> indexedBy(String inp);
-    }
-
-    @Dao
-    public interface SqlMasterDao {
-        @Query("SELECT name, tbl_name, sql FROM sqlite_master WHERE type = 'index'")
-        List<IndexInfo> loadIndices();
-    }
-
-    @Database(entities = {Entity1.class}, version = 1, exportSchema = false)
-    abstract static class IndexingDb extends RoomDatabase {
-        abstract SqlMasterDao sqlMasterDao();
-        abstract Entity1Dao entity1Dao();
-    }
-
-    @Test
-    public void verifyIndices() {
-        Context context = ApplicationProvider.getApplicationContext();
-        IndexingDb db = Room.inMemoryDatabaseBuilder(context, IndexingDb.class).build();
-        List<IndexInfo> indices = db.sqlMasterDao().loadIndices();
-        assertThat(indices.size(), is(4));
-        for (IndexInfo info : indices) {
-            assertThat(info.tableName, is("foo_table"));
-        }
-        assertThat(indices.get(0).sql, is("CREATE INDEX `index_foo_table_field1_field2`"
-                + " ON `foo_table` (`field1`, `field2`)"));
-        assertThat(indices.get(1).sql, is("CREATE UNIQUE INDEX `index_foo_table_field2_mId`"
-                + " ON `foo_table` (`field2`, `mId`)"));
-        assertThat(indices.get(2).sql, is("CREATE UNIQUE INDEX `customIndex`"
-                + " ON `foo_table` (`field2`)"));
-        assertThat(indices.get(3).sql, is("CREATE INDEX `index_foo_table_my_field`"
-                + " ON `foo_table` (`my_field`)"));
-        db.close();
-    }
-
-    @Test
-    public void indexedByQuery() {
-        Context context = ApplicationProvider.getApplicationContext();
-        IndexingDb db = Room.inMemoryDatabaseBuilder(context, IndexingDb.class).build();
-        db.entity1Dao().insert(new Entity1(1, "a", "b", "c"));
-        List<Entity1> result = db.entity1Dao().indexedBy("b");
-        assertThat(result.size(), is(1));
-        db.close();
-    }
-}
diff --git a/room3/integration-tests/testapp/src/androidTest/java/androidx/room3/integration/testapp/test/InvalidationTest.java b/room3/integration-tests/testapp/src/androidTest/java/androidx/room3/integration/testapp/test/InvalidationTest.java
deleted file mode 100644
index 623bce4..0000000
--- a/room3/integration-tests/testapp/src/androidTest/java/androidx/room3/integration/testapp/test/InvalidationTest.java
+++ /dev/null
@@ -1,176 +0,0 @@
-/*
- * Copyright (C) 2017 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 androidx.room3.integration.testapp.test;
-
-import static org.hamcrest.CoreMatchers.hasItem;
-import static org.hamcrest.CoreMatchers.nullValue;
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.hamcrest.collection.IsCollectionWithSize.hasSize;
-
-import android.content.Context;
-
-import androidx.arch.core.executor.testing.CountingTaskExecutorRule;
-import androidx.room3.InvalidationTracker;
-import androidx.room3.Room;
-import androidx.room3.integration.testapp.TestDatabase;
-import androidx.room3.integration.testapp.dao.PetDao;
-import androidx.room3.integration.testapp.dao.UserDao;
-import androidx.room3.integration.testapp.vo.Pet;
-import androidx.room3.integration.testapp.vo.User;
-import androidx.test.core.app.ApplicationProvider;
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.test.filters.SmallTest;
-
-import org.jspecify.annotations.NonNull;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.util.Set;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.TimeoutException;
-
-/**
- * Tests invalidation tracking.
- */
-@SmallTest
-@RunWith(AndroidJUnit4.class)
-public class InvalidationTest {
-    @Rule
-    public CountingTaskExecutorRule executorRule = new CountingTaskExecutorRule();
-    private UserDao mUserDao;
-    private PetDao mPetDao;
-    private TestDatabase mDb;
-
-    @Before
-    public void createDb() throws TimeoutException, InterruptedException {
-        Context context = ApplicationProvider.getApplicationContext();
-        mDb = Room.inMemoryDatabaseBuilder(context, TestDatabase.class).build();
-        mUserDao = mDb.getUserDao();
-        mPetDao = mDb.getPetDao();
-        drain();
-    }
-
-    @After
-    public void closeDb() throws TimeoutException, InterruptedException {
-        mDb.close();
-        drain();
-    }
-
-    private void drain() throws TimeoutException, InterruptedException {
-        executorRule.drainTasks(1, TimeUnit.MINUTES);
-    }
-
-    @Test
-    public void testInvalidationOnUpdate() throws InterruptedException, TimeoutException {
-        User user = TestUtil.createUser(3);
-        mUserDao.insert(user);
-        LoggingObserver observer = new LoggingObserver("User");
-        mDb.getInvalidationTracker().addObserver(observer);
-        drain();
-        mUserDao.updateById(3, "foo2");
-        drain();
-        assertThat(observer.getInvalidatedTables(), hasSize(1));
-        assertThat(observer.getInvalidatedTables(), hasItem("User"));
-    }
-
-    @Test
-    public void testInvalidationOnDelete() throws InterruptedException, TimeoutException {
-        User user = TestUtil.createUser(3);
-        mUserDao.insert(user);
-        LoggingObserver observer = new LoggingObserver("User");
-        mDb.getInvalidationTracker().addObserver(observer);
-        drain();
-        mUserDao.delete(user);
-        drain();
-        assertThat(observer.getInvalidatedTables(), hasSize(1));
-        assertThat(observer.getInvalidatedTables(), hasItem("User"));
-    }
-
-    @Test
-    public void testInvalidationOnInsert() throws InterruptedException, TimeoutException {
-        LoggingObserver observer = new LoggingObserver("User");
-        mDb.getInvalidationTracker().addObserver(observer);
-        drain();
-        mUserDao.insert(TestUtil.createUser(3));
-        drain();
-        assertThat(observer.getInvalidatedTables(), hasSize(1));
-        assertThat(observer.getInvalidatedTables(), hasItem("User"));
-    }
-
-    @Test
-    public void testDontInvalidateOnLateInsert() throws InterruptedException, TimeoutException {
-        LoggingObserver observer = new LoggingObserver("User");
-        mUserDao.insert(TestUtil.createUser(3));
-        drain();
-        mDb.getInvalidationTracker().addObserver(observer);
-        drain();
-        assertThat(observer.getInvalidatedTables(), nullValue());
-    }
-
-    @Test
-    public void testMultipleTables() throws InterruptedException, TimeoutException {
-        LoggingObserver observer = new LoggingObserver("User", "Pet");
-        mDb.getInvalidationTracker().addObserver(observer);
-        drain();
-        mUserDao.insert(TestUtil.createUser(3));
-        drain();
-        assertThat(observer.getInvalidatedTables(), hasSize(1));
-        assertThat(observer.getInvalidatedTables(), hasItem("User"));
-    }
-
-    @Test
-    public void testView() throws InterruptedException, TimeoutException {
-        LoggingObserver observer = new LoggingObserver("PetWithUser");
-        mDb.getInvalidationTracker().addObserver(observer);
-        drain();
-        mUserDao.insert(TestUtil.createUser(3));
-        drain();
-        assertThat(observer.getInvalidatedTables(), hasSize(1));
-        assertThat(observer.getInvalidatedTables(), hasItem("User"));
-        observer.reset();
-        Pet pet = TestUtil.createPet(3);
-        pet.setUserId(3);
-        mPetDao.insertOrReplace(pet);
-        drain();
-        assertThat(observer.getInvalidatedTables(), hasSize(1));
-        assertThat(observer.getInvalidatedTables(), hasItem("Pet"));
-    }
-
-    private static class LoggingObserver extends InvalidationTracker.Observer {
-        private Set<String> mInvalidatedTables;
-
-        LoggingObserver(String... tables) {
-            super(tables);
-        }
-
-        @Override
-        public void onInvalidated(@NonNull Set<String> tables) {
-            mInvalidatedTables = tables;
-        }
-
-        Set<String> getInvalidatedTables() {
-            return mInvalidatedTables;
-        }
-
-        void reset() {
-            mInvalidatedTables = null;
-        }
-    }
-}
diff --git a/room3/integration-tests/testapp/src/androidTest/java/androidx/room3/integration/testapp/test/InvalidationTrackerBehavioralTest.java b/room3/integration-tests/testapp/src/androidTest/java/androidx/room3/integration/testapp/test/InvalidationTrackerBehavioralTest.java
deleted file mode 100644
index 2b7a200..0000000
--- a/room3/integration-tests/testapp/src/androidTest/java/androidx/room3/integration/testapp/test/InvalidationTrackerBehavioralTest.java
+++ /dev/null
@@ -1,263 +0,0 @@
-/*
- * Copyright 2021 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 androidx.room3.integration.testapp.test;
-
-import static org.hamcrest.CoreMatchers.is;
-import static org.hamcrest.MatcherAssert.assertThat;
-
-import androidx.room3.Dao;
-import androidx.room3.Database;
-import androidx.room3.Entity;
-import androidx.room3.Insert;
-import androidx.room3.InvalidationTracker;
-import androidx.room3.PrimaryKey;
-import androidx.room3.Room;
-import androidx.room3.RoomDatabase;
-import androidx.test.core.app.ApplicationProvider;
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.test.filters.FlakyTest;
-import androidx.test.filters.LargeTest;
-
-import org.jspecify.annotations.NonNull;
-import org.jspecify.annotations.Nullable;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.util.Set;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicInteger;
-
-/**
- * Regression test for a situation where an InvalidationTracker callback may intermittently be
- * invoked too early, too late, or not at all, due to missing transactionality in tracking table
- * code, when distinct database updates occur in close temporal proximity.
- */
-@LargeTest
-@FlakyTest(
-        bugId = 154040286,
-        detail = "Behavioral test for potentially intermittent InvalidationTracker problems"
-)
-@RunWith(AndroidJUnit4.class)
-public class InvalidationTrackerBehavioralTest {
-    private ExecutorService mExecutorService;
-
-    @Before
-    public void setup() {
-        mExecutorService = Executors.newSingleThreadExecutor();
-    }
-
-    @After
-    public void tearDown() {
-        mExecutorService.shutdown();
-    }
-
-    @Test
-    public void testInserts_JournalModeTruncate() throws ExecutionException, InterruptedException {
-        testInserts(RoomDatabase.JournalMode.TRUNCATE);
-    }
-
-    @Test
-    public void testInserts_JournalModeWAL() throws ExecutionException, InterruptedException {
-        testInserts(RoomDatabase.JournalMode.WRITE_AHEAD_LOGGING);
-    }
-
-    private void testInserts(RoomDatabase.JournalMode journalMode)
-            throws ExecutionException, InterruptedException {
-        testInserts(journalMode, true);
-        testInserts(journalMode, false);
-    }
-
-    private void testInserts(RoomDatabase.JournalMode journalMode, boolean multiInstance)
-            throws ExecutionException, InterruptedException {
-        final RoomDatabase.Builder<DB> dbBuilder = Room
-                // We need a physical DB to more easily reproduce invalidation callback errors,
-                // and to support enableMultiInstanceInvalidation, which in turn helps reproduce
-                // missed invalidation callbacks
-                .databaseBuilder(ApplicationProvider.getApplicationContext(), DB.class, DB.NAME)
-                .setJournalMode(journalMode);
-        if (multiInstance) {
-            // Helps reproduce missed invalidation callbacks
-            dbBuilder.enableMultiInstanceInvalidation();
-        }
-
-        DB db = dbBuilder.build();
-
-        try {
-            testInserts(db, 30, 0L, 0);
-            testInserts(db, 30, 0L, 10);
-            testInserts(db, 30, 0L, 100);
-            testInserts(db, 30, 0L, 1_000);
-            testInserts(db, 30, 0L, 10_000);
-            testInserts(db, 30, 0L, 100_000);
-            testInserts(db, 30, 1L, 0);
-        } finally {
-            db.close();
-            ApplicationProvider.getApplicationContext().deleteDatabase(DB.NAME);
-        }
-    }
-
-    /**
-     * Uses repetitions within the test to better approximate real-life behavior, rather than
-     * scheduling the whole test for repeated runs from the outside.
-     */
-    private void testInserts(
-            final DB db, final int iterations, final long delayMillis, final int delayNanos
-    ) throws ExecutionException, InterruptedException {
-        final AtomicInteger missedInvalidations = new AtomicInteger();
-        final AtomicInteger spuriousInvalidations = new AtomicInteger();
-
-        // Does not terminate execution as soon as a problem is detected, for simplicity.
-        // Usually there should not be a problem; termination is delayed only when there is a
-        // problem.
-        mExecutorService.submit(new Runnable() {
-            volatile @Nullable CountDownLatch mLatch = null;
-
-            // Releases latch when change notification received, increments
-            // spuriousInvalidations when notification received without a recent change
-            final InvalidationTracker.Observer mInvalidationObserver =
-                    new InvalidationTracker.Observer(Counter2.TABLE_NAME) {
-                        @Override
-                        public void onInvalidated(@NonNull Set<String> tables) {
-                            if (tables.contains(Counter2.TABLE_NAME)) {
-                                // Reading the latch field value is a bit racy,
-                                // but it does not matter:
-                                //
-                                // If we see null here then we're either too early or too late;
-                                // too late means that our long delay was too short, so we'd
-                                // need to adjust it because now the test failed.
-                                // Too early means that we received a spurious invalidation, so
-                                // we need to fail the test.
-                                //
-                                // If we see non-null here instead of null due to a race then
-                                // our long delay was just too short and we'll need to adjust it
-                                // because the test will have failed. latch.countDown() happens
-                                // too late in this case but it has no particular effect.
-                                final CountDownLatch latch = mLatch;
-                                if (latch == null) {
-                                    // Spurious invalidation callback; this might occur due to a
-                                    // large delay beyond the provisioned margin, or due to a
-                                    // bug in the code under test
-                                    spuriousInvalidations.incrementAndGet();
-                                } else {
-                                    latch.countDown();
-                                }
-                            }
-                        }
-                    };
-
-            @Override
-            public void run() {
-                // Ulterior use of this background thread to add the observer, which is not
-                // legal to do from main thread.
-                // To be close to a real use case we only register the observer once,
-                // we do not re-register for each loop iteration.
-                db.getInvalidationTracker().addObserver(mInvalidationObserver);
-
-                try {
-                    // Resets latch and updates missedInvalidations when change notification failed
-                    for (int i = 0; i < iterations; ++i) {
-                        // The Counter1 table exists just to make InvalidationTracker's life more
-                        // difficult, we are not interested in notifications from this one;
-                        // inserts may trigger undefined invalidation callback behavior,
-                        // depending on table update timing
-                        db.counterDao().insert(new Counter1());
-
-                        // Use variable delay to detect different kinds of timing-related problems
-                        try {
-                            Thread.sleep(delayMillis, delayNanos);
-                        } catch (InterruptedException e) {
-                            throw new RuntimeException(e);
-                        }
-
-                        final CountDownLatch latch = new CountDownLatch(1);
-
-                        db.runInTransaction(() -> {
-                            db.counterDao().insert(new Counter2());
-
-                            // Flag that we have inserted a new value, expect invalidation callback;
-                            // do this as late as possible prior to the end of the transaction;
-                            // this might cause an occasional false negative due to a race,
-                            // where a buggy InvalidationTracker could log successful tracking
-                            // even though the transaction is not completed yet, but it does not
-                            // matter much, as this is an intentionally flaky test; on another run
-                            // it should become apparent that InvalidationTracker is buggy.
-                            mLatch = latch;
-                        });
-
-                        // Use sufficient delay to give invalidation tracker ample time to catch up;
-                        // this would need to be increased if the test had false positives.
-                        try {
-                            if (!latch.await(10L, TimeUnit.SECONDS)) {
-                                // The tracker still has not been called, log an error
-                                missedInvalidations.incrementAndGet();
-                            }
-                        } catch (InterruptedException e) {
-                            throw new RuntimeException(e);
-                        }
-
-                        mLatch = null;
-                    }
-                } finally {
-                    db.getInvalidationTracker().removeObserver(mInvalidationObserver);
-                }
-            }
-        }).get();
-
-        assertThat("Missed invalidations on " + iterations + " iterations with delay of " +
-                delayMillis + " ms, " + delayNanos + " ns", missedInvalidations.get(), is(0));
-        assertThat("Spurious invalidations on " + iterations + " iterations with delay of " +
-                delayMillis + " ms, " + delayNanos + " ns", spuriousInvalidations.get(), is(0));
-    }
-
-    @Database(entities = { Counter1.class, Counter2.class }, version = 1, exportSchema = false)
-    abstract static class DB extends RoomDatabase {
-        static final String NAME = "invalidationtrackerbehavioraltest";
-
-        abstract CounterDao counterDao();
-    }
-
-    @Entity(tableName = Counter1.TABLE_NAME)
-    static final class Counter1 {
-        static final String TABLE_NAME = "counter1";
-
-        @PrimaryKey(autoGenerate = true)
-        long value;
-    }
-
-    @Entity(tableName = Counter2.TABLE_NAME)
-    static final class Counter2 {
-        static final String TABLE_NAME = "counter2";
-
-        @PrimaryKey(autoGenerate = true)
-        long value;
-    }
-
-    @Dao
-    abstract static class CounterDao {
-        @Insert
-        abstract void insert(Counter1 entity);
-
-        @Insert
-        abstract void insert(Counter2 entity);
-    }
-}
diff --git a/room3/integration-tests/testapp/src/androidTest/java/androidx/room3/integration/testapp/test/InvalidationTrackerTest.java b/room3/integration-tests/testapp/src/androidTest/java/androidx/room3/integration/testapp/test/InvalidationTrackerTest.java
deleted file mode 100644
index b1d56e5..0000000
--- a/room3/integration-tests/testapp/src/androidTest/java/androidx/room3/integration/testapp/test/InvalidationTrackerTest.java
+++ /dev/null
@@ -1,273 +0,0 @@
-/*
- * Copyright 2018 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 androidx.room3.integration.testapp.test;
-
-import static androidx.room3.integration.testapp.test.TestUtil.forceGc;
-
-import static junit.framework.TestCase.assertFalse;
-
-import static org.hamcrest.CoreMatchers.is;
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.doAnswer;
-
-import android.app.Instrumentation;
-import android.os.Looper;
-
-import androidx.arch.core.executor.testing.CountingTaskExecutorRule;
-import androidx.lifecycle.Lifecycle;
-import androidx.lifecycle.LiveData;
-import androidx.lifecycle.testing.TestLifecycleOwner;
-import androidx.room3.Dao;
-import androidx.room3.Database;
-import androidx.room3.Entity;
-import androidx.room3.Insert;
-import androidx.room3.InvalidationTracker;
-import androidx.room3.OnConflictStrategy;
-import androidx.room3.PrimaryKey;
-import androidx.room3.Query;
-import androidx.room3.Room;
-import androidx.room3.RoomDatabase;
-import androidx.sqlite.db.SupportSQLiteDatabase;
-import androidx.test.core.app.ApplicationProvider;
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.test.filters.MediumTest;
-import androidx.test.platform.app.InstrumentationRegistry;
-
-import io.reactivex.Flowable;
-import io.reactivex.Observable;
-import io.reactivex.disposables.CompositeDisposable;
-
-import org.jspecify.annotations.NonNull;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mockito;
-
-import java.util.Objects;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.TimeoutException;
-import java.util.concurrent.atomic.AtomicBoolean;
-
-@MediumTest
-@RunWith(AndroidJUnit4.class)
-public class InvalidationTrackerTest {
-    @Rule
-    public CountingTaskExecutorRule mExecutorRule = new CountingTaskExecutorRule();
-    private Instrumentation mInstrumentation;
-    private InvalidationTestDatabase mDb;
-
-    @Before
-    public void setup() {
-        mInstrumentation = InstrumentationRegistry.getInstrumentation();
-        mDb = Room.inMemoryDatabaseBuilder(
-                ApplicationProvider.getApplicationContext(),
-                InvalidationTestDatabase.class)
-                .build();
-    }
-
-    @After
-    public void teardown() throws InterruptedException, TimeoutException {
-        mExecutorRule.drainTasks(5, TimeUnit.SECONDS);
-        mDb.close();
-    }
-
-
-    @Test
-    public void testInit_differentTempStore() {
-        InvalidationTestDatabase db = Room.inMemoryDatabaseBuilder(
-                ApplicationProvider.getApplicationContext(),
-                InvalidationTestDatabase.class)
-                .addCallback(new RoomDatabase.Callback() {
-                    @Override
-                    public void onCreate(@NonNull SupportSQLiteDatabase db) {
-                        db.execSQL("PRAGMA temp_store = FILE;");
-                        db.execSQL("CREATE TEMP TABLE cache (id INTEGER PRIMARY KEY)");
-                    }
-                })
-                .build();
-        // Open DB to init InvalidationTracker, should not crash.
-        db.getOpenHelper().getWritableDatabase();
-        db.close();
-    }
-
-    @Test
-    public void testSubscribe_mainThread() throws InterruptedException {
-        mDb.setShouldSpyOnInvalidation(true);
-        mDb.getOpenHelper().getWritableDatabase(); // Open DB to init InvalidationTracker
-
-        CompositeDisposable disposables = new CompositeDisposable();
-        AtomicBoolean mainThreadViolation = new AtomicBoolean();
-
-        // Expect 2 calls to addObserver
-        CountDownLatch addLatch = new CountDownLatch(2);
-        doAnswer(invocation -> {
-            if (Looper.myLooper() == Looper.getMainLooper()) {
-                mainThreadViolation.set(true);
-            }
-            addLatch.countDown();
-            return null;
-        }).when(mDb.getInvalidationTracker())
-                .addObserver(any(InvalidationTracker.Observer.class));
-        mInstrumentation.runOnMainSync(() -> {
-            disposables.add(mDb.getItemDao().flowableItemById(1).subscribe());
-            disposables.add(mDb.getItemDao().observableItemById(1).subscribe());
-        });
-        addLatch.await(10, TimeUnit.SECONDS);
-
-        // Expect 2 calls to removeObserver
-        CountDownLatch removeLatch = new CountDownLatch(2);
-        doAnswer(invocation -> {
-            if (Looper.myLooper() == Looper.getMainLooper()) {
-                mainThreadViolation.set(true);
-            }
-            removeLatch.countDown();
-            return null;
-        }).when(mDb.getInvalidationTracker())
-                .removeObserver(any(InvalidationTracker.Observer.class));
-        mInstrumentation.runOnMainSync(disposables::dispose);
-        removeLatch.await(10, TimeUnit.SECONDS);
-
-        assertFalse("Expected no main thread disk IO violation.", mainThreadViolation.get());
-    }
-
-    @Test
-    public void createLiveData() throws ExecutionException, InterruptedException, TimeoutException {
-        final LiveData<Item> liveData = mDb
-                .getInvalidationTracker()
-                .createLiveData(new String[]{"Item"}, false, () -> mDb.getItemDao().itemById(1));
-
-        mDb.getItemDao().insert(new Item(1, "v1"));
-
-        final TestLifecycleOwner lifecycleOwner = new TestLifecycleOwner(
-                Lifecycle.State.INITIALIZED);
-        TestObserver<Item> observer = new MyObserver<>();
-        TestUtil.observeOnMainThread(liveData, lifecycleOwner, observer);
-        assertThat(observer.hasValue(), is(false));
-        lifecycleOwner.handleLifecycleEvent(Lifecycle.Event.ON_START);
-        drain();
-        assertThat(observer.get(), is(new Item(1, "v1")));
-
-        mDb.getItemDao().insert(new Item(1, "v2"));
-        drain();
-        assertThat(observer.get(), is(new Item(1, "v2")));
-    }
-
-    @Test
-    public void createLiveData_observeForever()
-            throws ExecutionException, InterruptedException, TimeoutException {
-        LiveData<Item> liveData = mDb
-                .getInvalidationTracker()
-                .createLiveData(new String[]{"Item"}, false, () -> mDb.getItemDao().itemById(1));
-
-        mDb.getItemDao().insert(new Item(1, "v1"));
-
-        TestObserver<Item> observer = new MyObserver<>();
-        TestUtil.observeForeverOnMainThread(liveData, observer);
-        assertThat(observer.get(), is(new Item(1, "v1")));
-
-        mDb.getItemDao().insert(new Item(1, "v2"));
-        assertThat(observer.get(), is(new Item(1, "v2")));
-
-        //noinspection UnusedAssignment
-        liveData = null;
-        forceGc();
-        mDb.getItemDao().insert(new Item(1, "v3"));
-        assertThat(observer.get(), is(new Item(1, "v3")));
-    }
-
-    private void drain() throws TimeoutException, InterruptedException {
-        mExecutorRule.drainTasks(1, TimeUnit.MINUTES);
-    }
-
-    @Database(entities = Item.class, version = 1, exportSchema = false)
-    abstract static class InvalidationTestDatabase extends RoomDatabase {
-
-        private boolean mShouldSpyOnInvalidation;
-
-        private InvalidationTracker mInvalidationTrackerSpy;
-
-        public void setShouldSpyOnInvalidation(boolean shouldSpyOnInvalidation) {
-            mShouldSpyOnInvalidation = shouldSpyOnInvalidation;
-        }
-
-        @Override
-        public @NonNull InvalidationTracker getInvalidationTracker() {
-            if (mShouldSpyOnInvalidation) {
-                if (mInvalidationTrackerSpy == null) {
-                    mInvalidationTrackerSpy = Mockito.spy(super.getInvalidationTracker());
-                }
-                return mInvalidationTrackerSpy;
-            }
-            return super.getInvalidationTracker();
-        }
-
-        abstract ItemDao getItemDao();
-    }
-
-    @Entity
-    static class Item {
-        @PrimaryKey
-        public final long id;
-        public final @NonNull String name;
-        Item(long id, String name) {
-            this.id = id;
-            this.name = name;
-        }
-
-        @Override
-        public boolean equals(Object o) {
-            if (this == o) return true;
-            if (o == null || getClass() != o.getClass()) return false;
-            Item item = (Item) o;
-            return id == item.id
-                    && name.equals(item.name);
-        }
-
-        @Override
-        public int hashCode() {
-            return Objects.hash(id, name);
-        }
-    }
-
-    @Dao
-    interface ItemDao {
-        @Query("select * from item where id = :id")
-        Flowable<@NonNull Item> flowableItemById(int id);
-
-        @Query("select * from item where id = :id")
-        Observable<@NonNull Item> observableItemById(int id);
-
-        @Query("select * from item where id = :id")
-        Item itemById(int id);
-
-        @Insert(onConflict = OnConflictStrategy.REPLACE)
-        void insert(Item item);
-    }
-
-    private class MyObserver<T> extends TestObserver<T> {
-
-        @Override
-        protected void drain() throws TimeoutException, InterruptedException {
-            InvalidationTrackerTest.this.drain();
-        }
-    }
-}
diff --git a/room3/integration-tests/testapp/src/androidTest/java/androidx/room3/integration/testapp/test/LegacyIdentityHashTest.java b/room3/integration-tests/testapp/src/androidTest/java/androidx/room3/integration/testapp/test/LegacyIdentityHashTest.java
deleted file mode 100644
index 4b3e40c..0000000
--- a/room3/integration-tests/testapp/src/androidTest/java/androidx/room3/integration/testapp/test/LegacyIdentityHashTest.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Copyright 2024 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 androidx.room3.integration.testapp.test;
-
-import android.content.Context;
-
-import androidx.room3.Database;
-import androidx.room3.Entity;
-import androidx.room3.PrimaryKey;
-import androidx.room3.Room;
-import androidx.room3.RoomDatabase;
-import androidx.room3.RoomMasterTable;
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.test.filters.SmallTest;
-import androidx.test.platform.app.InstrumentationRegistry;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-@SmallTest
-@RunWith(AndroidJUnit4.class)
-public class LegacyIdentityHashTest {
-
-    private Context mTargetContext =
-            InstrumentationRegistry.getInstrumentation().getTargetContext();
-    private String mDatabaseName = "legacy-test.db";
-
-    @Before
-    public void setup() {
-        mTargetContext.deleteDatabase(mDatabaseName);
-    }
-
-    @After
-    public void teardown() {
-        mTargetContext.deleteDatabase(mDatabaseName);
-    }
-
-    @Test
-    public void openDatabaseWithLegacyHash() {
-        RoomDatabase.Builder<LegacyDatabase> dbBuilder = Room.databaseBuilder(
-                InstrumentationRegistry.getInstrumentation().getTargetContext(),
-                LegacyDatabase.class,
-                "legacy-test.db"
-        );
-
-        LegacyDatabase newDb = dbBuilder.build();
-        String insertQuery =
-                RoomMasterTable.createInsertQuery("d5249b2a35eb34d6c54d25ca1b7b9b74");
-        newDb.getOpenHelper().getWritableDatabase().execSQL(insertQuery);
-        newDb.close();
-
-        LegacyDatabase legacyDb = dbBuilder.build();
-        legacyDb.getOpenHelper().getWritableDatabase(); // force open db
-        legacyDb.close();
-    }
-
-    @Database(entities = TestDataEntity.class, version = 1, exportSchema = false)
-    abstract static class LegacyDatabase extends RoomDatabase {
-
-    }
-
-    @Entity
-    static class TestDataEntity {
-        @PrimaryKey @SuppressWarnings("unused") Long mId;
-    }
-}
diff --git a/room3/integration-tests/testapp/src/androidTest/java/androidx/room3/integration/testapp/test/LiveDataQueryTest.java b/room3/integration-tests/testapp/src/androidTest/java/androidx/room3/integration/testapp/test/LiveDataQueryTest.java
deleted file mode 100644
index 1022c74..0000000
--- a/room3/integration-tests/testapp/src/androidTest/java/androidx/room3/integration/testapp/test/LiveDataQueryTest.java
+++ /dev/null
@@ -1,542 +0,0 @@
-/*
- * Copyright (C) 2017 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 androidx.room3.integration.testapp.test;
-
-import static org.hamcrest.CoreMatchers.equalTo;
-import static org.hamcrest.CoreMatchers.is;
-import static org.hamcrest.CoreMatchers.notNullValue;
-import static org.hamcrest.CoreMatchers.nullValue;
-import static org.hamcrest.MatcherAssert.assertThat;
-
-import android.content.Context;
-
-import androidx.arch.core.executor.testing.CountingTaskExecutorRule;
-import androidx.lifecycle.Lifecycle;
-import androidx.lifecycle.LiveData;
-import androidx.lifecycle.Observer;
-import androidx.lifecycle.testing.TestLifecycleOwner;
-import androidx.room3.Room;
-import androidx.room3.integration.testapp.FtsTestDatabase;
-import androidx.room3.integration.testapp.MusicTestDatabase;
-import androidx.room3.integration.testapp.dao.MailDao;
-import androidx.room3.integration.testapp.dao.MusicDao;
-import androidx.room3.integration.testapp.dao.SongDao;
-import androidx.room3.integration.testapp.vo.AvgWeightByAge;
-import androidx.room3.integration.testapp.vo.Mail;
-import androidx.room3.integration.testapp.vo.Pet;
-import androidx.room3.integration.testapp.vo.PetWithUser;
-import androidx.room3.integration.testapp.vo.PetsToys;
-import androidx.room3.integration.testapp.vo.Playlist;
-import androidx.room3.integration.testapp.vo.PlaylistSongXRef;
-import androidx.room3.integration.testapp.vo.PlaylistWithSongs;
-import androidx.room3.integration.testapp.vo.Song;
-import androidx.room3.integration.testapp.vo.SongDescription;
-import androidx.room3.integration.testapp.vo.Toy;
-import androidx.room3.integration.testapp.vo.User;
-import androidx.room3.integration.testapp.vo.UserAndAllPets;
-import androidx.test.core.app.ApplicationProvider;
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.test.filters.MediumTest;
-import androidx.test.platform.app.InstrumentationRegistry;
-
-import org.junit.After;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.lang.ref.WeakReference;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-import java.util.UUID;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.TimeoutException;
-import java.util.concurrent.atomic.AtomicReference;
-
-/**
- * Tests invalidation tracking.
- */
-@MediumTest
-@RunWith(AndroidJUnit4.class)
-public class LiveDataQueryTest extends TestDatabaseTest {
-    @Rule
-    public CountingTaskExecutorRule mExecutorRule = new CountingTaskExecutorRule();
-
-    @After
-    public void teardown() throws InterruptedException, TimeoutException {
-        mExecutorRule.drainTasks(5, TimeUnit.SECONDS);
-    }
-
-    @Test
-    public void observeById() throws InterruptedException, ExecutionException, TimeoutException {
-        final LiveData<User> userLiveData = mUserDao.liveUserById(5);
-        final TestLifecycleOwner testOwner = new TestLifecycleOwner(Lifecycle.State.CREATED);
-        final TestObserver<User> observer = new MyTestObserver<>();
-        TestUtil.observeOnMainThread(userLiveData, testOwner, observer);
-        assertThat(observer.hasValue(), is(false));
-        observer.reset();
-
-        testOwner.handleLifecycleEvent(Lifecycle.Event.ON_START);
-        assertThat(observer.get(), is(nullValue()));
-
-        // another id
-        observer.reset();
-        mUserDao.insert(TestUtil.createUser(7));
-        assertThat(observer.get(), is(nullValue()));
-
-        observer.reset();
-        final User u5 = TestUtil.createUser(5);
-        mUserDao.insert(u5);
-        assertThat(observer.get(), is(notNullValue()));
-
-        u5.setName("foo-foo-foo");
-        observer.reset();
-        mUserDao.insertOrReplace(u5);
-        final User updated = observer.get();
-        assertThat(updated, is(notNullValue()));
-        assertThat(updated.getName(), is("foo-foo-foo"));
-
-        testOwner.handleLifecycleEvent(Lifecycle.Event.ON_STOP);
-        observer.reset();
-        u5.setName("baba");
-        mUserDao.insertOrReplace(u5);
-        assertThat(observer.hasValue(), is(false));
-    }
-
-    @Test
-    public void observeListQuery() throws InterruptedException, ExecutionException,
-            TimeoutException {
-        final LiveData<List<User>> userLiveData = mUserDao.liveUsersListByName("frida");
-        final TestLifecycleOwner lifecycleOwner = new TestLifecycleOwner();
-        final TestObserver<List<User>> observer = new MyTestObserver<>();
-        TestUtil.observeOnMainThread(userLiveData, lifecycleOwner, observer);
-        assertThat(observer.get(), is(Collections.<User>emptyList()));
-
-        observer.reset();
-        final User user1 = TestUtil.createUser(3);
-        user1.setName("dog frida");
-        mUserDao.insert(user1);
-        assertThat(observer.get(), is(Collections.singletonList(user1)));
-
-        observer.reset();
-        final User user2 = TestUtil.createUser(5);
-        user2.setName("does not match");
-        mUserDao.insert(user2);
-        assertThat(observer.get(), is(Collections.singletonList(user1)));
-
-        observer.reset();
-        user1.setName("i don't match either");
-        mUserDao.insertOrReplace(user1);
-        assertThat(observer.get(), is(Collections.<User>emptyList()));
-
-        lifecycleOwner.handleLifecycleEvent(Lifecycle.Event.ON_STOP);
-
-        observer.reset();
-        final User user3 = TestUtil.createUser(9);
-        user3.setName("painter frida");
-        mUserDao.insertOrReplace(user3);
-        assertThat(observer.hasValue(), is(false));
-
-        observer.reset();
-        final User user4 = TestUtil.createUser(11);
-        user4.setName("friday");
-        mUserDao.insertOrReplace(user4);
-        assertThat(observer.hasValue(), is(false));
-
-        lifecycleOwner.handleLifecycleEvent(Lifecycle.Event.ON_START);
-        assertThat(observer.get(), is(Arrays.asList(user4, user3)));
-    }
-
-    @Test
-    public void liveDataWithPojo() throws ExecutionException, InterruptedException,
-            TimeoutException {
-        User[] users = TestUtil.createUsersArray(3, 5, 7, 9);
-        users[0].setAge(10);
-        users[0].setWeight(15);
-
-        users[1].setAge(20);
-        users[1].setWeight(25);
-
-        users[2].setAge(20);
-        users[2].setWeight(26);
-
-        users[3].setAge(10);
-        users[3].setWeight(21);
-
-        final TestLifecycleOwner lifecycleOwner = new TestLifecycleOwner();
-
-        final TestObserver<AvgWeightByAge> observer = new MyTestObserver<>();
-        LiveData<AvgWeightByAge> liveData = mUserDao.maxWeightByAgeGroup();
-
-        TestUtil.observeOnMainThread(liveData, lifecycleOwner, observer);
-        assertThat(observer.get(), is(nullValue()));
-
-        observer.reset();
-        mUserDao.insertAll(users);
-        assertThat(observer.get(), is(new AvgWeightByAge(20, 25.5f)));
-
-        observer.reset();
-        User user3 = mUserDao.load(3);
-        user3.setWeight(79);
-        mUserDao.insertOrReplace(user3);
-
-        assertThat(observer.get(), is(new AvgWeightByAge(10, 50)));
-    }
-
-    @Test
-    public void liveDataWithView() throws ExecutionException, InterruptedException,
-            TimeoutException {
-        User user = TestUtil.createUser(1);
-        Pet pet = TestUtil.createPet(3);
-        pet.setUserId(user.getId());
-
-        final TestLifecycleOwner lifecycleOwner = new TestLifecycleOwner();
-
-        final TestObserver<PetWithUser> observer = new MyTestObserver<>();
-        LiveData<PetWithUser> liveData = mPetDao.petWithUserLiveData(3);
-
-        TestUtil.observeOnMainThread(liveData, lifecycleOwner, observer);
-        assertThat(observer.get(), is(nullValue()));
-
-        observer.reset();
-        mUserDao.insert(user);
-        mPetDao.insertOrReplace(pet);
-        PetWithUser petWithUser = observer.get();
-        assertThat(petWithUser.pet, is(equalTo(pet)));
-        assertThat(petWithUser.user, is(equalTo(user)));
-    }
-
-    @Test
-    public void withRelation() throws ExecutionException, InterruptedException, TimeoutException {
-        final LiveData<UserAndAllPets> liveData = mUserPetDao.liveUserWithPets(3);
-        final TestObserver<UserAndAllPets> observer = new MyTestObserver<>();
-        final TestLifecycleOwner lifecycleOwner = new TestLifecycleOwner();
-        TestUtil.observeOnMainThread(liveData, lifecycleOwner, observer);
-        assertThat(observer.get(), is(nullValue()));
-
-        observer.reset();
-        User user = TestUtil.createUser(3);
-        mUserDao.insert(user);
-        final UserAndAllPets noPets = observer.get();
-        assertThat(noPets.user, is(user));
-
-        observer.reset();
-        Pet[] pets = TestUtil.createPetsForUser(3, 1, 2);
-        mPetDao.insertAll(pets);
-
-        final UserAndAllPets withPets = observer.get();
-        assertThat(withPets.user, is(user));
-        assertThat(withPets.pets, is(Arrays.asList(pets)));
-    }
-
-    @Test
-    public void withRelationOnly() throws ExecutionException, InterruptedException,
-            TimeoutException {
-        LiveData<PetsToys> liveData = mSpecificDogDao.getSpecificDogsToys();
-
-        PetsToys expected = new PetsToys();
-        expected.petId = 123;
-
-        Pet testPet = TestUtil.createPet(123);
-        mPetDao.insertOrReplace(testPet);
-
-        Toy toy = new Toy();
-        toy.setId(1);
-        toy.setPetId(123);
-        toy.setName("ball");
-        toy.setPetId(123);
-
-        final TestLifecycleOwner lifecycleOwner = new TestLifecycleOwner();
-        final TestObserver<PetsToys> observer = new MyTestObserver<>();
-        TestUtil.observeOnMainThread(liveData, lifecycleOwner, observer);
-        assertThat(observer.get(), is(expected));
-
-        observer.reset();
-        expected.toys.add(toy);
-        mToyDao.insert(toy);
-        assertThat(observer.get(), is(expected));
-    }
-
-    @Test
-    public void withRelationAndJunction() throws ExecutionException, InterruptedException,
-            TimeoutException {
-        Context context = ApplicationProvider.getApplicationContext();
-        final MusicTestDatabase db = Room.inMemoryDatabaseBuilder(context, MusicTestDatabase.class)
-                .build();
-        final MusicDao musicDao = db.getDao();
-
-        final Song mSong1 = new Song(
-                1,
-                "I Know Places",
-                "Taylor Swift",
-                "1989",
-                195,
-                2014);
-        final Song mSong2 = new Song(
-                2,
-                "Blank Space",
-                "Taylor Swift",
-                "1989",
-                241,
-                2014);
-
-        final Playlist mPlaylist1 = new Playlist(1);
-        final Playlist mPlaylist2 = new Playlist(2);
-
-        musicDao.addSongs(mSong1, mSong2);
-        musicDao.addPlaylists(mPlaylist1, mPlaylist2);
-
-        musicDao.addPlaylistSongRelation(new PlaylistSongXRef(1, 1));
-
-        LiveData<PlaylistWithSongs> liveData = musicDao.getPlaylistsWithSongsLiveData(1);
-
-        final TestLifecycleOwner lifecycleOwner = new TestLifecycleOwner();
-        final TestObserver<PlaylistWithSongs> observer = new MyTestObserver<>();
-        TestUtil.observeOnMainThread(liveData, lifecycleOwner, observer);
-
-        assertThat(observer.get().songs.size(), is(1));
-        assertThat(observer.get().songs.get(0), is(mSong1));
-
-        observer.reset();
-
-        musicDao.addPlaylistSongRelation(new PlaylistSongXRef(1, 2));
-
-        assertThat(observer.get().songs.size(), is(2));
-        assertThat(observer.get().songs.get(0), is(mSong1));
-        assertThat(observer.get().songs.get(1), is(mSong2));
-
-        db.close();
-    }
-
-    @Test
-    public void withWithClause() throws ExecutionException, InterruptedException,
-            TimeoutException {
-        LiveData<List<String>> actual =
-                mWithClauseDao.getUsersWithFactorialIdsLiveData(0);
-        List<String> expected = new ArrayList<>();
-
-        final TestLifecycleOwner lifecycleOwner = new TestLifecycleOwner();
-        final TestObserver<List<String>> observer = new MyTestObserver<>();
-        TestUtil.observeOnMainThread(actual, lifecycleOwner, observer);
-        assertThat(observer.get(), is(expected));
-
-        observer.reset();
-        User user = new User();
-        user.setId(0);
-        user.setName("Zero");
-        mUserDao.insert(user);
-        assertThat(observer.get(), is(expected));
-
-        observer.reset();
-        user = new User();
-        user.setId(1);
-        user.setName("One");
-        mUserDao.insert(user);
-        expected.add("One");
-        assertThat(observer.get(), is(expected));
-
-        observer.reset();
-        user = new User();
-        user.setId(6);
-        user.setName("Six");
-        mUserDao.insert(user);
-        assertThat(observer.get(), is(expected));
-
-        actual = mWithClauseDao.getUsersWithFactorialIdsLiveData(3);
-        TestUtil.observeOnMainThread(actual, lifecycleOwner, observer);
-        expected.add("Six");
-        assertThat(observer.get(), is(expected));
-    }
-
-    @Test
-    public void withFtsTable() throws ExecutionException, InterruptedException, TimeoutException {
-        final Context context = ApplicationProvider.getApplicationContext();
-        final FtsTestDatabase db = Room.inMemoryDatabaseBuilder(context, FtsTestDatabase.class)
-                .build();
-        final MailDao mailDao = db.getMailDao();
-        final TestLifecycleOwner lifecycleOwner = new TestLifecycleOwner();
-
-        final TestObserver<List<Mail>> observer = new MyTestObserver<>();
-        LiveData<List<Mail>> liveData = mailDao.getLiveDataMail();
-
-        TestUtil.observeOnMainThread(liveData, lifecycleOwner, observer);
-        assertThat(observer.get(), is(Collections.emptyList()));
-
-        observer.reset();
-
-        Mail mail = TestUtil.createMail(1, "subject", "body");
-        mailDao.insert(mail);
-        assertThat(observer.get().get(0), is(mail));
-
-        db.close();
-    }
-
-    @Test
-    public void withExternalContentFtsTable()
-            throws ExecutionException, InterruptedException, TimeoutException {
-        final Context context = ApplicationProvider.getApplicationContext();
-        final FtsTestDatabase db = Room.inMemoryDatabaseBuilder(context, FtsTestDatabase.class)
-                .build();
-        final SongDao songDao = db.getSongDao();
-        final TestLifecycleOwner lifecycleOwner = new TestLifecycleOwner();
-
-        final TestObserver<List<Song>> songObserver = new MyTestObserver<>();
-        final TestObserver<List<SongDescription>> songDescriptionObserver = new MyTestObserver<>();
-        LiveData<List<Song>> songData = songDao.getLiveDataSong();
-        LiveData<List<SongDescription>> songDescriptionData = songDao.getLiveDataSongDescription();
-        TestUtil.observeOnMainThread(songData, lifecycleOwner, songObserver);
-        TestUtil.observeOnMainThread(songDescriptionData, lifecycleOwner, songDescriptionObserver);
-
-        assertThat(songObserver.get(), is(Collections.emptyList()));
-        assertThat(songDescriptionObserver.get(), is(Collections.emptyList()));
-
-        songObserver.reset();
-        songDescriptionObserver.reset();
-
-        Song song1 = new Song(
-                1,
-                "Estamos Bien",
-                "Bad Bunny",
-                "X 100Pre",
-                208,
-                2018);
-
-        songDao.insert(song1);
-
-        assertThat(songObserver.get().get(0), is(song1));
-        assertThat(songDescriptionObserver.get().size(), is(1));
-
-        songObserver.reset();
-        songDescriptionObserver.reset();
-
-        InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
-            @Override
-            public void run() {
-                songDescriptionData.removeObserver(songDescriptionObserver);
-            }
-        });
-
-        Song song2 = new Song(
-                2,
-                "RLNDT",
-                "Bad Bunny",
-                "X 100Pre",
-                284,
-                2018);
-
-        songDao.insert(song2);
-
-        assertThat(songObserver.get().get(1), is(song2));
-
-        db.close();
-    }
-
-    @MediumTest
-    @Test
-    public void handleGc() throws ExecutionException, InterruptedException, TimeoutException {
-        LiveData<User> liveData = mUserDao.liveUserById(3);
-        final TestObserver<User> observer = new MyTestObserver<>();
-        final TestLifecycleOwner lifecycleOwner = new TestLifecycleOwner(Lifecycle.State.STARTED);
-        TestUtil.observeOnMainThread(liveData, lifecycleOwner, observer);
-        assertThat(observer.get(), is(nullValue()));
-        observer.reset();
-        final User user = TestUtil.createUser(3);
-        mUserDao.insert(user);
-        assertThat(observer.get(), is(notNullValue()));
-        observer.reset();
-        TestUtil.forceGc();
-        String name = UUID.randomUUID().toString();
-        mUserDao.updateById(3, name);
-        assertThat(observer.get().getName(), is(name));
-
-        // release references
-        lifecycleOwner.handleLifecycleEvent(Lifecycle.Event.ON_DESTROY);
-        WeakReference<LiveData> weakLiveData = new WeakReference<LiveData>(liveData);
-        //noinspection UnusedAssignment
-        liveData = null;
-        TestUtil.forceGc();
-        mUserDao.updateById(3, "Bar");
-        TestUtil.forceGc();
-        assertThat(weakLiveData.get(), nullValue());
-    }
-
-    @Test
-    public void handleGcWithObserveForever() throws TimeoutException, InterruptedException {
-        final AtomicReference<User> referenced = new AtomicReference<>();
-        Observer<User> observer = referenced::set;
-        AtomicReference<WeakReference<LiveData<User>>> liveDataReference = new AtomicReference<>();
-        InstrumentationRegistry.getInstrumentation().runOnMainSync(
-                () -> {
-                    LiveData<User> userLiveData = mUserDao.liveUserById(3);
-                    userLiveData.observeForever(observer);
-                    liveDataReference.set(new WeakReference<>(userLiveData));
-                });
-        User v1 = TestUtil.createUser(3);
-        mUserDao.insert(v1);
-        drain();
-        assertThat(referenced.get(), is(v1));
-        TestUtil.forceGc();
-        User v2 = TestUtil.createUser(3);
-        v2.setName("handle gc");
-        mUserDao.insertOrReplace(v2);
-        drain();
-        assertThat(referenced.get(), is(v2));
-        assertThat(liveDataReference.get().get(), notNullValue());
-        InstrumentationRegistry.getInstrumentation().runOnMainSync(
-                () -> liveDataReference.get().get().removeObserver(observer));
-        drain();
-        TestUtil.forceGc();
-        drain();
-        User v3 = TestUtil.createUser(3);
-        v3.setName("handle gc, get rid of LiveData");
-        mUserDao.insertOrReplace(v3);
-        drain();
-        assertThat(referenced.get(), is(v2));
-        assertThat(liveDataReference.get().get(), is(nullValue()));
-    }
-
-    @Test
-    public void booleanLiveData() throws ExecutionException, InterruptedException,
-            TimeoutException {
-        User user = TestUtil.createUser(3);
-        user.setAdmin(false);
-        LiveData<Boolean> adminLiveData = mUserDao.isAdminLiveData(3);
-        final TestLifecycleOwner lifecycleOwner = new TestLifecycleOwner();
-        final TestObserver<Boolean> observer = new MyTestObserver<>();
-        TestUtil.observeOnMainThread(adminLiveData, lifecycleOwner, observer);
-        assertThat(observer.get(), is(nullValue()));
-        mUserDao.insert(user);
-        assertThat(observer.get(), is(false));
-        user.setAdmin(true);
-        mUserDao.insertOrReplace(user);
-        assertThat(observer.get(), is(true));
-    }
-
-    private void drain() throws TimeoutException, InterruptedException {
-        mExecutorRule.drainTasks(1, TimeUnit.MINUTES);
-    }
-
-    private class MyTestObserver<T> extends TestObserver<T> {
-
-        @Override
-        protected void drain() throws TimeoutException, InterruptedException {
-            LiveDataQueryTest.this.drain();
-        }
-    }
-}
diff --git a/room3/integration-tests/testapp/src/androidTest/java/androidx/room3/integration/testapp/test/TestDatabaseTest.java b/room3/integration-tests/testapp/src/androidTest/java/androidx/room3/integration/testapp/test/TestDatabaseTest.java
index 7aa2bc7..95386ce 100644
--- a/room3/integration-tests/testapp/src/androidTest/java/androidx/room3/integration/testapp/test/TestDatabaseTest.java
+++ b/room3/integration-tests/testapp/src/androidTest/java/androidx/room3/integration/testapp/test/TestDatabaseTest.java
@@ -20,7 +20,6 @@
 
 import androidx.room3.Room;
 import androidx.room3.integration.testapp.TestDatabase;
-import androidx.room3.integration.testapp.dao.FunnyNamedDao;
 import androidx.room3.integration.testapp.dao.PagingSourceOnlyUserDao;
 import androidx.room3.integration.testapp.dao.PetCoupleDao;
 import androidx.room3.integration.testapp.dao.PetDao;
@@ -50,7 +49,6 @@
     protected ToyDao mToyDao;
     protected SpecificDogDao mSpecificDogDao;
     protected WithClauseDao mWithClauseDao;
-    protected FunnyNamedDao mFunnyNamedDao;
     protected RawDao mRawDao;
     protected UserHouseDao mUserHouseDao;
     protected RobotsDao mRobotsDao;
@@ -68,7 +66,6 @@
         mToyDao = mDatabase.getToyDao();
         mSpecificDogDao = mDatabase.getSpecificDogDao();
         mWithClauseDao = mDatabase.getWithClauseDao();
-        mFunnyNamedDao = mDatabase.getFunnyNamedDao();
         mRawDao = mDatabase.getRawDao();
         mUserHouseDao = mDatabase.getUserHouseDao();
         mRobotsDao = mDatabase.getRobotsDao();
diff --git a/room3/integration-tests/testapp/src/androidTest/java/androidx/room3/integration/testapp/vo/FunnyNamedEntity.java b/room3/integration-tests/testapp/src/androidTest/java/androidx/room3/integration/testapp/vo/FunnyNamedEntity.java
deleted file mode 100644
index 9b52389..0000000
--- a/room3/integration-tests/testapp/src/androidTest/java/androidx/room3/integration/testapp/vo/FunnyNamedEntity.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Copyright (C) 2017 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 androidx.room3.integration.testapp.vo;
-
-import androidx.room3.ColumnInfo;
-import androidx.room3.Entity;
-import androidx.room3.PrimaryKey;
-
-/**
- * An entity that was weird names
- */
-@Entity(tableName = FunnyNamedEntity.TABLE_NAME)
-public class FunnyNamedEntity {
-    public static final String TABLE_NAME = "funny but not so funny";
-    public static final String COLUMN_ID = "_this $is id$";
-    public static final String COLUMN_VALUE = "unlikely-Ωşå¨ıünames";
-    @PrimaryKey(autoGenerate = true)
-    @ColumnInfo(name = COLUMN_ID)
-    private int mId;
-    @ColumnInfo(name = COLUMN_VALUE)
-    private String mValue;
-
-    public FunnyNamedEntity(int id, String value) {
-        mId = id;
-        mValue = value;
-    }
-
-    public int getId() {
-        return mId;
-    }
-
-    public void setId(int id) {
-        mId = id;
-    }
-
-    public String getValue() {
-        return mValue;
-    }
-
-    public void setValue(String value) {
-        mValue = value;
-    }
-
-    @Override
-    public boolean equals(Object o) {
-        if (this == o) return true;
-        if (o == null || getClass() != o.getClass()) return false;
-
-        FunnyNamedEntity entity = (FunnyNamedEntity) o;
-
-        if (mId != entity.mId) return false;
-        return mValue != null ? mValue.equals(entity.mValue) : entity.mValue == null;
-    }
-
-    @Override
-    public int hashCode() {
-        int result = mId;
-        result = 31 * result + (mValue != null ? mValue.hashCode() : 0);
-        return result;
-    }
-}
diff --git a/room3/room3-runtime/build.gradle b/room3/room3-runtime/build.gradle
index e024559..efd68c3 100644
--- a/room3/room3-runtime/build.gradle
+++ b/room3/room3-runtime/build.gradle
@@ -153,7 +153,7 @@
                 implementation("androidx.annotation:annotation-experimental:1.5.0")
             }
         }
-        androidUnitTest {
+        androidHostTest {
             dependsOn(commonTest)
             dependencies {
                 implementation("androidx.arch.core:core-testing:2.2.0")
diff --git a/room3/room3-runtime/src/androidUnitTest/kotlin/androidx/room3/BuilderTest.kt b/room3/room3-runtime/src/androidHostTest/kotlin/androidx/room3/BuilderTest.kt
similarity index 100%
rename from room3/room3-runtime/src/androidUnitTest/kotlin/androidx/room3/BuilderTest.kt
rename to room3/room3-runtime/src/androidHostTest/kotlin/androidx/room3/BuilderTest.kt
diff --git a/room3/room3-runtime/src/androidUnitTest/kotlin/androidx/room3/BuilderTest_TestDatabase_Impl.kt b/room3/room3-runtime/src/androidHostTest/kotlin/androidx/room3/BuilderTest_TestDatabase_Impl.kt
similarity index 100%
rename from room3/room3-runtime/src/androidUnitTest/kotlin/androidx/room3/BuilderTest_TestDatabase_Impl.kt
rename to room3/room3-runtime/src/androidHostTest/kotlin/androidx/room3/BuilderTest_TestDatabase_Impl.kt
diff --git a/room3/room3-runtime/src/androidUnitTest/kotlin/androidx/room3/BuilderTest_TestDatabase_InstantiateImpl.kt b/room3/room3-runtime/src/androidHostTest/kotlin/androidx/room3/BuilderTest_TestDatabase_InstantiateImpl.kt
similarity index 100%
rename from room3/room3-runtime/src/androidUnitTest/kotlin/androidx/room3/BuilderTest_TestDatabase_InstantiateImpl.kt
rename to room3/room3-runtime/src/androidHostTest/kotlin/androidx/room3/BuilderTest_TestDatabase_InstantiateImpl.kt
diff --git a/room3/room3-runtime/src/androidUnitTest/kotlin/androidx/room3/InvalidationLiveDataContainerTest.kt b/room3/room3-runtime/src/androidHostTest/kotlin/androidx/room3/InvalidationLiveDataContainerTest.kt
similarity index 100%
rename from room3/room3-runtime/src/androidUnitTest/kotlin/androidx/room3/InvalidationLiveDataContainerTest.kt
rename to room3/room3-runtime/src/androidHostTest/kotlin/androidx/room3/InvalidationLiveDataContainerTest.kt
diff --git a/room3/room3-runtime/src/androidUnitTest/kotlin/androidx/room3/InvalidationTrackerTest.kt b/room3/room3-runtime/src/androidHostTest/kotlin/androidx/room3/InvalidationTrackerTest.kt
similarity index 100%
rename from room3/room3-runtime/src/androidUnitTest/kotlin/androidx/room3/InvalidationTrackerTest.kt
rename to room3/room3-runtime/src/androidHostTest/kotlin/androidx/room3/InvalidationTrackerTest.kt
diff --git a/room3/room3-runtime/src/androidUnitTest/kotlin/androidx/room3/MigrationTest.kt b/room3/room3-runtime/src/androidHostTest/kotlin/androidx/room3/MigrationTest.kt
similarity index 100%
rename from room3/room3-runtime/src/androidUnitTest/kotlin/androidx/room3/MigrationTest.kt
rename to room3/room3-runtime/src/androidHostTest/kotlin/androidx/room3/MigrationTest.kt
diff --git a/room3/room3-runtime/src/androidUnitTest/kotlin/androidx/room3/ObservedTableStatesTest.kt b/room3/room3-runtime/src/androidHostTest/kotlin/androidx/room3/ObservedTableStatesTest.kt
similarity index 100%
rename from room3/room3-runtime/src/androidUnitTest/kotlin/androidx/room3/ObservedTableStatesTest.kt
rename to room3/room3-runtime/src/androidHostTest/kotlin/androidx/room3/ObservedTableStatesTest.kt
diff --git a/room3/room3-runtime/src/androidUnitTest/kotlin/androidx/room3/RoomSQLiteQueryTest.kt b/room3/room3-runtime/src/androidHostTest/kotlin/androidx/room3/RoomSQLiteQueryTest.kt
similarity index 100%
rename from room3/room3-runtime/src/androidUnitTest/kotlin/androidx/room3/RoomSQLiteQueryTest.kt
rename to room3/room3-runtime/src/androidHostTest/kotlin/androidx/room3/RoomSQLiteQueryTest.kt
diff --git a/room3/room3-runtime/src/androidUnitTest/kotlin/androidx/room3/SharedSQLiteStatementTest.kt b/room3/room3-runtime/src/androidHostTest/kotlin/androidx/room3/SharedSQLiteStatementTest.kt
similarity index 100%
rename from room3/room3-runtime/src/androidUnitTest/kotlin/androidx/room3/SharedSQLiteStatementTest.kt
rename to room3/room3-runtime/src/androidHostTest/kotlin/androidx/room3/SharedSQLiteStatementTest.kt
diff --git a/room3/room3-runtime/src/androidUnitTest/kotlin/androidx/room3/TransactionExecutorTest.kt b/room3/room3-runtime/src/androidHostTest/kotlin/androidx/room3/TransactionExecutorTest.kt
similarity index 100%
rename from room3/room3-runtime/src/androidUnitTest/kotlin/androidx/room3/TransactionExecutorTest.kt
rename to room3/room3-runtime/src/androidHostTest/kotlin/androidx/room3/TransactionExecutorTest.kt
diff --git a/room3/room3-runtime/src/androidUnitTest/kotlin/androidx/room3/support/PrePackagedCopyOpenHelperTest.kt b/room3/room3-runtime/src/androidHostTest/kotlin/androidx/room3/support/PrePackagedCopyOpenHelperTest.kt
similarity index 100%
rename from room3/room3-runtime/src/androidUnitTest/kotlin/androidx/room3/support/PrePackagedCopyOpenHelperTest.kt
rename to room3/room3-runtime/src/androidHostTest/kotlin/androidx/room3/support/PrePackagedCopyOpenHelperTest.kt
diff --git a/room3/room3-runtime/src/androidUnitTest/kotlin/androidx/room3/util/ByteArrayWrapperTest.kt b/room3/room3-runtime/src/androidHostTest/kotlin/androidx/room3/util/ByteArrayWrapperTest.kt
similarity index 100%
rename from room3/room3-runtime/src/androidUnitTest/kotlin/androidx/room3/util/ByteArrayWrapperTest.kt
rename to room3/room3-runtime/src/androidHostTest/kotlin/androidx/room3/util/ByteArrayWrapperTest.kt
diff --git a/room3/room3-runtime/src/androidUnitTest/kotlin/androidx/room3/util/CursorUtilTest.kt b/room3/room3-runtime/src/androidHostTest/kotlin/androidx/room3/util/CursorUtilTest.kt
similarity index 100%
rename from room3/room3-runtime/src/androidUnitTest/kotlin/androidx/room3/util/CursorUtilTest.kt
rename to room3/room3-runtime/src/androidHostTest/kotlin/androidx/room3/util/CursorUtilTest.kt
diff --git a/room3/room3-runtime/src/androidUnitTest/kotlin/androidx/room3/util/FtsTableInfoTest.kt b/room3/room3-runtime/src/androidHostTest/kotlin/androidx/room3/util/FtsTableInfoTest.kt
similarity index 100%
rename from room3/room3-runtime/src/androidUnitTest/kotlin/androidx/room3/util/FtsTableInfoTest.kt
rename to room3/room3-runtime/src/androidHostTest/kotlin/androidx/room3/util/FtsTableInfoTest.kt
diff --git a/room3/room3-runtime/src/androidUnitTest/kotlin/androidx/room3/util/StringUtilTest.java b/room3/room3-runtime/src/androidHostTest/kotlin/androidx/room3/util/StringUtilTest.java
similarity index 100%
rename from room3/room3-runtime/src/androidUnitTest/kotlin/androidx/room3/util/StringUtilTest.java
rename to room3/room3-runtime/src/androidHostTest/kotlin/androidx/room3/util/StringUtilTest.java
diff --git a/room3/room3-runtime/src/androidUnitTest/kotlin/androidx/room3/util/UUIDUtilTest.kt b/room3/room3-runtime/src/androidHostTest/kotlin/androidx/room3/util/UUIDUtilTest.kt
similarity index 100%
rename from room3/room3-runtime/src/androidUnitTest/kotlin/androidx/room3/util/UUIDUtilTest.kt
rename to room3/room3-runtime/src/androidHostTest/kotlin/androidx/room3/util/UUIDUtilTest.kt
diff --git a/room3/room3-runtime/src/androidUnitTest/resources/mockito-extensions/org.mockito.plugins.MockMaker b/room3/room3-runtime/src/androidHostTest/resources/mockito-extensions/org.mockito.plugins.MockMaker
similarity index 100%
rename from room3/room3-runtime/src/androidUnitTest/resources/mockito-extensions/org.mockito.plugins.MockMaker
rename to room3/room3-runtime/src/androidHostTest/resources/mockito-extensions/org.mockito.plugins.MockMaker
diff --git a/savedstate/savedstate-testing/build.gradle b/savedstate/savedstate-testing/build.gradle
index 66d47d2..b699a6e 100644
--- a/savedstate/savedstate-testing/build.gradle
+++ b/savedstate/savedstate-testing/build.gradle
@@ -78,7 +78,7 @@
             }
         }
 
-        androidUnitTest {
+        androidHostTest {
             dependsOn(jvmTest)
         }
 
diff --git a/savedstate/savedstate/build.gradle b/savedstate/savedstate/build.gradle
index 4b6faac..67dd61c 100644
--- a/savedstate/savedstate/build.gradle
+++ b/savedstate/savedstate/build.gradle
@@ -78,7 +78,7 @@
             }
         }
 
-        androidUnitTest {
+        androidHostTest {
             dependsOn(jvmTest)
             dependencies {
             }
diff --git a/savedstate/savedstate/src/androidUnitTest/kotlin/androidx/savedstate/RobolectricTest.android.kt b/savedstate/savedstate/src/androidHostTest/kotlin/androidx/savedstate/RobolectricTest.android.kt
similarity index 100%
rename from savedstate/savedstate/src/androidUnitTest/kotlin/androidx/savedstate/RobolectricTest.android.kt
rename to savedstate/savedstate/src/androidHostTest/kotlin/androidx/savedstate/RobolectricTest.android.kt
diff --git a/savedstate/savedstate/src/androidUnitTest/kotlin/androidx/savedstate/SavedStateAndroidTest.android.kt b/savedstate/savedstate/src/androidHostTest/kotlin/androidx/savedstate/SavedStateAndroidTest.android.kt
similarity index 100%
rename from savedstate/savedstate/src/androidUnitTest/kotlin/androidx/savedstate/SavedStateAndroidTest.android.kt
rename to savedstate/savedstate/src/androidHostTest/kotlin/androidx/savedstate/SavedStateAndroidTest.android.kt
diff --git a/savedstate/savedstate/src/androidUnitTest/kotlin/androidx/savedstate/SavedStateCodecAndroidTest.android.kt b/savedstate/savedstate/src/androidHostTest/kotlin/androidx/savedstate/SavedStateCodecAndroidTest.android.kt
similarity index 100%
rename from savedstate/savedstate/src/androidUnitTest/kotlin/androidx/savedstate/SavedStateCodecAndroidTest.android.kt
rename to savedstate/savedstate/src/androidHostTest/kotlin/androidx/savedstate/SavedStateCodecAndroidTest.android.kt
diff --git a/savedstate/savedstate/src/androidUnitTest/kotlin/androidx/savedstate/serialization/SavedStateCodecTestUtils.android.kt b/savedstate/savedstate/src/androidHostTest/kotlin/androidx/savedstate/serialization/SavedStateCodecTestUtils.android.kt
similarity index 100%
rename from savedstate/savedstate/src/androidUnitTest/kotlin/androidx/savedstate/serialization/SavedStateCodecTestUtils.android.kt
rename to savedstate/savedstate/src/androidHostTest/kotlin/androidx/savedstate/serialization/SavedStateCodecTestUtils.android.kt
diff --git a/sqlite/sqlite/build.gradle b/sqlite/sqlite/build.gradle
index 485fb3a..c70b3d6 100644
--- a/sqlite/sqlite/build.gradle
+++ b/sqlite/sqlite/build.gradle
@@ -60,7 +60,7 @@
         androidMain {
             dependsOn(commonMain)
         }
-        androidUnitTest {
+        androidHostTest {
             dependsOn(commonTest)
             dependencies {
                 implementation(libs.junit)
diff --git a/sqlite/sqlite/src/androidUnitTest/kotlin/androidx/sqlite/db/SimpleSQLiteQueryTest.kt b/sqlite/sqlite/src/androidHostTest/kotlin/androidx/sqlite/db/SimpleSQLiteQueryTest.kt
similarity index 100%
rename from sqlite/sqlite/src/androidUnitTest/kotlin/androidx/sqlite/db/SimpleSQLiteQueryTest.kt
rename to sqlite/sqlite/src/androidHostTest/kotlin/androidx/sqlite/db/SimpleSQLiteQueryTest.kt
diff --git a/sqlite/sqlite/src/androidUnitTest/kotlin/androidx/sqlite/db/SupportSQLiteQueryBuilderTest.kt b/sqlite/sqlite/src/androidHostTest/kotlin/androidx/sqlite/db/SupportSQLiteQueryBuilderTest.kt
similarity index 100%
rename from sqlite/sqlite/src/androidUnitTest/kotlin/androidx/sqlite/db/SupportSQLiteQueryBuilderTest.kt
rename to sqlite/sqlite/src/androidHostTest/kotlin/androidx/sqlite/db/SupportSQLiteQueryBuilderTest.kt
diff --git a/wear/compose/compose-material3/src/main/res/values-fa/strings.xml b/wear/compose/compose-material3/src/main/res/values-fa/strings.xml
index 3066fd5..3b56ae4 100644
--- a/wear/compose/compose-material3/src/main/res/values-fa/strings.xml
+++ b/wear/compose/compose-material3/src/main/res/values-fa/strings.xml
@@ -45,7 +45,7 @@
     <string name="wear_m3c_slider_decrease_content_description" msgid="8242572466064289486">"کاهش دادن"</string>
     <string name="wear_m3c_slider_increase_content_description" msgid="3329631766954416834">"افزایش دادن"</string>
     <string name="wear_m3c_alert_dialog_content_description_confirm_button" msgid="7776845597891182382">"تأیید کردن"</string>
-    <string name="wear_m3c_alert_dialog_content_description_dismiss_button" msgid="3572467833850785688">"بستن پنجره"</string>
+    <string name="wear_m3c_alert_dialog_content_description_dismiss_button" msgid="3572467833850785688">"بستن"</string>
     <string name="wear_m3c_open_on_phone" msgid="3200727397161392122">"تلفن را بررسی کنید"</string>
     <string name="wear_m3c_open_on_phone_icon_content_description" msgid="5953380527505012363">"نماد بررسی تلفن"</string>
 </resources>
diff --git a/wear/compose/integration-tests/demos/src/main/java/androidx/wear/compose/integration/demos/ButtonDemo.kt b/wear/compose/integration-tests/demos/src/main/java/androidx/wear/compose/integration/demos/ButtonDemo.kt
index ff608db..107296f 100644
--- a/wear/compose/integration-tests/demos/src/main/java/androidx/wear/compose/integration/demos/ButtonDemo.kt
+++ b/wear/compose/integration-tests/demos/src/main/java/androidx/wear/compose/integration/demos/ButtonDemo.kt
@@ -119,7 +119,7 @@
                     colors = ButtonDefaults.secondaryButtonColors(),
                     enabled = enabled,
                 ) {
-                    DemoIcon(R.drawable.ic_accessibility_24px)
+                    DemoIcon(R.drawable.icon_accessibility_24px)
                 }
                 Button(
                     onClick = {
@@ -128,7 +128,7 @@
                     colors = ButtonDefaults.primaryButtonColors(),
                     enabled = enabled,
                 ) {
-                    DemoIcon(R.drawable.ic_accessibility_24px)
+                    DemoIcon(R.drawable.icon_accessibility_24px)
                 }
             }
         }
@@ -150,7 +150,7 @@
                     modifier = Modifier.size(ButtonDefaults.SmallButtonSize),
                     enabled = enabled,
                 ) {
-                    DemoIcon(R.drawable.ic_accessibility_24px)
+                    DemoIcon(R.drawable.icon_accessibility_24px)
                 }
                 Button(
                     onClick = {
@@ -165,7 +165,7 @@
                     modifier = Modifier.size(ButtonDefaults.LargeButtonSize),
                     enabled = enabled,
                 ) {
-                    DemoIcon(R.drawable.ic_accessibility_24px)
+                    DemoIcon(R.drawable.icon_accessibility_24px)
                 }
             }
         }
@@ -181,7 +181,7 @@
                     },
                     enabled = enabled,
                 ) {
-                    DemoIcon(R.drawable.ic_accessibility_24px)
+                    DemoIcon(R.drawable.icon_accessibility_24px)
                 }
                 OutlinedCompactButton(
                     onClick = {
@@ -194,7 +194,7 @@
                     },
                     enabled = enabled,
                 ) {
-                    DemoIcon(R.drawable.ic_accessibility_24px)
+                    DemoIcon(R.drawable.icon_accessibility_24px)
                 }
             }
         }
@@ -212,7 +212,7 @@
                     enabled = enabled,
                     shape = CutCornerShape(4.dp),
                 ) {
-                    DemoIcon(R.drawable.ic_accessibility_24px)
+                    DemoIcon(R.drawable.icon_accessibility_24px)
                 }
                 CompactButton(
                     onClick = {
@@ -228,7 +228,7 @@
                     enabled = enabled,
                     shape = CutCornerShape(4.dp),
                 ) {
-                    DemoIcon(R.drawable.ic_accessibility_24px)
+                    DemoIcon(R.drawable.icon_accessibility_24px)
                 }
             }
         }
@@ -250,7 +250,7 @@
                     enabled = enabled,
                     shape = CutCornerShape(4.dp),
                 ) {
-                    DemoIcon(R.drawable.ic_accessibility_24px)
+                    DemoIcon(R.drawable.icon_accessibility_24px)
                 }
                 Button(
                     onClick = {
@@ -267,7 +267,7 @@
                         ),
                     enabled = enabled,
                 ) {
-                    DemoIcon(R.drawable.ic_accessibility_24px)
+                    DemoIcon(R.drawable.icon_accessibility_24px)
                 }
             }
         }
@@ -286,7 +286,7 @@
                     onCheckedChange = { enabled = it },
                     modifier = Modifier.size(ButtonDefaults.SmallButtonSize),
                 ) {
-                    DemoIcon(R.drawable.ic_check_24px)
+                    DemoIcon(R.drawable.icon_check_24px)
                 }
             }
         }
@@ -309,14 +309,14 @@
                     colors = ButtonDefaults.primaryButtonColors(),
                     modifier = Modifier.size(ButtonDefaults.LargeButtonSize),
                 ) {
-                    DemoIcon(resourceId = R.drawable.ic_play, contentDescription = "Play")
+                    DemoIcon(resourceId = R.drawable.icon_play, contentDescription = "Play")
                 }
                 Button(
                     onClick = {},
                     colors = ButtonDefaults.secondaryButtonColors(),
                     modifier = Modifier.size(ButtonDefaults.LargeButtonSize),
                 ) {
-                    DemoIcon(resourceId = R.drawable.ic_play, contentDescription = "Play")
+                    DemoIcon(resourceId = R.drawable.icon_play, contentDescription = "Play")
                 }
             }
         }
@@ -327,7 +327,7 @@
                     colors = ButtonDefaults.iconButtonColors(),
                     modifier = Modifier.size(ButtonDefaults.LargeButtonSize),
                 ) {
-                    DemoIcon(resourceId = R.drawable.ic_skip_next, contentDescription = "Skip")
+                    DemoIcon(resourceId = R.drawable.icon_skip_next, contentDescription = "Skip")
                 }
                 Spacer(Modifier.width(ButtonDefaults.LargeButtonSize))
             }
@@ -337,17 +337,20 @@
         item {
             Row(horizontalArrangement = Arrangement.spacedBy(16.dp)) {
                 Button(onClick = {}, colors = ButtonDefaults.primaryButtonColors()) {
-                    DemoIcon(resourceId = R.drawable.ic_check_24px, contentDescription = "Tick")
+                    DemoIcon(resourceId = R.drawable.icon_check_24px, contentDescription = "Tick")
                 }
                 Button(onClick = {}, colors = ButtonDefaults.secondaryButtonColors()) {
-                    DemoIcon(resourceId = R.drawable.ic_clear_24px, contentDescription = "Cross")
+                    DemoIcon(resourceId = R.drawable.icon_clear_24px, contentDescription = "Cross")
                 }
             }
         }
         item {
             Row(horizontalArrangement = Arrangement.spacedBy(16.dp)) {
                 Button(onClick = {}, colors = ButtonDefaults.iconButtonColors()) {
-                    DemoIcon(resourceId = R.drawable.ic_devices_24, contentDescription = "Devices")
+                    DemoIcon(
+                        resourceId = R.drawable.icon_devices_24,
+                        contentDescription = "Devices",
+                    )
                 }
                 Spacer(Modifier.width(ButtonDefaults.DefaultButtonSize))
             }
@@ -361,14 +364,14 @@
                     colors = ButtonDefaults.primaryButtonColors(),
                     modifier = Modifier.size(ButtonDefaults.SmallButtonSize),
                 ) {
-                    DemoIcon(resourceId = R.drawable.ic_music_24, contentDescription = "Music")
+                    DemoIcon(resourceId = R.drawable.icon_music_24, contentDescription = "Music")
                 }
                 Button(
                     onClick = {},
                     colors = ButtonDefaults.secondaryButtonColors(),
                     modifier = Modifier.size(ButtonDefaults.SmallButtonSize),
                 ) {
-                    DemoIcon(resourceId = R.drawable.ic_mic_24, contentDescription = "Mic")
+                    DemoIcon(resourceId = R.drawable.icon_mic_24, contentDescription = "Mic")
                 }
             }
         }
@@ -379,7 +382,10 @@
                     colors = ButtonDefaults.iconButtonColors(),
                     modifier = Modifier.size(ButtonDefaults.SmallButtonSize),
                 ) {
-                    DemoIcon(resourceId = R.drawable.ic_volume_up_24px, contentDescription = "Vol")
+                    DemoIcon(
+                        resourceId = R.drawable.icon_volume_up_24px,
+                        contentDescription = "Vol",
+                    )
                 }
                 Spacer(Modifier.width(ButtonDefaults.SmallButtonSize))
             }
@@ -390,13 +396,13 @@
             Row(horizontalArrangement = Arrangement.spacedBy(16.dp)) {
                 CompactButton(onClick = {}, colors = ButtonDefaults.primaryButtonColors()) {
                     DemoIcon(
-                        resourceId = R.drawable.ic_arrow_left_modified,
+                        resourceId = R.drawable.icon_arrow_left_modified,
                         contentDescription = "Left",
                     )
                 }
                 CompactButton(onClick = {}, colors = ButtonDefaults.secondaryButtonColors()) {
                     DemoIcon(
-                        resourceId = R.drawable.ic_arrow_right_modified,
+                        resourceId = R.drawable.icon_arrow_right_modified,
                         contentDescription = "Right",
                     )
                 }
@@ -406,13 +412,13 @@
             Row(horizontalArrangement = Arrangement.spacedBy(16.dp)) {
                 CompactButton(onClick = {}, colors = ButtonDefaults.iconButtonColors()) {
                     DemoIcon(
-                        resourceId = R.drawable.ic_arrow_left_modified,
+                        resourceId = R.drawable.icon_arrow_left_modified,
                         contentDescription = "Left",
                     )
                 }
                 CompactButton(onClick = {}, colors = ButtonDefaults.iconButtonColors()) {
                     DemoIcon(
-                        resourceId = R.drawable.ic_arrow_right_modified,
+                        resourceId = R.drawable.icon_arrow_right_modified,
                         contentDescription = "Right",
                     )
                 }
diff --git a/wear/compose/integration-tests/demos/src/main/java/androidx/wear/compose/integration/demos/CardDemo.kt b/wear/compose/integration-tests/demos/src/main/java/androidx/wear/compose/integration/demos/CardDemo.kt
index 9e7016d..c09625e 100644
--- a/wear/compose/integration-tests/demos/src/main/java/androidx/wear/compose/integration/demos/CardDemo.kt
+++ b/wear/compose/integration-tests/demos/src/main/java/androidx/wear/compose/integration/demos/CardDemo.kt
@@ -91,7 +91,7 @@
                 appName = { Text("AppName") },
                 appImage = {
                     DemoImage(
-                        resourceId = R.drawable.ic_maps_icon,
+                        resourceId = R.drawable.icon_maps_icon,
                         size = CardDefaults.AppImageSize,
                     )
                 },
@@ -135,7 +135,7 @@
                 onClick = {},
                 title = {
                     DemoIcon(
-                        resourceId = R.drawable.ic_accessibility_24px,
+                        resourceId = R.drawable.icon_accessibility_24px,
                         size = CardDefaults.AppImageSize,
                     )
                     Spacer(Modifier.width(6.dp))
diff --git a/wear/compose/integration-tests/demos/src/main/java/androidx/wear/compose/integration/demos/ChipDemo.kt b/wear/compose/integration-tests/demos/src/main/java/androidx/wear/compose/integration/demos/ChipDemo.kt
index 770a957..1ff4332 100644
--- a/wear/compose/integration-tests/demos/src/main/java/androidx/wear/compose/integration/demos/ChipDemo.kt
+++ b/wear/compose/integration-tests/demos/src/main/java/androidx/wear/compose/integration/demos/ChipDemo.kt
@@ -113,7 +113,7 @@
                 label = "Label with icon",
                 enabled = enabled,
             ) {
-                DemoIcon(resourceId = R.drawable.ic_accessibility_24px)
+                DemoIcon(resourceId = R.drawable.icon_accessibility_24px)
             }
         }
         item {
@@ -123,7 +123,7 @@
                 label = "Long label to show truncation which does not fit into" + " 2 lines",
                 enabled = enabled,
             ) {
-                DemoIcon(resourceId = R.drawable.ic_accessibility_24px)
+                DemoIcon(resourceId = R.drawable.icon_accessibility_24px)
             }
         }
         item {
@@ -159,7 +159,7 @@
                 secondaryLabel = "Secondary Label",
                 enabled = enabled,
             ) {
-                DemoIcon(resourceId = R.drawable.ic_accessibility_24px)
+                DemoIcon(resourceId = R.drawable.icon_accessibility_24px)
             }
         }
         item {
@@ -171,7 +171,7 @@
                     "Long secondary label to show truncation which does not fit into" + "1 line",
                 enabled = enabled,
             ) {
-                DemoIcon(resourceId = R.drawable.ic_accessibility_24px)
+                DemoIcon(resourceId = R.drawable.icon_accessibility_24px)
             }
         }
         item {
@@ -239,7 +239,7 @@
                 style = chipStyle,
             ) {
                 DemoIcon(
-                    resourceId = R.drawable.ic_accessibility_24px,
+                    resourceId = R.drawable.icon_accessibility_24px,
                     modifier =
                         Modifier.size(ChipDefaults.SmallIconSize)
                             .wrapContentSize(align = Alignment.Center),
@@ -255,7 +255,7 @@
                 style = chipStyle,
             ) {
                 DemoIcon(
-                    resourceId = R.drawable.ic_accessibility_24px,
+                    resourceId = R.drawable.icon_accessibility_24px,
                     modifier =
                         Modifier.size(ChipDefaults.SmallIconSize)
                             .wrapContentSize(align = Alignment.Center),
@@ -330,7 +330,7 @@
                 colors = ChipDefaults.secondaryChipColors(),
                 enabled = enabled,
             ) {
-                DemoImage(resourceId = R.drawable.ic_maps_icon)
+                DemoImage(resourceId = R.drawable.icon_maps_icon)
             }
         }
         item {
@@ -341,7 +341,7 @@
                 colors = ChipDefaults.gradientBackgroundChipColors(),
                 enabled = enabled,
             ) {
-                DemoImage(resourceId = R.drawable.ic_maps_icon)
+                DemoImage(resourceId = R.drawable.icon_maps_icon)
             }
         }
         item {
@@ -358,7 +358,7 @@
                     ),
                 enabled = enabled,
             ) {
-                DemoImage(resourceId = R.drawable.ic_maps_icon)
+                DemoImage(resourceId = R.drawable.icon_maps_icon)
             }
         }
         item {
@@ -423,7 +423,7 @@
                     label = "Standard chip with ",
                     secondaryLabel = "Secondary Label",
                 ) {
-                    DemoIcon(resourceId = R.drawable.ic_accessibility_24px)
+                    DemoIcon(resourceId = R.drawable.icon_accessibility_24px)
                 }
             }
             item {
@@ -439,7 +439,7 @@
                     },
                     icon = {
                         DemoIcon(
-                            resourceId = R.drawable.ic_accessibility_24px,
+                            resourceId = R.drawable.icon_accessibility_24px,
                             modifier = Modifier.size(ChipDefaults.SmallIconSize),
                         )
                     },
@@ -465,7 +465,7 @@
                     secondaryLabel = "Default gradient color",
                     colors = ChipDefaults.gradientBackgroundChipColors(),
                 ) {
-                    DemoImage(resourceId = R.drawable.ic_maps_icon)
+                    DemoImage(resourceId = R.drawable.icon_maps_icon)
                 }
             }
         }
@@ -490,7 +490,7 @@
                     colors = ChipDefaults.primaryChipColors(),
                     enabled = enabled,
                 ) {
-                    DemoIcon(resourceId = R.drawable.ic_accessibility_24px)
+                    DemoIcon(resourceId = R.drawable.icon_accessibility_24px)
                 }
             }
         }
@@ -509,7 +509,7 @@
                         ChipDefaults.secondaryChipColors(contentColor = AlternatePrimaryColor2),
                     icon = {
                         DemoIcon(
-                            resourceId = R.drawable.ic_accessibility_24px,
+                            resourceId = R.drawable.icon_accessibility_24px,
                             modifier = Modifier.size(ChipDefaults.IconSize),
                         )
                     },
@@ -533,7 +533,7 @@
                         ChipDefaults.secondaryChipColors(contentColor = AlternatePrimaryColor3),
                     icon = {
                         DemoIcon(
-                            resourceId = R.drawable.ic_accessibility_24px,
+                            resourceId = R.drawable.icon_accessibility_24px,
                             modifier = Modifier.size(ChipDefaults.IconSize),
                         )
                     },
diff --git a/wear/compose/integration-tests/demos/src/main/java/androidx/wear/compose/integration/demos/CurvedLayoutDemo.kt b/wear/compose/integration-tests/demos/src/main/java/androidx/wear/compose/integration/demos/CurvedLayoutDemo.kt
index c2ed18c..cbdd288 100644
--- a/wear/compose/integration-tests/demos/src/main/java/androidx/wear/compose/integration/demos/CurvedLayoutDemo.kt
+++ b/wear/compose/integration-tests/demos/src/main/java/androidx/wear/compose/integration/demos/CurvedLayoutDemo.kt
@@ -423,7 +423,7 @@
             angularDirection = CurvedDirection.Angular.CounterClockwise,
         ) {
             curvedComposable(rotationLocked = true) { Text("Foo", color = Color.White) }
-            listOf(R.drawable.ic_skip_previous, R.drawable.ic_play, R.drawable.ic_skip_next)
+            listOf(R.drawable.icon_skip_previous, R.drawable.icon_play, R.drawable.icon_skip_next)
                 .forEach {
                     curvedComposable(
                         modifier = CurvedModifier.angularSize(40f),
diff --git a/wear/compose/integration-tests/demos/src/main/java/androidx/wear/compose/integration/demos/DialogDemo.kt b/wear/compose/integration-tests/demos/src/main/java/androidx/wear/compose/integration/demos/DialogDemo.kt
index cdb07a2..0f0af39 100644
--- a/wear/compose/integration-tests/demos/src/main/java/androidx/wear/compose/integration/demos/DialogDemo.kt
+++ b/wear/compose/integration-tests/demos/src/main/java/androidx/wear/compose/integration/demos/DialogDemo.kt
@@ -70,7 +70,7 @@
                     onClick = { showDialog = false },
                     colors = ButtonDefaults.secondaryButtonColors(),
                 ) {
-                    DemoIcon(resourceId = R.drawable.ic_clear_24px, contentDescription = "No")
+                    DemoIcon(resourceId = R.drawable.icon_clear_24px, contentDescription = "No")
                 }
             },
             positiveButton = {
@@ -78,7 +78,7 @@
                     onClick = { showDialog = false },
                     colors = ButtonDefaults.primaryButtonColors(),
                 ) {
-                    DemoIcon(resourceId = R.drawable.ic_check_24px, contentDescription = "Yes")
+                    DemoIcon(resourceId = R.drawable.icon_check_24px, contentDescription = "Yes")
                 }
             },
             scrollState = scrollState,
@@ -107,7 +107,7 @@
             scrollState = scrollState,
             icon = {
                 DemoIcon(
-                    resourceId = R.drawable.ic_baseline_location_on_24,
+                    resourceId = R.drawable.icon_baseline_location_on_24,
                     contentDescription = "Location",
                 )
             },
@@ -123,7 +123,7 @@
                     onClick = { showDialog = false },
                     colors = ButtonDefaults.secondaryButtonColors(),
                 ) {
-                    DemoIcon(resourceId = R.drawable.ic_clear_24px, contentDescription = "Cross")
+                    DemoIcon(resourceId = R.drawable.icon_clear_24px, contentDescription = "Cross")
                 }
             },
             positiveButton = {
@@ -131,7 +131,7 @@
                     onClick = { showDialog = false },
                     colors = ButtonDefaults.primaryButtonColors(),
                 ) {
-                    DemoIcon(resourceId = R.drawable.ic_check_24px, contentDescription = "Tick")
+                    DemoIcon(resourceId = R.drawable.icon_check_24px, contentDescription = "Tick")
                 }
             },
         )
@@ -155,7 +155,7 @@
                 scrollState = scrollState,
                 icon = {
                     DemoIcon(
-                        resourceId = R.drawable.ic_baseline_location_on_24,
+                        resourceId = R.drawable.icon_baseline_location_on_24,
                         contentDescription = "Location",
                     )
                 },
@@ -172,7 +172,7 @@
                         colors = ButtonDefaults.secondaryButtonColors(),
                     ) {
                         DemoIcon(
-                            resourceId = R.drawable.ic_clear_24px,
+                            resourceId = R.drawable.icon_clear_24px,
                             contentDescription = "Cross",
                         )
                     }
@@ -182,7 +182,10 @@
                         onClick = { showDialog = false },
                         colors = ButtonDefaults.primaryButtonColors(),
                     ) {
-                        DemoIcon(resourceId = R.drawable.ic_check_24px, contentDescription = "Tick")
+                        DemoIcon(
+                            resourceId = R.drawable.icon_check_24px,
+                            contentDescription = "Tick",
+                        )
                     }
                 },
             )
@@ -203,7 +206,10 @@
         Alert(
             scrollState = scrollState,
             icon = {
-                DemoIcon(resourceId = R.drawable.ic_baseline_error_24, contentDescription = "Error")
+                DemoIcon(
+                    resourceId = R.drawable.icon_baseline_error_24,
+                    contentDescription = "Error",
+                )
             },
             title = {
                 Text(
@@ -217,7 +223,7 @@
                 Chip(
                     icon = {
                         DemoIcon(
-                            resourceId = R.drawable.ic_baseline_settings_24,
+                            resourceId = R.drawable.icon_baseline_settings_24,
                             contentDescription = "Settings",
                         )
                     },
@@ -264,7 +270,10 @@
             item {
                 Chip(
                     icon = {
-                        DemoIcon(resourceId = R.drawable.ic_check_24px, contentDescription = "Tick")
+                        DemoIcon(
+                            resourceId = R.drawable.icon_check_24px,
+                            contentDescription = "Tick",
+                        )
                     },
                     label = { Text("Allow access") },
                     onClick = { showDialog = false },
@@ -275,7 +284,7 @@
                 Chip(
                     icon = {
                         DemoIcon(
-                            resourceId = R.drawable.ic_clear_24px,
+                            resourceId = R.drawable.icon_clear_24px,
                             contentDescription = "Cross",
                         )
                     },
@@ -297,7 +306,7 @@
             onTimeout = { showDialog = false },
             icon = {
                 DemoIcon(
-                    resourceId = R.drawable.ic_check_48px,
+                    resourceId = R.drawable.icon_check_48px,
                     size = 48.dp,
                     contentDescription = "Tick",
                 )
diff --git a/wear/compose/integration-tests/demos/src/main/java/androidx/wear/compose/integration/demos/ExpandableDemo.kt b/wear/compose/integration-tests/demos/src/main/java/androidx/wear/compose/integration/demos/ExpandableDemo.kt
index 7980b90..a954bd4 100644
--- a/wear/compose/integration-tests/demos/src/main/java/androidx/wear/compose/integration/demos/ExpandableDemo.kt
+++ b/wear/compose/integration-tests/demos/src/main/java/androidx/wear/compose/integration/demos/ExpandableDemo.kt
@@ -170,7 +170,7 @@
             label = {
                 Text("Show More")
                 Spacer(Modifier.size(6.dp))
-                DemoIcon(resourceId = R.drawable.ic_expand_more_24, contentDescription = "Expand")
+                DemoIcon(resourceId = R.drawable.icon_expand_more_24, contentDescription = "Expand")
             },
             onClick = { state.expanded = true },
             border = if (outline) ChipDefaults.outlinedChipBorder() else ChipDefaults.chipBorder(),
@@ -193,6 +193,6 @@
         label = { Text(label) },
         onClick = {},
         secondaryLabel = { Text("line 2 - Secondary") },
-        icon = { DemoIcon(resourceId = R.drawable.ic_play) },
+        icon = { DemoIcon(resourceId = R.drawable.icon_play) },
         colors = ChipDefaults.primaryChipColors(backgroundColor = color),
     )
diff --git a/wear/compose/integration-tests/demos/src/main/java/androidx/wear/compose/integration/demos/PlaceholderDemo.kt b/wear/compose/integration-tests/demos/src/main/java/androidx/wear/compose/integration/demos/PlaceholderDemo.kt
index 9336b51..9cf9804 100644
--- a/wear/compose/integration-tests/demos/src/main/java/androidx/wear/compose/integration/demos/PlaceholderDemo.kt
+++ b/wear/compose/integration-tests/demos/src/main/java/androidx/wear/compose/integration/demos/PlaceholderDemo.kt
@@ -141,7 +141,10 @@
             }
             item {
                 var label by remember { mutableStateOf("") }
-                ChipWithOverlaidPlaceholder(label = label, icon = R.drawable.ic_accessibility_24px)
+                ChipWithOverlaidPlaceholder(
+                    label = label,
+                    icon = R.drawable.icon_accessibility_24px,
+                )
                 LaunchedEffect(resetCount) {
                     label = ""
                     delay(3000)
@@ -150,7 +153,10 @@
             }
             item {
                 var label by remember { mutableStateOf("") }
-                ChipWithOverlaidPlaceholder(label = label, icon = R.drawable.ic_accessibility_24px)
+                ChipWithOverlaidPlaceholder(
+                    label = label,
+                    icon = R.drawable.icon_accessibility_24px,
+                )
                 LaunchedEffect(resetCount) {
                     label = ""
                     delay(3000)
@@ -195,7 +201,7 @@
                 var secondaryLabel by remember { mutableStateOf("") }
                 ChipWithOverlaidPlaceholder(
                     label = label,
-                    icon = R.drawable.ic_accessibility_24px,
+                    icon = R.drawable.icon_accessibility_24px,
                     secondaryLabel = secondaryLabel,
                 )
                 LaunchedEffect(resetCount) {
@@ -210,7 +216,7 @@
                 var label by remember { mutableStateOf("") }
                 ChipWithOverlaidPlaceholder(
                     label = label,
-                    icon = R.drawable.ic_accessibility_24px,
+                    icon = R.drawable.icon_accessibility_24px,
                     colors =
                         ChipDefaults.chipColors(
                             backgroundColor = MaterialTheme.colors.surface,
@@ -228,7 +234,7 @@
                 var secondaryLabel by remember { mutableStateOf("") }
                 ChipWithOverlaidPlaceholder(
                     label = label,
-                    icon = R.drawable.ic_accessibility_24px,
+                    icon = R.drawable.icon_accessibility_24px,
                     secondaryLabel = secondaryLabel,
                     colors = ChipDefaults.chipColors(backgroundColor = AlternatePrimaryColor2),
                 )
@@ -245,7 +251,7 @@
                 var secondaryLabel by remember { mutableStateOf("") }
                 ChipWithOverlaidPlaceholder(
                     label = label,
-                    icon = R.drawable.ic_accessibility_24px,
+                    icon = R.drawable.icon_accessibility_24px,
                     secondaryLabel = secondaryLabel,
                 )
                 LaunchedEffect(resetCount) {
diff --git a/wear/compose/integration-tests/demos/src/main/java/androidx/wear/compose/integration/demos/ProgressIndicatorDemo.kt b/wear/compose/integration-tests/demos/src/main/java/androidx/wear/compose/integration/demos/ProgressIndicatorDemo.kt
index ecfb9db..8ec405c 100644
--- a/wear/compose/integration-tests/demos/src/main/java/androidx/wear/compose/integration/demos/ProgressIndicatorDemo.kt
+++ b/wear/compose/integration-tests/demos/src/main/java/androidx/wear/compose/integration/demos/ProgressIndicatorDemo.kt
@@ -123,7 +123,7 @@
                     colors = ButtonDefaults.iconButtonColors(),
                 ) {
                     Icon(
-                        painter = painterResource(id = R.drawable.ic_skip_previous),
+                        painter = painterResource(id = R.drawable.icon_skip_previous),
                         contentDescription = "Previous",
                         modifier = Modifier.size(24.dp).wrapContentSize(align = Alignment.Center),
                     )
@@ -156,8 +156,8 @@
                         Icon(
                             painter =
                                 painterResource(
-                                    if (status == Status.Playing) R.drawable.ic_pause
-                                    else R.drawable.ic_play
+                                    if (status == Status.Playing) R.drawable.icon_pause
+                                    else R.drawable.icon_play
                                 ),
                             contentDescription = "Play",
                             modifier =
@@ -193,7 +193,7 @@
                     colors = ButtonDefaults.iconButtonColors(),
                 ) {
                     Icon(
-                        painter = painterResource(id = R.drawable.ic_skip_next),
+                        painter = painterResource(id = R.drawable.icon_skip_next),
                         contentDescription = "Next",
                         modifier = Modifier.size(24.dp).wrapContentSize(align = Alignment.Center),
                     )
@@ -228,7 +228,7 @@
                         modifier = Modifier.fillMaxSize(),
                     ) {
                         Icon(
-                            painter = painterResource(R.drawable.ic_play),
+                            painter = painterResource(R.drawable.icon_play),
                             contentDescription = "Play",
                             modifier =
                                 Modifier.size(24.dp).wrapContentSize(align = Alignment.Center),
@@ -254,7 +254,7 @@
                     colors = ButtonDefaults.iconButtonColors(),
                 ) {
                     Icon(
-                        painter = painterResource(id = R.drawable.ic_skip_next),
+                        painter = painterResource(id = R.drawable.icon_skip_next),
                         contentDescription = "Next",
                         modifier = Modifier.size(24.dp).wrapContentSize(align = Alignment.Center),
                     )
diff --git a/wear/compose/integration-tests/demos/src/main/java/androidx/wear/compose/integration/demos/ScalingLazyColumnDemo.kt b/wear/compose/integration-tests/demos/src/main/java/androidx/wear/compose/integration/demos/ScalingLazyColumnDemo.kt
index 1758b64..c510f5d 100644
--- a/wear/compose/integration-tests/demos/src/main/java/androidx/wear/compose/integration/demos/ScalingLazyColumnDemo.kt
+++ b/wear/compose/integration-tests/demos/src/main/java/androidx/wear/compose/integration/demos/ScalingLazyColumnDemo.kt
@@ -108,7 +108,7 @@
                 secondaryLabel = "Defaults",
                 colors = ChipDefaults.secondaryChipColors(),
             ) {
-                DemoImage(resourceId = R.drawable.ic_maps_icon)
+                DemoImage(resourceId = R.drawable.icon_maps_icon)
             }
         }
         item {
@@ -117,7 +117,7 @@
                 appName = { Text("AppName") },
                 appImage = {
                     DemoImage(
-                        resourceId = R.drawable.ic_maps_icon,
+                        resourceId = R.drawable.icon_maps_icon,
                         size = CardDefaults.AppImageSize,
                     )
                 },
@@ -137,7 +137,7 @@
                 secondaryLabel = "Defaults",
                 colors = ChipDefaults.secondaryChipColors(),
             ) {
-                DemoImage(resourceId = R.drawable.ic_maps_icon)
+                DemoImage(resourceId = R.drawable.icon_maps_icon)
             }
         }
         item { ListHeader { Text("Activity") } }
@@ -147,7 +147,7 @@
                 appName = { Text("AppName") },
                 appImage = {
                     DemoImage(
-                        resourceId = R.drawable.ic_maps_icon,
+                        resourceId = R.drawable.icon_maps_icon,
                         size = CardDefaults.AppImageSize,
                     )
                 },
@@ -172,7 +172,7 @@
                 appName = { Text("AppName") },
                 appImage = {
                     DemoImage(
-                        resourceId = R.drawable.ic_maps_icon,
+                        resourceId = R.drawable.icon_maps_icon,
                         size = CardDefaults.AppImageSize,
                     )
                 },
diff --git a/wear/compose/integration-tests/demos/src/main/java/androidx/wear/compose/integration/demos/SettingsDemo.kt b/wear/compose/integration-tests/demos/src/main/java/androidx/wear/compose/integration/demos/SettingsDemo.kt
index 82dc274..a2b12e3 100644
--- a/wear/compose/integration-tests/demos/src/main/java/androidx/wear/compose/integration/demos/SettingsDemo.kt
+++ b/wear/compose/integration-tests/demos/src/main/java/androidx/wear/compose/integration/demos/SettingsDemo.kt
@@ -46,84 +46,95 @@
             // Connectivity
             item {
                 SettingsChip(
-                    painterResourceId = R.drawable.ic_settings_connectivity,
+                    painterResourceId = R.drawable.icon_settings_connectivity,
                     text = "Connectivity",
                 )
             }
             // Display
             item {
                 SettingsChip(
-                    painterResourceId = R.drawable.ic_settings_brightness,
+                    painterResourceId = R.drawable.icon_settings_brightness,
                     text = "Display",
                 )
             }
             // Gestures
             item {
-                SettingsChip(painterResourceId = R.drawable.ic_settings_gestures, text = "Gestures")
+                SettingsChip(
+                    painterResourceId = R.drawable.icon_settings_gestures,
+                    text = "Gestures",
+                )
             }
             // Apps & Notifications
             item {
                 SettingsChip(
-                    painterResourceId = R.drawable.ic_settings_apps,
+                    painterResourceId = R.drawable.icon_settings_apps,
                     text = "Apps & Notifications",
                 )
             }
             // Google
             item {
-                SettingsChip(painterResourceId = R.drawable.ic_settings_googleg, text = "Google")
+                SettingsChip(painterResourceId = R.drawable.icon_settings_googleg, text = "Google")
             }
             // Sound
-            item { SettingsChip(painterResourceId = R.drawable.ic_settings_sound, text = "Sound") }
+            item {
+                SettingsChip(painterResourceId = R.drawable.icon_settings_sound, text = "Sound")
+            }
             // Vibration
             item {
                 SettingsChip(
-                    painterResourceId = R.drawable.ic_settings_vibration,
+                    painterResourceId = R.drawable.icon_settings_vibration,
                     text = "Vibration",
                 )
             }
             // Battery
             item {
-                SettingsChip(painterResourceId = R.drawable.ic_settings_battery, text = "Battery")
+                SettingsChip(painterResourceId = R.drawable.icon_settings_battery, text = "Battery")
             }
             // General
             item {
                 SettingsChip(
-                    painterResourceId = R.drawable.ic_settings_watch_device,
+                    painterResourceId = R.drawable.icon_settings_watch_device,
                     text = "General",
                 )
             }
             // Health Profile
             item {
                 SettingsChip(
-                    painterResourceId = R.drawable.ic_settings_health_profile,
+                    painterResourceId = R.drawable.icon_settings_health_profile,
                     text = "Health Profile",
                 )
             }
             // Location
             item {
-                SettingsChip(painterResourceId = R.drawable.ic_settings_location, text = "Location")
+                SettingsChip(
+                    painterResourceId = R.drawable.icon_settings_location,
+                    text = "Location",
+                )
             }
             // Safety and Emergency
             item {
                 SettingsChip(
-                    painterResourceId = R.drawable.ic_settings_emergency,
+                    painterResourceId = R.drawable.icon_settings_emergency,
                     text = "Safety and Emergency",
                 )
             }
             // Accessibility
             item {
                 SettingsChip(
-                    painterResourceId = R.drawable.ic_settings_accessibility,
+                    painterResourceId = R.drawable.icon_settings_accessibility,
                     text = "Accessibility",
                 )
             }
             // Security
             item {
-                SettingsChip(painterResourceId = R.drawable.ic_settings_security, text = "Security")
+                SettingsChip(
+                    painterResourceId = R.drawable.icon_settings_security,
+                    text = "Security",
+                )
             }
             // System
             item {
-                SettingsChip(painterResourceId = R.drawable.ic_settings_system, text = "System")
+                SettingsChip(painterResourceId = R.drawable.icon_settings_system, text = "System")
             }
         }
     }
diff --git a/wear/compose/integration-tests/demos/src/main/java/androidx/wear/compose/integration/demos/StepperDemo.kt b/wear/compose/integration-tests/demos/src/main/java/androidx/wear/compose/integration/demos/StepperDemo.kt
index 3732ece..1d7835c 100644
--- a/wear/compose/integration-tests/demos/src/main/java/androidx/wear/compose/integration/demos/StepperDemo.kt
+++ b/wear/compose/integration-tests/demos/src/main/java/androidx/wear/compose/integration/demos/StepperDemo.kt
@@ -86,8 +86,8 @@
                     painter =
                         painterResource(
                             id =
-                                if (valueState > 0) R.drawable.ic_volume_up_24px
-                                else R.drawable.ic_volume_off_24px
+                                if (valueState > 0) R.drawable.icon_volume_up_24px
+                                else R.drawable.icon_volume_off_24px
                         ),
                     contentDescription = null,
                 )
diff --git a/wear/compose/integration-tests/demos/src/main/java/androidx/wear/compose/integration/demos/ToggleButtonDemo.kt b/wear/compose/integration-tests/demos/src/main/java/androidx/wear/compose/integration/demos/ToggleButtonDemo.kt
index 352408d..a5784ee3 100644
--- a/wear/compose/integration-tests/demos/src/main/java/androidx/wear/compose/integration/demos/ToggleButtonDemo.kt
+++ b/wear/compose/integration-tests/demos/src/main/java/androidx/wear/compose/integration/demos/ToggleButtonDemo.kt
@@ -67,9 +67,9 @@
                 modifier = Modifier.size(ButtonDefaults.SmallButtonSize),
             ) {
                 if (singularButton1Enabled) {
-                    DemoIcon(R.drawable.ic_volume_up_24px)
+                    DemoIcon(R.drawable.icon_volume_up_24px)
                 } else {
-                    DemoIcon(R.drawable.ic_volume_off_24px)
+                    DemoIcon(R.drawable.icon_volume_off_24px)
                 }
             }
             Spacer(modifier = Modifier.size(4.dp))
@@ -83,7 +83,7 @@
                     ),
                 modifier = Modifier.size(ButtonDefaults.SmallButtonSize),
             ) {
-                DemoIcon(R.drawable.ic_airplanemode_active_24px)
+                DemoIcon(R.drawable.icon_airplanemode_active_24px)
             }
             Spacer(modifier = Modifier.size(4.dp))
             ToggleButton(
@@ -97,7 +97,7 @@
                 modifier = Modifier,
                 shape = CutCornerShape(4.dp),
             ) {
-                DemoIcon(R.drawable.ic_airplanemode_active_24px)
+                DemoIcon(R.drawable.icon_airplanemode_active_24px)
             }
         }
         Spacer(modifier = Modifier.size(4.dp))
@@ -116,7 +116,7 @@
                 onCheckedChange = { toggleButtonsEnabled = it },
                 modifier = Modifier.size(ButtonDefaults.SmallButtonSize),
             ) {
-                DemoIcon(R.drawable.ic_check_24px)
+                DemoIcon(R.drawable.icon_check_24px)
             }
         }
     }
diff --git a/wear/compose/integration-tests/demos/src/main/java/androidx/wear/compose/integration/demos/ToggleChipDemo.kt b/wear/compose/integration-tests/demos/src/main/java/androidx/wear/compose/integration/demos/ToggleChipDemo.kt
index 8b15551..30bde57 100644
--- a/wear/compose/integration-tests/demos/src/main/java/androidx/wear/compose/integration/demos/ToggleChipDemo.kt
+++ b/wear/compose/integration-tests/demos/src/main/java/androidx/wear/compose/integration/demos/ToggleChipDemo.kt
@@ -174,7 +174,7 @@
                         Switch(checked = switchIconWithSecondaryChecked, enabled = enabled)
                     },
                     onCheckedChange = { switchIconWithSecondaryChecked = it },
-                    appIcon = { DemoIcon(R.drawable.ic_airplanemode_active_24px) },
+                    appIcon = { DemoIcon(R.drawable.icon_airplanemode_active_24px) },
                     enabled = enabled,
                 )
             }
@@ -200,8 +200,8 @@
                     },
                     onCheckedChange = { switchIconWithIconChecked = it },
                     appIcon = {
-                        if (switchIconWithIconChecked) DemoIcon(R.drawable.ic_volume_up_24px)
-                        else DemoIcon(R.drawable.ic_volume_off_24px)
+                        if (switchIconWithIconChecked) DemoIcon(R.drawable.icon_volume_up_24px)
+                        else DemoIcon(R.drawable.icon_volume_off_24px)
                     },
                     enabled = enabled,
                 )
diff --git a/wear/compose/integration-tests/demos/src/main/res/drawable/ic_accessibility_24px.xml b/wear/compose/integration-tests/demos/src/main/res/drawable/icon_accessibility_24px.xml
similarity index 100%
rename from wear/compose/integration-tests/demos/src/main/res/drawable/ic_accessibility_24px.xml
rename to wear/compose/integration-tests/demos/src/main/res/drawable/icon_accessibility_24px.xml
diff --git a/wear/compose/integration-tests/demos/src/main/res/drawable/ic_airplanemode_active_24px.xml b/wear/compose/integration-tests/demos/src/main/res/drawable/icon_airplanemode_active_24px.xml
similarity index 100%
rename from wear/compose/integration-tests/demos/src/main/res/drawable/ic_airplanemode_active_24px.xml
rename to wear/compose/integration-tests/demos/src/main/res/drawable/icon_airplanemode_active_24px.xml
diff --git a/wear/compose/integration-tests/demos/src/main/res/drawable/ic_arrow_left_modified.xml b/wear/compose/integration-tests/demos/src/main/res/drawable/icon_arrow_left_modified.xml
similarity index 100%
rename from wear/compose/integration-tests/demos/src/main/res/drawable/ic_arrow_left_modified.xml
rename to wear/compose/integration-tests/demos/src/main/res/drawable/icon_arrow_left_modified.xml
diff --git a/wear/compose/integration-tests/demos/src/main/res/drawable/ic_arrow_right_modified.xml b/wear/compose/integration-tests/demos/src/main/res/drawable/icon_arrow_right_modified.xml
similarity index 100%
rename from wear/compose/integration-tests/demos/src/main/res/drawable/ic_arrow_right_modified.xml
rename to wear/compose/integration-tests/demos/src/main/res/drawable/icon_arrow_right_modified.xml
diff --git a/wear/compose/integration-tests/demos/src/main/res/drawable/ic_baseline_error_24.xml b/wear/compose/integration-tests/demos/src/main/res/drawable/icon_baseline_error_24.xml
similarity index 100%
rename from wear/compose/integration-tests/demos/src/main/res/drawable/ic_baseline_error_24.xml
rename to wear/compose/integration-tests/demos/src/main/res/drawable/icon_baseline_error_24.xml
diff --git a/wear/compose/integration-tests/demos/src/main/res/drawable/ic_baseline_location_on_24.xml b/wear/compose/integration-tests/demos/src/main/res/drawable/icon_baseline_location_on_24.xml
similarity index 100%
rename from wear/compose/integration-tests/demos/src/main/res/drawable/ic_baseline_location_on_24.xml
rename to wear/compose/integration-tests/demos/src/main/res/drawable/icon_baseline_location_on_24.xml
diff --git a/wear/compose/integration-tests/demos/src/main/res/drawable/ic_baseline_settings_24.xml b/wear/compose/integration-tests/demos/src/main/res/drawable/icon_baseline_settings_24.xml
similarity index 100%
rename from wear/compose/integration-tests/demos/src/main/res/drawable/ic_baseline_settings_24.xml
rename to wear/compose/integration-tests/demos/src/main/res/drawable/icon_baseline_settings_24.xml
diff --git a/wear/compose/integration-tests/demos/src/main/res/drawable/ic_check_24px.xml b/wear/compose/integration-tests/demos/src/main/res/drawable/icon_check_24px.xml
similarity index 100%
rename from wear/compose/integration-tests/demos/src/main/res/drawable/ic_check_24px.xml
rename to wear/compose/integration-tests/demos/src/main/res/drawable/icon_check_24px.xml
diff --git a/wear/compose/integration-tests/demos/src/main/res/drawable/ic_check_48px.xml b/wear/compose/integration-tests/demos/src/main/res/drawable/icon_check_48px.xml
similarity index 100%
rename from wear/compose/integration-tests/demos/src/main/res/drawable/ic_check_48px.xml
rename to wear/compose/integration-tests/demos/src/main/res/drawable/icon_check_48px.xml
diff --git a/wear/compose/integration-tests/demos/src/main/res/drawable/ic_chevron_right_24.xml b/wear/compose/integration-tests/demos/src/main/res/drawable/icon_chevron_right_24.xml
similarity index 100%
rename from wear/compose/integration-tests/demos/src/main/res/drawable/ic_chevron_right_24.xml
rename to wear/compose/integration-tests/demos/src/main/res/drawable/icon_chevron_right_24.xml
diff --git a/wear/compose/integration-tests/demos/src/main/res/drawable/ic_clear_24px.xml b/wear/compose/integration-tests/demos/src/main/res/drawable/icon_clear_24px.xml
similarity index 100%
rename from wear/compose/integration-tests/demos/src/main/res/drawable/ic_clear_24px.xml
rename to wear/compose/integration-tests/demos/src/main/res/drawable/icon_clear_24px.xml
diff --git a/wear/compose/integration-tests/demos/src/main/res/drawable/ic_devices_24.xml b/wear/compose/integration-tests/demos/src/main/res/drawable/icon_devices_24.xml
similarity index 100%
rename from wear/compose/integration-tests/demos/src/main/res/drawable/ic_devices_24.xml
rename to wear/compose/integration-tests/demos/src/main/res/drawable/icon_devices_24.xml
diff --git a/wear/compose/integration-tests/demos/src/main/res/drawable/ic_expand_more_24.xml b/wear/compose/integration-tests/demos/src/main/res/drawable/icon_expand_more_24.xml
similarity index 100%
rename from wear/compose/integration-tests/demos/src/main/res/drawable/ic_expand_more_24.xml
rename to wear/compose/integration-tests/demos/src/main/res/drawable/icon_expand_more_24.xml
diff --git a/wear/compose/integration-tests/demos/src/main/res/drawable/ic_maps_icon.xml b/wear/compose/integration-tests/demos/src/main/res/drawable/icon_maps_icon.xml
similarity index 100%
rename from wear/compose/integration-tests/demos/src/main/res/drawable/ic_maps_icon.xml
rename to wear/compose/integration-tests/demos/src/main/res/drawable/icon_maps_icon.xml
diff --git a/wear/compose/integration-tests/demos/src/main/res/drawable/ic_mic_24.xml b/wear/compose/integration-tests/demos/src/main/res/drawable/icon_mic_24.xml
similarity index 100%
rename from wear/compose/integration-tests/demos/src/main/res/drawable/ic_mic_24.xml
rename to wear/compose/integration-tests/demos/src/main/res/drawable/icon_mic_24.xml
diff --git a/wear/compose/integration-tests/demos/src/main/res/drawable/ic_music_24.xml b/wear/compose/integration-tests/demos/src/main/res/drawable/icon_music_24.xml
similarity index 100%
rename from wear/compose/integration-tests/demos/src/main/res/drawable/ic_music_24.xml
rename to wear/compose/integration-tests/demos/src/main/res/drawable/icon_music_24.xml
diff --git a/wear/compose/integration-tests/demos/src/main/res/drawable/ic_pause.xml b/wear/compose/integration-tests/demos/src/main/res/drawable/icon_pause.xml
similarity index 100%
rename from wear/compose/integration-tests/demos/src/main/res/drawable/ic_pause.xml
rename to wear/compose/integration-tests/demos/src/main/res/drawable/icon_pause.xml
diff --git a/wear/compose/integration-tests/demos/src/main/res/drawable/ic_play.xml b/wear/compose/integration-tests/demos/src/main/res/drawable/icon_play.xml
similarity index 100%
rename from wear/compose/integration-tests/demos/src/main/res/drawable/ic_play.xml
rename to wear/compose/integration-tests/demos/src/main/res/drawable/icon_play.xml
diff --git a/wear/compose/integration-tests/demos/src/main/res/drawable/ic_settings_accessibility.xml b/wear/compose/integration-tests/demos/src/main/res/drawable/icon_settings_accessibility.xml
similarity index 100%
rename from wear/compose/integration-tests/demos/src/main/res/drawable/ic_settings_accessibility.xml
rename to wear/compose/integration-tests/demos/src/main/res/drawable/icon_settings_accessibility.xml
diff --git a/wear/compose/integration-tests/demos/src/main/res/drawable/ic_settings_apps.xml b/wear/compose/integration-tests/demos/src/main/res/drawable/icon_settings_apps.xml
similarity index 100%
rename from wear/compose/integration-tests/demos/src/main/res/drawable/ic_settings_apps.xml
rename to wear/compose/integration-tests/demos/src/main/res/drawable/icon_settings_apps.xml
diff --git a/wear/compose/integration-tests/demos/src/main/res/drawable/ic_settings_battery.xml b/wear/compose/integration-tests/demos/src/main/res/drawable/icon_settings_battery.xml
similarity index 100%
rename from wear/compose/integration-tests/demos/src/main/res/drawable/ic_settings_battery.xml
rename to wear/compose/integration-tests/demos/src/main/res/drawable/icon_settings_battery.xml
diff --git a/wear/compose/integration-tests/demos/src/main/res/drawable/ic_settings_brightness.xml b/wear/compose/integration-tests/demos/src/main/res/drawable/icon_settings_brightness.xml
similarity index 100%
rename from wear/compose/integration-tests/demos/src/main/res/drawable/ic_settings_brightness.xml
rename to wear/compose/integration-tests/demos/src/main/res/drawable/icon_settings_brightness.xml
diff --git a/wear/compose/integration-tests/demos/src/main/res/drawable/ic_settings_connectivity.xml b/wear/compose/integration-tests/demos/src/main/res/drawable/icon_settings_connectivity.xml
similarity index 100%
rename from wear/compose/integration-tests/demos/src/main/res/drawable/ic_settings_connectivity.xml
rename to wear/compose/integration-tests/demos/src/main/res/drawable/icon_settings_connectivity.xml
diff --git a/wear/compose/integration-tests/demos/src/main/res/drawable/ic_settings_emergency.xml b/wear/compose/integration-tests/demos/src/main/res/drawable/icon_settings_emergency.xml
similarity index 100%
rename from wear/compose/integration-tests/demos/src/main/res/drawable/ic_settings_emergency.xml
rename to wear/compose/integration-tests/demos/src/main/res/drawable/icon_settings_emergency.xml
diff --git a/wear/compose/integration-tests/demos/src/main/res/drawable/ic_settings_gestures.xml b/wear/compose/integration-tests/demos/src/main/res/drawable/icon_settings_gestures.xml
similarity index 100%
rename from wear/compose/integration-tests/demos/src/main/res/drawable/ic_settings_gestures.xml
rename to wear/compose/integration-tests/demos/src/main/res/drawable/icon_settings_gestures.xml
diff --git a/wear/compose/integration-tests/demos/src/main/res/drawable/ic_settings_googleg.xml b/wear/compose/integration-tests/demos/src/main/res/drawable/icon_settings_googleg.xml
similarity index 100%
rename from wear/compose/integration-tests/demos/src/main/res/drawable/ic_settings_googleg.xml
rename to wear/compose/integration-tests/demos/src/main/res/drawable/icon_settings_googleg.xml
diff --git a/wear/compose/integration-tests/demos/src/main/res/drawable/ic_settings_health_profile.xml b/wear/compose/integration-tests/demos/src/main/res/drawable/icon_settings_health_profile.xml
similarity index 100%
rename from wear/compose/integration-tests/demos/src/main/res/drawable/ic_settings_health_profile.xml
rename to wear/compose/integration-tests/demos/src/main/res/drawable/icon_settings_health_profile.xml
diff --git a/wear/compose/integration-tests/demos/src/main/res/drawable/ic_settings_location.xml b/wear/compose/integration-tests/demos/src/main/res/drawable/icon_settings_location.xml
similarity index 100%
rename from wear/compose/integration-tests/demos/src/main/res/drawable/ic_settings_location.xml
rename to wear/compose/integration-tests/demos/src/main/res/drawable/icon_settings_location.xml
diff --git a/wear/compose/integration-tests/demos/src/main/res/drawable/ic_settings_security.xml b/wear/compose/integration-tests/demos/src/main/res/drawable/icon_settings_security.xml
similarity index 100%
rename from wear/compose/integration-tests/demos/src/main/res/drawable/ic_settings_security.xml
rename to wear/compose/integration-tests/demos/src/main/res/drawable/icon_settings_security.xml
diff --git a/wear/compose/integration-tests/demos/src/main/res/drawable/ic_settings_sound.xml b/wear/compose/integration-tests/demos/src/main/res/drawable/icon_settings_sound.xml
similarity index 100%
rename from wear/compose/integration-tests/demos/src/main/res/drawable/ic_settings_sound.xml
rename to wear/compose/integration-tests/demos/src/main/res/drawable/icon_settings_sound.xml
diff --git a/wear/compose/integration-tests/demos/src/main/res/drawable/ic_settings_system.xml b/wear/compose/integration-tests/demos/src/main/res/drawable/icon_settings_system.xml
similarity index 100%
rename from wear/compose/integration-tests/demos/src/main/res/drawable/ic_settings_system.xml
rename to wear/compose/integration-tests/demos/src/main/res/drawable/icon_settings_system.xml
diff --git a/wear/compose/integration-tests/demos/src/main/res/drawable/ic_settings_vibration.xml b/wear/compose/integration-tests/demos/src/main/res/drawable/icon_settings_vibration.xml
similarity index 100%
rename from wear/compose/integration-tests/demos/src/main/res/drawable/ic_settings_vibration.xml
rename to wear/compose/integration-tests/demos/src/main/res/drawable/icon_settings_vibration.xml
diff --git a/wear/compose/integration-tests/demos/src/main/res/drawable/ic_settings_watch_device.xml b/wear/compose/integration-tests/demos/src/main/res/drawable/icon_settings_watch_device.xml
similarity index 100%
rename from wear/compose/integration-tests/demos/src/main/res/drawable/ic_settings_watch_device.xml
rename to wear/compose/integration-tests/demos/src/main/res/drawable/icon_settings_watch_device.xml
diff --git a/wear/compose/integration-tests/demos/src/main/res/drawable/ic_skip_next.xml b/wear/compose/integration-tests/demos/src/main/res/drawable/icon_skip_next.xml
similarity index 100%
rename from wear/compose/integration-tests/demos/src/main/res/drawable/ic_skip_next.xml
rename to wear/compose/integration-tests/demos/src/main/res/drawable/icon_skip_next.xml
diff --git a/wear/compose/integration-tests/demos/src/main/res/drawable/ic_skip_previous.xml b/wear/compose/integration-tests/demos/src/main/res/drawable/icon_skip_previous.xml
similarity index 100%
rename from wear/compose/integration-tests/demos/src/main/res/drawable/ic_skip_previous.xml
rename to wear/compose/integration-tests/demos/src/main/res/drawable/icon_skip_previous.xml
diff --git a/wear/compose/integration-tests/demos/src/main/res/drawable/ic_volume_off_24px.xml b/wear/compose/integration-tests/demos/src/main/res/drawable/icon_volume_off_24px.xml
similarity index 100%
rename from wear/compose/integration-tests/demos/src/main/res/drawable/ic_volume_off_24px.xml
rename to wear/compose/integration-tests/demos/src/main/res/drawable/icon_volume_off_24px.xml
diff --git a/wear/compose/integration-tests/demos/src/main/res/drawable/ic_volume_up_24px.xml b/wear/compose/integration-tests/demos/src/main/res/drawable/icon_volume_up_24px.xml
similarity index 100%
rename from wear/compose/integration-tests/demos/src/main/res/drawable/ic_volume_up_24px.xml
rename to wear/compose/integration-tests/demos/src/main/res/drawable/icon_volume_up_24px.xml
diff --git a/webkit/README.md b/webkit/README.md
index bab07f75..46c6a02 100644
--- a/webkit/README.md
+++ b/webkit/README.md
@@ -5,7 +5,8 @@
 
 The Jetpack Webkit library (also known as AndroidX Webkit) is a static library
 you can add to your Android application in order to use android.webkit APIs that
-are not available for older platform versions.
+are not available for older platform versions, as well as access new features
+available in [Android System WebView].
 
 ## Basic info
 
@@ -16,17 +17,35 @@
 * [Existing open bugs](https://issuetracker.google.com/issues?q=componentid:460423%20status:open)
 * [File a new bug](https://issuetracker.google.com/issues/new?component=460423)
 
+## Jetpack Webkit and Android System WebView
+
+The Jetpack Webkit library enables developers to access new features that are
+available in the installed version of [Android System WebView], even if those
+features are not exposed through the
+[android.webkit](https://developer.android.com/reference/android/webkit/package-summary)
+framework API. It does this by dynamically checking the set of available
+features through the
+[`WebViewFeature`](http://go/android-dev/reference/androidx/webkit/WebViewFeature#isFeatureSupported(java.lang.String))
+class.
+
+You should take care to always check feature availability before calling an
+API, as you otherwise risk a runtime crash if the WebView provider installed on
+a users device doesn't support the feature in question. This is most likely to
+happen if the user in question has not yet updated to a version of [Android
+System WebView] that supports the feature, but in rare cases WebView may also
+stop supporting a previously supported feature as part of an API deprecation.
+
 ## How to use this library in your app
 
 Add this to your `build.gradle` file:
 
 ```
 dependencies {
-    implementation "androidx.webkit:webkit:1.13.0"
+    implementation "androidx.webkit:webkit:1.14.0"
 }
 ```
 
-**Important:** replace `1.13.0` with the latest version from
+**Important:** replace `1.14.0` with the latest version from
 https://developer.android.com/jetpack/androidx/releases/webkit.
 
 ## Sample apps
@@ -37,6 +56,7 @@
 For more APIs, check out the sample app in the [AndroidX repo][AndroidX demo
 app].
 
+
 ## Public bug tracker
 
 If you find bugs in the Jetpack Webkit library or want to request new features,
@@ -79,3 +99,4 @@
 
 [GitHub demo app]: https://github.com/android/views-widgets-samples/tree/main/WebView
 [AndroidX demo app]: /androidx-main/webkit/integration-tests/testapp/README.md
+[Android System WebView]: https://play.google.com/store/apps/details?id=com.google.android.webview
diff --git a/xr/compose/compose/api/current.txt b/xr/compose/compose/api/current.txt
index e5a9635..5f23357 100644
--- a/xr/compose/compose/api/current.txt
+++ b/xr/compose/compose/api/current.txt
@@ -90,6 +90,9 @@
     property public androidx.xr.compose.spatial.ContentEdge.Vertical Start;
   }
 
+  @SuppressCompatibility @kotlin.RequiresOptIn(level=kotlin.RequiresOptIn.Level.ERROR, message="This is an experimental API. It may be changed or removed in the future.") @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) public @interface ExperimentalUserSubspaceApi {
+  }
+
   public final class OrbiterDefaults {
     method @BytecodeOnly public float getElevation-D9Ej5fM();
     method @InaccessibleFromKotlin public androidx.xr.compose.subspace.layout.SpatialShape getShape();
@@ -178,6 +181,8 @@
     method @BytecodeOnly @androidx.compose.runtime.Composable @androidx.compose.runtime.ComposableOpenTarget(index=0xffffffff) public static void ApplicationSubspace(androidx.xr.compose.subspace.layout.SubspaceModifier?, boolean, kotlin.jvm.functions.Function3<? super androidx.xr.compose.subspace.SpatialBoxScope!,? super androidx.compose.runtime.Composer!,? super java.lang.Integer!,kotlin.Unit!>, androidx.compose.runtime.Composer?, int, int);
     method @KotlinOnly @androidx.compose.runtime.Composable @androidx.compose.runtime.ComposableOpenTarget(index=0xffffffff) public static void Subspace(kotlin.jvm.functions.Function1<androidx.xr.compose.subspace.SpatialBoxScope,kotlin.Unit> content);
     method @BytecodeOnly @androidx.compose.runtime.Composable @androidx.compose.runtime.ComposableOpenTarget(index=0xffffffff) public static void Subspace(kotlin.jvm.functions.Function3<? super androidx.xr.compose.subspace.SpatialBoxScope!,? super androidx.compose.runtime.Composer!,? super java.lang.Integer!,kotlin.Unit!>, androidx.compose.runtime.Composer?, int);
+    method @KotlinOnly @SuppressCompatibility @androidx.compose.runtime.Composable @androidx.compose.runtime.ComposableOpenTarget(index=0xffffffff) @androidx.xr.compose.spatial.ExperimentalUserSubspaceApi public static void UserSubspace(optional androidx.xr.compose.subspace.layout.SubspaceModifier modifier, optional androidx.xr.compose.subspace.BodyPart lockTo, optional androidx.xr.compose.subspace.LockDimensions lockDimensions, optional androidx.xr.compose.subspace.LockingBehavior behavior, optional boolean allowUnboundedSubspace, kotlin.jvm.functions.Function1<androidx.xr.compose.subspace.SpatialBoxScope,kotlin.Unit> content);
+    method @BytecodeOnly @SuppressCompatibility @androidx.compose.runtime.Composable @androidx.compose.runtime.ComposableOpenTarget(index=0xffffffff) @androidx.xr.compose.spatial.ExperimentalUserSubspaceApi public static void UserSubspace-cW0BTCk(androidx.xr.compose.subspace.layout.SubspaceModifier?, int, androidx.xr.compose.subspace.LockDimensions?, androidx.xr.compose.subspace.LockingBehavior?, boolean, kotlin.jvm.functions.Function3<? super androidx.xr.compose.subspace.SpatialBoxScope!,? super androidx.compose.runtime.Composer!,? super java.lang.Integer!,kotlin.Unit!>, androidx.compose.runtime.Composer?, int, int);
   }
 
 }
@@ -195,12 +200,58 @@
     property public boolean isEnabled;
   }
 
+  @SuppressCompatibility @androidx.xr.compose.spatial.ExperimentalUserSubspaceApi @kotlin.jvm.JvmInline public final value class BodyPart {
+    method @BytecodeOnly public static androidx.xr.compose.subspace.BodyPart! box-impl(int);
+    method @BytecodeOnly public int unbox-impl();
+    field public static final androidx.xr.compose.subspace.BodyPart.Companion Companion;
+  }
+
+  public static final class BodyPart.Companion {
+    method @BytecodeOnly public int getHead-SDaINFc();
+    property public androidx.xr.compose.subspace.BodyPart Head;
+  }
+
   public abstract class DragPolicy {
   }
 
   @SuppressCompatibility @kotlin.RequiresOptIn(level=kotlin.RequiresOptIn.Level.ERROR, message="This is an experimental API. It may be changed or removed in the future.") @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) public @interface ExperimentalSubspaceVolumeApi {
   }
 
+  @SuppressCompatibility @androidx.xr.compose.spatial.ExperimentalUserSubspaceApi public final class LockDimensions {
+    ctor public LockDimensions();
+    ctor public LockDimensions(optional boolean isTranslationXTracked, optional boolean isTranslationYTracked, optional boolean isTranslationZTracked, optional boolean isRotationXTracked, optional boolean isRotationYTracked, optional boolean isRotationZTracked);
+    method @InaccessibleFromKotlin public boolean isRotationXTracked();
+    method @InaccessibleFromKotlin public boolean isRotationYTracked();
+    method @InaccessibleFromKotlin public boolean isRotationZTracked();
+    method @InaccessibleFromKotlin public boolean isTranslationXTracked();
+    method @InaccessibleFromKotlin public boolean isTranslationYTracked();
+    method @InaccessibleFromKotlin public boolean isTranslationZTracked();
+    property public boolean isRotationXTracked;
+    property public boolean isRotationYTracked;
+    property public boolean isRotationZTracked;
+    property public boolean isTranslationXTracked;
+    property public boolean isTranslationYTracked;
+    property public boolean isTranslationZTracked;
+    field public static final androidx.xr.compose.subspace.LockDimensions.Companion Companion;
+  }
+
+  public static final class LockDimensions.Companion {
+    method @InaccessibleFromKotlin public androidx.xr.compose.subspace.LockDimensions getAll();
+    property public androidx.xr.compose.subspace.LockDimensions All;
+  }
+
+  @SuppressCompatibility @androidx.xr.compose.spatial.ExperimentalUserSubspaceApi public abstract class LockingBehavior {
+    method @InaccessibleFromKotlin protected final androidx.xr.runtime.math.Pose getTargetCurrentPose();
+    method @InaccessibleFromKotlin protected final void setTargetCurrentPose(androidx.xr.runtime.math.Pose);
+    property protected final androidx.xr.runtime.math.Pose targetCurrentPose;
+    field public static final androidx.xr.compose.subspace.LockingBehavior.Companion Companion;
+  }
+
+  public static final class LockingBehavior.Companion {
+    method public androidx.xr.compose.subspace.LockingBehavior lazy(optional @IntRange(from=100L) int durationMs);
+    method public androidx.xr.compose.subspace.LockingBehavior static();
+  }
+
   public final class MovePolicy extends androidx.xr.compose.subspace.DragPolicy {
     ctor public MovePolicy();
     ctor public MovePolicy(optional boolean isEnabled, optional boolean isStickyPose, optional boolean shouldScaleWithDistance, optional kotlin.jvm.functions.Function1<? super androidx.xr.compose.subspace.layout.SpatialMoveStartEvent,kotlin.Unit>? onMoveStart, optional kotlin.jvm.functions.Function1<? super androidx.xr.compose.subspace.layout.SpatialMoveEndEvent,kotlin.Unit>? onMoveEnd, optional kotlin.jvm.functions.Function1<? super androidx.xr.compose.subspace.layout.SpatialMoveEvent,java.lang.Boolean>? onMove);
@@ -445,6 +496,10 @@
     property public abstract androidx.xr.compose.subspace.layout.SubspaceModifier.Node node;
   }
 
+  public final class GravityAlignedKt {
+    method public static androidx.xr.compose.subspace.layout.SubspaceModifier gravityAligned(androidx.xr.compose.subspace.layout.SubspaceModifier);
+  }
+
   public final class LayoutModifierKt {
     method public static androidx.xr.compose.subspace.layout.SubspaceModifier layout(androidx.xr.compose.subspace.layout.SubspaceModifier, kotlin.jvm.functions.Function3<? super androidx.xr.compose.subspace.layout.SubspaceMeasureScope,? super androidx.xr.compose.subspace.layout.SubspaceMeasurable,? super androidx.xr.compose.unit.VolumeConstraints,? extends androidx.xr.compose.subspace.layout.SubspaceMeasureResult> measure);
   }
@@ -871,10 +926,14 @@
   }
 
   public interface SubspaceLayoutCoordinates {
+    method @InaccessibleFromKotlin public androidx.xr.compose.subspace.layout.SubspaceLayoutCoordinates? getParentCoordinates();
+    method @InaccessibleFromKotlin public androidx.xr.compose.subspace.layout.SubspaceLayoutCoordinates? getParentLayoutCoordinates();
     method @InaccessibleFromKotlin public androidx.xr.runtime.math.Pose getPose();
     method @InaccessibleFromKotlin public androidx.xr.runtime.math.Pose getPoseInParentEntity();
     method @InaccessibleFromKotlin public androidx.xr.runtime.math.Pose getPoseInRoot();
     method @InaccessibleFromKotlin public androidx.xr.compose.unit.IntVolumeSize getSize();
+    property public abstract androidx.xr.compose.subspace.layout.SubspaceLayoutCoordinates? parentCoordinates;
+    property public abstract androidx.xr.compose.subspace.layout.SubspaceLayoutCoordinates? parentLayoutCoordinates;
     property public abstract androidx.xr.runtime.math.Pose pose;
     property public abstract androidx.xr.runtime.math.Pose poseInParentEntity;
     property public abstract androidx.xr.runtime.math.Pose poseInRoot;
diff --git a/xr/compose/compose/api/restricted_current.txt b/xr/compose/compose/api/restricted_current.txt
index 5996bce..cbe1664 100644
--- a/xr/compose/compose/api/restricted_current.txt
+++ b/xr/compose/compose/api/restricted_current.txt
@@ -110,6 +110,9 @@
     property public androidx.xr.compose.spatial.ContentEdge.Vertical Start;
   }
 
+  @SuppressCompatibility @kotlin.RequiresOptIn(level=kotlin.RequiresOptIn.Level.ERROR, message="This is an experimental API. It may be changed or removed in the future.") @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) public @interface ExperimentalUserSubspaceApi {
+  }
+
   public final class OrbiterDefaults {
     method @BytecodeOnly public float getElevation-D9Ej5fM();
     method @InaccessibleFromKotlin public androidx.xr.compose.subspace.layout.SpatialShape getShape();
@@ -200,6 +203,8 @@
     method @BytecodeOnly @RestrictTo({androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX}) @androidx.compose.runtime.Composable @androidx.compose.runtime.ComposableOpenTarget(index=0xffffffff) public static void GravityAlignedSubspace(androidx.xr.compose.subspace.layout.SubspaceModifier?, boolean, kotlin.jvm.functions.Function3<? super androidx.xr.compose.subspace.SpatialBoxScope!,? super androidx.compose.runtime.Composer!,? super java.lang.Integer!,kotlin.Unit!>, androidx.compose.runtime.Composer?, int, int);
     method @KotlinOnly @androidx.compose.runtime.Composable @androidx.compose.runtime.ComposableOpenTarget(index=0xffffffff) public static void Subspace(kotlin.jvm.functions.Function1<androidx.xr.compose.subspace.SpatialBoxScope,kotlin.Unit> content);
     method @BytecodeOnly @androidx.compose.runtime.Composable @androidx.compose.runtime.ComposableOpenTarget(index=0xffffffff) public static void Subspace(kotlin.jvm.functions.Function3<? super androidx.xr.compose.subspace.SpatialBoxScope!,? super androidx.compose.runtime.Composer!,? super java.lang.Integer!,kotlin.Unit!>, androidx.compose.runtime.Composer?, int);
+    method @KotlinOnly @SuppressCompatibility @androidx.compose.runtime.Composable @androidx.compose.runtime.ComposableOpenTarget(index=0xffffffff) @androidx.xr.compose.spatial.ExperimentalUserSubspaceApi public static void UserSubspace(optional androidx.xr.compose.subspace.layout.SubspaceModifier modifier, optional androidx.xr.compose.subspace.BodyPart lockTo, optional androidx.xr.compose.subspace.LockDimensions lockDimensions, optional androidx.xr.compose.subspace.LockingBehavior behavior, optional boolean allowUnboundedSubspace, kotlin.jvm.functions.Function1<androidx.xr.compose.subspace.SpatialBoxScope,kotlin.Unit> content);
+    method @BytecodeOnly @SuppressCompatibility @androidx.compose.runtime.Composable @androidx.compose.runtime.ComposableOpenTarget(index=0xffffffff) @androidx.xr.compose.spatial.ExperimentalUserSubspaceApi public static void UserSubspace-cW0BTCk(androidx.xr.compose.subspace.layout.SubspaceModifier?, int, androidx.xr.compose.subspace.LockDimensions?, androidx.xr.compose.subspace.LockingBehavior?, boolean, kotlin.jvm.functions.Function3<? super androidx.xr.compose.subspace.SpatialBoxScope!,? super androidx.compose.runtime.Composer!,? super java.lang.Integer!,kotlin.Unit!>, androidx.compose.runtime.Composer?, int, int);
   }
 
 }
@@ -217,12 +222,58 @@
     property public boolean isEnabled;
   }
 
+  @SuppressCompatibility @androidx.xr.compose.spatial.ExperimentalUserSubspaceApi @kotlin.jvm.JvmInline public final value class BodyPart {
+    method @BytecodeOnly public static androidx.xr.compose.subspace.BodyPart! box-impl(int);
+    method @BytecodeOnly public int unbox-impl();
+    field public static final androidx.xr.compose.subspace.BodyPart.Companion Companion;
+  }
+
+  public static final class BodyPart.Companion {
+    method @BytecodeOnly public int getHead-SDaINFc();
+    property public androidx.xr.compose.subspace.BodyPart Head;
+  }
+
   public abstract class DragPolicy {
   }
 
   @SuppressCompatibility @kotlin.RequiresOptIn(level=kotlin.RequiresOptIn.Level.ERROR, message="This is an experimental API. It may be changed or removed in the future.") @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) public @interface ExperimentalSubspaceVolumeApi {
   }
 
+  @SuppressCompatibility @androidx.xr.compose.spatial.ExperimentalUserSubspaceApi public final class LockDimensions {
+    ctor public LockDimensions();
+    ctor public LockDimensions(optional boolean isTranslationXTracked, optional boolean isTranslationYTracked, optional boolean isTranslationZTracked, optional boolean isRotationXTracked, optional boolean isRotationYTracked, optional boolean isRotationZTracked);
+    method @InaccessibleFromKotlin public boolean isRotationXTracked();
+    method @InaccessibleFromKotlin public boolean isRotationYTracked();
+    method @InaccessibleFromKotlin public boolean isRotationZTracked();
+    method @InaccessibleFromKotlin public boolean isTranslationXTracked();
+    method @InaccessibleFromKotlin public boolean isTranslationYTracked();
+    method @InaccessibleFromKotlin public boolean isTranslationZTracked();
+    property public boolean isRotationXTracked;
+    property public boolean isRotationYTracked;
+    property public boolean isRotationZTracked;
+    property public boolean isTranslationXTracked;
+    property public boolean isTranslationYTracked;
+    property public boolean isTranslationZTracked;
+    field public static final androidx.xr.compose.subspace.LockDimensions.Companion Companion;
+  }
+
+  public static final class LockDimensions.Companion {
+    method @InaccessibleFromKotlin public androidx.xr.compose.subspace.LockDimensions getAll();
+    property public androidx.xr.compose.subspace.LockDimensions All;
+  }
+
+  @SuppressCompatibility @androidx.xr.compose.spatial.ExperimentalUserSubspaceApi public abstract class LockingBehavior {
+    method @InaccessibleFromKotlin protected final androidx.xr.runtime.math.Pose getTargetCurrentPose();
+    method @InaccessibleFromKotlin protected final void setTargetCurrentPose(androidx.xr.runtime.math.Pose);
+    property protected final androidx.xr.runtime.math.Pose targetCurrentPose;
+    field public static final androidx.xr.compose.subspace.LockingBehavior.Companion Companion;
+  }
+
+  public static final class LockingBehavior.Companion {
+    method public androidx.xr.compose.subspace.LockingBehavior lazy(optional @IntRange(from=100L) int durationMs);
+    method public androidx.xr.compose.subspace.LockingBehavior static();
+  }
+
   public final class MovePolicy extends androidx.xr.compose.subspace.DragPolicy {
     ctor public MovePolicy();
     ctor public MovePolicy(optional boolean isEnabled, optional boolean isStickyPose, optional boolean shouldScaleWithDistance, optional kotlin.jvm.functions.Function1<? super androidx.xr.compose.subspace.layout.SpatialMoveStartEvent,kotlin.Unit>? onMoveStart, optional kotlin.jvm.functions.Function1<? super androidx.xr.compose.subspace.layout.SpatialMoveEndEvent,kotlin.Unit>? onMoveEnd, optional kotlin.jvm.functions.Function1<? super androidx.xr.compose.subspace.layout.SpatialMoveEvent,java.lang.Boolean>? onMove);
@@ -473,6 +524,10 @@
     property public abstract androidx.xr.compose.subspace.layout.SubspaceModifier.Node node;
   }
 
+  public final class GravityAlignedKt {
+    method public static androidx.xr.compose.subspace.layout.SubspaceModifier gravityAligned(androidx.xr.compose.subspace.layout.SubspaceModifier);
+  }
+
   public final class LayoutModifierKt {
     method public static androidx.xr.compose.subspace.layout.SubspaceModifier layout(androidx.xr.compose.subspace.layout.SubspaceModifier, kotlin.jvm.functions.Function3<? super androidx.xr.compose.subspace.layout.SubspaceMeasureScope,? super androidx.xr.compose.subspace.layout.SubspaceMeasurable,? super androidx.xr.compose.unit.VolumeConstraints,? extends androidx.xr.compose.subspace.layout.SubspaceMeasureResult> measure);
   }
@@ -902,10 +957,14 @@
   }
 
   public interface SubspaceLayoutCoordinates {
+    method @InaccessibleFromKotlin public androidx.xr.compose.subspace.layout.SubspaceLayoutCoordinates? getParentCoordinates();
+    method @InaccessibleFromKotlin public androidx.xr.compose.subspace.layout.SubspaceLayoutCoordinates? getParentLayoutCoordinates();
     method @InaccessibleFromKotlin public androidx.xr.runtime.math.Pose getPose();
     method @InaccessibleFromKotlin public androidx.xr.runtime.math.Pose getPoseInParentEntity();
     method @InaccessibleFromKotlin public androidx.xr.runtime.math.Pose getPoseInRoot();
     method @InaccessibleFromKotlin public androidx.xr.compose.unit.IntVolumeSize getSize();
+    property public abstract androidx.xr.compose.subspace.layout.SubspaceLayoutCoordinates? parentCoordinates;
+    property public abstract androidx.xr.compose.subspace.layout.SubspaceLayoutCoordinates? parentLayoutCoordinates;
     property public abstract androidx.xr.runtime.math.Pose pose;
     property public abstract androidx.xr.runtime.math.Pose poseInParentEntity;
     property public abstract androidx.xr.runtime.math.Pose poseInRoot;
diff --git a/xr/compose/compose/build.gradle b/xr/compose/compose/build.gradle
index 0db9dd5..0127293 100644
--- a/xr/compose/compose/build.gradle
+++ b/xr/compose/compose/build.gradle
@@ -44,6 +44,7 @@
     implementation("androidx.activity:activity-compose:1.9.3")
     implementation("androidx.lifecycle:lifecycle-common:2.8.7")
     implementation("androidx.lifecycle:lifecycle-runtime:2.8.7")
+    implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.9.3")
 
     implementation("androidx.compose.animation:animation-core:1.7.5")
     implementation("androidx.compose.foundation:foundation:1.7.5")
diff --git a/xr/compose/compose/src/main/kotlin/androidx/xr/compose/spatial/Subspace.kt b/xr/compose/compose/src/main/kotlin/androidx/xr/compose/spatial/Subspace.kt
index a18680c..b32826d 100644
--- a/xr/compose/compose/src/main/kotlin/androidx/xr/compose/spatial/Subspace.kt
+++ b/xr/compose/compose/src/main/kotlin/androidx/xr/compose/spatial/Subspace.kt
@@ -13,9 +13,9 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
 package androidx.xr.compose.spatial
 
+import android.annotation.SuppressLint
 import android.view.View
 import androidx.activity.ComponentActivity
 import androidx.annotation.RestrictTo
@@ -24,7 +24,9 @@
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.ComposableOpenTarget
 import androidx.compose.runtime.CompositionLocalProvider
+import androidx.compose.runtime.LaunchedEffect
 import androidx.compose.runtime.ProvidableCompositionLocal
+import androidx.compose.runtime.SideEffect
 import androidx.compose.runtime.compositionLocalWithComputedDefaultOf
 import androidx.compose.runtime.currentComposer
 import androidx.compose.runtime.getValue
@@ -51,19 +53,27 @@
 import androidx.xr.compose.platform.disposableValueOf
 import androidx.xr.compose.platform.getValue
 import androidx.xr.compose.platform.requireActivity
+import androidx.xr.compose.subspace.BodyPart
+import androidx.xr.compose.subspace.LockDimensions
+import androidx.xr.compose.subspace.LockingBehavior
 import androidx.xr.compose.subspace.SpatialBox
 import androidx.xr.compose.subspace.SpatialBoxScope
 import androidx.xr.compose.subspace.SubspaceComposable
 import androidx.xr.compose.subspace.layout.CoreGroupEntity
 import androidx.xr.compose.subspace.layout.SubspaceLayout
 import androidx.xr.compose.subspace.layout.SubspaceModifier
+import androidx.xr.compose.subspace.layout.offset
 import androidx.xr.compose.subspace.layout.recommendedSizeIfUnbounded
 import androidx.xr.compose.subspace.node.SubspaceNodeApplier
 import androidx.xr.compose.unit.IntVolumeSize
+import androidx.xr.compose.unit.Meter
+import androidx.xr.compose.unit.Meter.Companion.meters
 import androidx.xr.compose.unit.VolumeConstraints
+import androidx.xr.runtime.Config
 import androidx.xr.runtime.math.Pose
 import androidx.xr.scenecore.Entity
 import androidx.xr.scenecore.GroupEntity
+import androidx.xr.scenecore.Space
 import androidx.xr.scenecore.scene
 
 private val LocalIsInApplicationSubspace: ProvidableCompositionLocal<Boolean> =
@@ -335,7 +345,6 @@
         val placeable = measurables[0].measure(constraints)
         val measuredPlaceholderSize = IntSize(placeable.width, placeable.height)
         layout(measuredPlaceholderSize.width, measuredPlaceholderSize.height) {
-
             // Here we determine the correct position for the 3D content and place the root node.
             // This ensures tighter coordination between the 2D and 3D placement. Note that this is
             // still imperfect as rendering is not explicitly synchronized.
@@ -351,6 +360,119 @@
 }
 
 /**
+ * Controls the default distance (z-offset) between the content and the BodyPart.
+ *
+ * This offset is applied to push the content in front of the user, so their anchor point (e.g.,
+ * head) is not inside the content. The values are in meters.
+ */
+private object UserSubspaceDefaults {
+    @SuppressLint("PrimitiveInCollection")
+    @OptIn(ExperimentalUserSubspaceApi::class)
+    val OFFSETS: Map<BodyPart, Meter> = mapOf(BodyPart.Head to (-0.5f).meters)
+}
+
+/**
+ * Marks Subspace APIs that are experimental and likely to change or be removed in the future.
+ *
+ * Any usage of a declaration annotated with `@ExperimentalUserSubspaceApi` must be accepted either
+ * by annotating that usage with `@OptIn(ExperimentalUserSubspaceApi::class)` or by propagating the
+ * annotation to the containing declaration.
+ */
+@RequiresOptIn(
+    level = RequiresOptIn.Level.ERROR,
+    message = "This is an experimental API. It may be changed or removed in the future.",
+)
+@Retention(AnnotationRetention.BINARY)
+public annotation class ExperimentalUserSubspaceApi
+
+/**
+ * Create a user-centric 3D space that is ideal for spatial UI content that follows the user's given
+ * body part with configurable following behaviors.
+ *
+ * Each call to `UserSubspace` creates a new, independent spatial UI hierarchy. It does **not**
+ * inherit the spatial position, orientation, or scale of any parent `ApplicationSubspace` it is
+ * nested within. Its position in the world is determined solely by its `lockTo` parameter.
+ *
+ * By default, this Subspace is automatically bounded by the system's recommended content box,
+ * similar to [ApplicationSubspace].
+ *
+ * When using BodyPart.Head as the lockTo target, this API requires headtracking to not be disabled
+ * in the session configuration. If it is disabled, this API will not return anything. The session
+ * configuration should resemble `session.configure( config = session.config.copy(headTracking =
+ * Config.HeadTrackingMode.LAST_KNOWN) )`
+ *
+ * This composable is a no-op in non-XR environments (i.e., Phone and Tablet).
+ *
+ * @param modifier The [SubspaceModifier] to be applied to the content of this Subspace.
+ * @param lockTo Specifies a part of the body which the Subspace will be locked to.
+ * @param lockDimensions A set of boolean flags to determine the dimensions of movement that are
+ *   tracked. Possible tracking dimensions are: translationX, translationY, translationZ, rotationX,
+ *   rotationY, and rotationZ. By default, all dimensions are tracked. Any dimensions not listed
+ *   will not be tracked. For example if translationY is not listed, this means the content will not
+ *   move as the user moves vertically up and down.
+ * @param behavior determines how the UserSubspace follows the user. It can be made to move faster
+ *   and be more responsive. The default is LockingBehavior.lazy().
+ * @param allowUnboundedSubspace If true, the default recommended content box constraints will not
+ *   be applied, allowing the Subspace to be infinite. Defaults to false, providing a safe, bounded
+ *   space.
+ * @param content The 3D content to render within this Subspace.
+ */
+// TODO(b/446871230): Add unit tests for UserSubspace.
+@Composable
+@ComposableOpenTarget(index = -1)
+@Suppress("COMPOSE_APPLIER_CALL_MISMATCH")
+@ExperimentalUserSubspaceApi
+public fun UserSubspace(
+    modifier: SubspaceModifier = SubspaceModifier,
+    lockTo: BodyPart = BodyPart.Head,
+    lockDimensions: LockDimensions = LockDimensions.All,
+    behavior: LockingBehavior = LockingBehavior.lazy(),
+    allowUnboundedSubspace: Boolean = false,
+    content: @Composable @SubspaceComposable SpatialBoxScope.() -> Unit,
+) {
+    // If not in XR, do nothing
+    if (!LocalSpatialConfiguration.current.hasXrSpatialFeature) return
+    val session = checkNotNull(LocalSession.current) { "session must be initialized" }
+
+    if (session.config.headTracking == Config.HeadTrackingMode.DISABLED) {
+        return
+    }
+
+    val userSubspaceRoot by remember {
+        disposableValueOf(GroupEntity.create(session, "UserSubspaceRoot")) { it.dispose() }
+    }
+    SideEffect {
+        session.scene.keyEntity?.getScale(relativeTo = Space.REAL_WORLD)?.let { scale ->
+            userSubspaceRoot.setScale(scale)
+        }
+    }
+
+    LaunchedEffect(behavior) {
+        behavior.configure(
+            session = session,
+            trailingEntity = userSubspaceRoot,
+            lockTo = lockTo,
+            lockDimensions = lockDimensions,
+        )
+    }
+
+    // The content is wrapped in a SpatialBox and we move it slightly ahead of the `lockTo` body
+    // part instead of the user being in the middle of it. But the user is still centered in the
+    // Subspace.
+    ApplicationSubspace(
+        modifier = modifier,
+        allowUnboundedSubspace = allowUnboundedSubspace,
+        subspaceRootNode = userSubspaceRoot,
+    ) {
+        val subspaceOffset =
+            checkNotNull(UserSubspaceDefaults.OFFSETS[lockTo]) {
+                "No offset found for lockTo target."
+            }
+        SpatialBox(modifier = SubspaceModifier.offset(z = subspaceOffset.toDp()), content = content)
+    }
+}
+
+/**
  * A Subspace that does not match the scaling, alignment, and placement suggested by the system.
  * Instead it will align itself to gravity (perpendicular to the floor) and have a scale value equal
  * to the scale of the [androidx.xr.scenecore.ActivitySpace] of the application (1:1 with OpenXR
diff --git a/xr/compose/compose/src/main/kotlin/androidx/xr/compose/subspace/LockingBehavior.kt b/xr/compose/compose/src/main/kotlin/androidx/xr/compose/subspace/LockingBehavior.kt
new file mode 100644
index 0000000..6027a51
--- /dev/null
+++ b/xr/compose/compose/src/main/kotlin/androidx/xr/compose/subspace/LockingBehavior.kt
@@ -0,0 +1,339 @@
+/*
+ * Copyright 2025 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 androidx.xr.compose.subspace
+
+import androidx.annotation.IntRange
+import androidx.xr.arcore.ArDevice
+import androidx.xr.compose.spatial.ExperimentalUserSubspaceApi
+import androidx.xr.runtime.Session
+import androidx.xr.runtime.math.Pose
+import androidx.xr.runtime.math.Quaternion
+import androidx.xr.runtime.math.Vector3
+import androidx.xr.scenecore.Entity
+import androidx.xr.scenecore.scene
+import kotlin.coroutines.coroutineContext
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.cancel
+import kotlinx.coroutines.delay
+import kotlinx.coroutines.launch
+
+/**
+ * A LockingBehavior controls the motion of content as it is following (or "locked" to) another
+ * entity, such as a user's head. Currently the options include "static", which does not
+ * continuously follow the target, and "lazy", which gradually catches up to the target.
+ */
+@ExperimentalUserSubspaceApi
+public abstract class LockingBehavior internal constructor() {
+    protected var targetCurrentPose: Pose = Pose.Identity
+
+    internal abstract suspend fun configure(
+        session: Session,
+        trailingEntity: Entity,
+        lockTo: BodyPart = BodyPart.Head,
+        lockDimensions: LockDimensions = LockDimensions.All,
+    )
+
+    public companion object {
+        /**
+         * The content is placed once based on the user's initial pose and does not follow
+         * subsequent movements.
+         */
+        public fun static(): LockingBehavior = StaticLockingBehavior()
+
+        /**
+         * Creates a behavior where the content smoothly animates to follow the user's movements,
+         * creating a comfortable "lazy follow" effect. This is implemented with the Hermite easing
+         * algorithm, which accelerates the content then slows it down towards the end of the
+         * motion, giving it a sense of real world physics. The use of the Hermite algorithm is not
+         * optional but the total duration of the motion can be modified.
+         *
+         * @param durationMs Amount of milliseconds it takes for the content to catch up to the
+         *   user. Default is 1500 milliseconds. A value less than 100 will be rounded up to 100 to
+         *   allow enough time to complete the content movement.
+         * @return A [LockingBehavior] instance configured for lazy locking.
+         */
+        public fun lazy(@IntRange(from = 100) durationMs: Int = 1500): LockingBehavior =
+            LazyLockingBehavior(durationMs)
+    }
+}
+
+/**
+ * Creates a behavior where the content smoothly animates to follow the user's movements, creating a
+ * comfortable "lazy follow" effect. This is the implementation for LazyLocking which is accessible
+ * through the public interface as LockingBehavior.lazy()
+ *
+ * @param durationMs Amount of milliseconds it takes for the content to catch up to the user.
+ *   Default is 1500 milliseconds. A value less than 100 will be rounded up to 100 to allow enough
+ *   time to complete the content movement.
+ */
+@OptIn(ExperimentalUserSubspaceApi::class)
+internal class LazyLockingBehavior(private val durationMs: Int = 1500) : LockingBehavior() {
+    private val totalFrames: Int
+
+    private companion object {
+        private const val TIME_BETWEEN_ANIMATION_TICKS: Long = 50
+        private const val TRANSLATION_THRESHOLD: Float = 0.1f
+        private const val ROTATION_THRESHOLD: Float = 3f
+        private const val HERMITE_CONSTANT1: Float = 3f
+        private const val HERMITE_CONSTANT2: Float = 2f
+    }
+
+    init {
+        totalFrames = (durationMs / TIME_BETWEEN_ANIMATION_TICKS).toInt().coerceAtLeast(1)
+    }
+
+    private var trailingEntity: Entity? = null
+    private var animationCounter: Int = 999
+    private var startPose: Pose = Pose.Identity
+
+    private fun animate() {
+        // Apply a Hermite easing to the interpolation
+        var t: Float = animationCounter.toFloat() / totalFrames
+        t = t * t * (HERMITE_CONSTANT1 - HERMITE_CONSTANT2 * t)
+        val nextPose = Pose.lerp(startPose, targetCurrentPose, t)
+        trailingEntity?.setPose(nextPose)
+        animationCounter++
+        if (animationCounter <= totalFrames) {
+            CoroutineScope(Dispatchers.Main).launch {
+                delay(TIME_BETWEEN_ANIMATION_TICKS)
+                animate()
+            }
+        }
+    }
+
+    fun startAnimationCriteria(): Boolean {
+        val trailingEntityCurrentPose = trailingEntity?.getPose() ?: Pose.Identity
+
+        val translationDelta =
+            (trailingEntityCurrentPose.translation - targetCurrentPose.translation).length
+        val rotationDelta =
+            Quaternion.angle(trailingEntityCurrentPose.rotation, targetCurrentPose.rotation)
+
+        return translationDelta > TRANSLATION_THRESHOLD || rotationDelta > ROTATION_THRESHOLD
+    }
+
+    fun handleNewPose() {
+        // If animation is in progress in another thread, do nothing.
+        if (animationCounter <= totalFrames) {
+            return
+        }
+        // If the target has moved significantly enough, start the animation over.
+        else {
+            if (startAnimationCriteria()) {
+                val trailingEntityCurrentPose = trailingEntity?.getPose() ?: Pose.Identity
+                startPose = trailingEntityCurrentPose
+                animationCounter = 1
+                animate()
+            }
+        }
+    }
+
+    override suspend fun configure(
+        session: Session,
+        trailingEntity: Entity,
+        lockTo: BodyPart,
+        lockDimensions: LockDimensions,
+    ) {
+        this.trailingEntity = trailingEntity
+        if (lockTo != BodyPart.Head) return
+
+        // TODO http://b/448689233 Initial head pose data is not reliable.
+        // Skipping over it with delay.
+        delay(1000)
+
+        val arDevice = ArDevice.getInstance(session)
+        arDevice.state.collect { state ->
+            val headPose =
+                session.scene.perceptionSpace.transformPoseTo(
+                    state.devicePose,
+                    session.scene.activitySpace,
+                )
+
+            // Determine the target pose using the source pose but ignoring the
+            // dimensions not specified in parameter lockDimensions.
+            targetCurrentPose =
+                Pose(
+                    translation =
+                        Vector3(
+                            x =
+                                if (lockDimensions.isTranslationXTracked) {
+                                    headPose.translation.x
+                                } else {
+                                    0f
+                                },
+                            y =
+                                if (lockDimensions.isTranslationYTracked) {
+                                    headPose.translation.y
+                                } else {
+                                    0f
+                                },
+                            z =
+                                if (lockDimensions.isTranslationZTracked) {
+                                    headPose.translation.z
+                                } else {
+                                    0f
+                                },
+                        ),
+                    rotation =
+                        Quaternion(
+                            x =
+                                if (lockDimensions.isRotationXTracked) {
+                                    headPose.rotation.x
+                                } else {
+                                    0f
+                                },
+                            y =
+                                if (lockDimensions.isRotationYTracked) {
+                                    headPose.rotation.y
+                                } else {
+                                    0f
+                                },
+                            z =
+                                if (lockDimensions.isRotationZTracked) {
+                                    headPose.rotation.z
+                                } else {
+                                    0f
+                                },
+                            w = headPose.rotation.w,
+                        ),
+                )
+            handleNewPose()
+        }
+    }
+}
+
+/**
+ * This is the implementation for StaticLocking which is accessible through the public interface as
+ * LockingBehavior.static()
+ */
+@OptIn(ExperimentalUserSubspaceApi::class)
+internal class StaticLockingBehavior() : LockingBehavior() {
+    override suspend fun configure(
+        session: Session,
+        trailingEntity: Entity,
+        lockTo: BodyPart,
+        lockDimensions: LockDimensions,
+    ) {
+        // TODO http://b/448689233 Initial head pose data is not reliable.
+        // Skipping over it with delay.
+        delay(1000)
+
+        val arDevice = ArDevice.getInstance(session)
+        arDevice.state.collect { state ->
+            val targetCurrentPose =
+                session.scene.perceptionSpace.transformPoseTo(
+                    state.devicePose,
+                    session.scene.activitySpace,
+                )
+
+            // Update the trailingEntity just once.
+            if (trailingEntity.getPose() == Pose.Identity) {
+                trailingEntity.setPose(targetCurrentPose)
+                coroutineContext.cancel()
+            }
+        }
+    }
+}
+
+/** A type-safe representation of a part of the user's body that can be used as a lock target. */
+@JvmInline
+@ExperimentalUserSubspaceApi
+public value class BodyPart private constructor(private val value: Int) {
+    public companion object {
+        /**
+         * The "Head" represents both where the user is located and where they are looking.
+         *
+         * This is typically tracked in order to move content to where it's always in the user's
+         * field of view. Please configure headTracking to use this feature. This configure can be
+         * set within the session as follows session.config.headTracking ==
+         * Config.HeadTrackingMode.LAST_KNOWN
+         *
+         * **Permissions:** Note that this requires the `android.permission.HEAD_TRACKING`
+         * permission.
+         */
+        public val Head: BodyPart = BodyPart(1)
+    }
+}
+
+/**
+ * A set of boolean flags which determine the dimensions of movement that are tracked.
+ *
+ * This is intended to be used with a [LockingBehavior]. These dimensions can be used to control how
+ * one entity is locked to another. For example, if a dev wants to place a marker on the floor
+ * showing a user's position in a room, they might want to track only translationX and translationZ.
+ * Possible values are: translationX, translationY, translationZ, rotationX, rotationY, rotationZ or
+ * "ALL".
+ */
+@ExperimentalUserSubspaceApi
+public class LockDimensions(
+    public val isTranslationXTracked: Boolean = false,
+    public val isTranslationYTracked: Boolean = false,
+    public val isTranslationZTracked: Boolean = false,
+    public val isRotationXTracked: Boolean = false,
+    public val isRotationYTracked: Boolean = false,
+    public val isRotationZTracked: Boolean = false,
+) {
+    public companion object {
+        /**
+         * LockDimensions.ALL is provided as a convenient way to specify all 6 dimensions of a pose.
+         */
+        public val All: LockDimensions =
+            LockDimensions(
+                isTranslationXTracked = true,
+                isTranslationYTracked = true,
+                isTranslationZTracked = true,
+                isRotationXTracked = true,
+                isRotationYTracked = true,
+                isRotationZTracked = true,
+            )
+    }
+
+    override fun equals(other: Any?): Boolean {
+        if (this === other) return true
+        if (other !is LockDimensions) return false
+
+        if (isTranslationXTracked != other.isTranslationXTracked) return false
+        if (isTranslationYTracked != other.isTranslationYTracked) return false
+        if (isTranslationZTracked != other.isTranslationZTracked) return false
+        if (isRotationXTracked != other.isRotationXTracked) return false
+        if (isRotationYTracked != other.isRotationYTracked) return false
+        if (isRotationZTracked != other.isRotationZTracked) return false
+
+        return true
+    }
+
+    override fun hashCode(): Int {
+        var result = isTranslationXTracked.hashCode()
+        result = 31 * result + isTranslationYTracked.hashCode()
+        result = 31 * result + isTranslationZTracked.hashCode()
+        result = 31 * result + isRotationXTracked.hashCode()
+        result = 31 * result + isRotationYTracked.hashCode()
+        result = 31 * result + isRotationZTracked.hashCode()
+        return result
+    }
+
+    override fun toString(): String {
+        return "LockDimensions(" +
+            "translationX=${isTranslationXTracked}, " +
+            "translationY=${isTranslationYTracked}, " +
+            "translationZ=${isTranslationZTracked}, " +
+            "rotationX=${isRotationXTracked}, " +
+            "rotationY=${isRotationYTracked}, " +
+            "rotationZ=${isRotationZTracked})"
+    }
+}
diff --git a/xr/compose/compose/src/main/kotlin/androidx/xr/compose/subspace/layout/GravityAligned.kt b/xr/compose/compose/src/main/kotlin/androidx/xr/compose/subspace/layout/GravityAligned.kt
new file mode 100644
index 0000000..a5ec35c
--- /dev/null
+++ b/xr/compose/compose/src/main/kotlin/androidx/xr/compose/subspace/layout/GravityAligned.kt
@@ -0,0 +1,123 @@
+/*
+ * Copyright 2025 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 androidx.xr.compose.subspace.layout
+
+import androidx.xr.compose.spatial.LocalSubspaceRootNode
+import androidx.xr.compose.subspace.node.CompositionLocalConsumerSubspaceModifierNode
+import androidx.xr.compose.subspace.node.SubspaceLayoutModifierNode
+import androidx.xr.compose.subspace.node.SubspaceModifierNodeElement
+import androidx.xr.compose.subspace.node.currentValueOf
+import androidx.xr.compose.unit.VolumeConstraints
+import androidx.xr.runtime.math.Pose
+import androidx.xr.runtime.math.Quaternion
+import androidx.xr.runtime.math.Vector3
+import androidx.xr.scenecore.Space
+
+/**
+ * A [SubspaceModifier] that forces the content to remain upright, aligned with gravity by isolating
+ * the element's yaw by cancelling parent pitch and roll.
+ *
+ * This modifier calculates the necessary counter-rotation to ignore the pitch and roll of its
+ * parent entity's total world transformation. It only affects the rotation and not the translation.
+ * This is useful for UI elements like labels or billboards that should always stay level,
+ * regardless of the orientation of the object they are attached to. It effectively isolates the
+ * **yaw** (rotation around the vertical Y-axis).
+ */
+public fun SubspaceModifier.gravityAligned(): SubspaceModifier = this.then(GravityAlignedElement)
+
+private object GravityAlignedElement : SubspaceModifierNodeElement<GravityAlignedNode>() {
+    override fun create(): GravityAlignedNode = GravityAlignedNode()
+
+    override fun update(node: GravityAlignedNode) {}
+
+    override fun hashCode(): Int = "GravityAligned".hashCode()
+
+    override fun equals(other: Any?): Boolean = other === this
+}
+
+internal class GravityAlignedNode :
+    SubspaceModifier.Node(),
+    SubspaceLayoutModifierNode,
+    CompositionLocalConsumerSubspaceModifierNode {
+
+    override fun SubspaceMeasureScope.measure(
+        measurable: SubspaceMeasurable,
+        constraints: VolumeConstraints,
+    ): SubspaceMeasureResult {
+        val placeable = measurable.measure(constraints)
+
+        return layout(placeable.measuredWidth, placeable.measuredHeight, placeable.measuredDepth) {
+            // Gravity Aligned Calculation:
+            // 1. Determine the object's desired "forward" direction in World space, but projected
+            // onto the horizontal (XZ) plane.
+            // 2. Create a goal world rotation that points in this new horizontal direction.
+            // 3. Convert this goal world rotation back into a local rotation relative to the parent
+            // layout.
+            // 4. Apply this new local rotation to the placeable.
+            // The "World" here in variables names refer to SceneCore's [Space.REAL_WORLD] which is
+            // the global coordinate space, unscaled and gravity aligned at the root of the scene
+            // graph of the activity.
+            val rootWorldRotation =
+                currentValueOf(LocalSubspaceRootNode)?.getPose(Space.REAL_WORLD)?.rotation
+                    ?: Quaternion.Identity
+            val nodePoseInRoot = coordinates?.poseInRoot?.rotation ?: Quaternion.Identity
+            val currentWorldRotation = rootWorldRotation * nodePoseInRoot
+
+            // Calculate the node's current forward vector in the World space.
+            val tiltedWorldForward = currentWorldRotation * Vector3.Forward
+
+            // Project the forward vector onto the horizontal (XZ) plane by zeroing out the Y.
+            // This removes any pitch and roll, leaving a vector perfectly level with the ground.
+            val levelForwardTarget = Vector3(tiltedWorldForward.x, 0f, tiltedWorldForward.z)
+
+            val goalWorldRotation: Quaternion =
+                // Check for a DEGENERATE CASE: if the object is looking almost straight up or down,
+                // the projected forward vector will be near zero length.
+                if (levelForwardTarget.lengthSquared < 1e-6f) {
+                    // DEGENERATE CASE: the yaw is undefined. The current forward vector is pointing
+                    // straight up or down. Fallback to using the parent layout node's world yaw as
+                    // a stable reference.
+                    val parentPoseInRoot =
+                        coordinates?.parentCoordinates?.poseInRoot?.rotation ?: Quaternion.Identity
+                    val parentWorldRotation = rootWorldRotation * parentPoseInRoot
+                    val parentWorldForward = parentWorldRotation * Vector3.Forward
+                    val projectedParentForward =
+                        Vector3(parentWorldForward.x, 0f, parentWorldForward.z)
+
+                    if (projectedParentForward.lengthSquared < 1e-6f) {
+                        // ULTIMATE FALLBACK: if the parent is also looking straight up or down.
+                        Quaternion.Identity
+                    } else {
+                        // Create a rotation from the default forward to the parent's projected
+                        // forward.
+                        Quaternion.fromRotation(Vector3.Forward, projectedParentForward)
+                    }
+                } else {
+                    // COMMON CASE: create a rotation that turns the default forward vector
+                    // to face the new, level target direction.
+                    Quaternion.fromRotation(Vector3.Forward, levelForwardTarget)
+                }
+
+            // Calculate the correction needed to go from the current rotation to the goal rotation.
+            // This works because placement in the modifier chain is compositional.
+            val newLocalRotation = currentWorldRotation.inverse * goalWorldRotation
+
+            // Place the measured content using the new gravity-aligned local rotation.
+            // The translation is zero as this modifier only affects the rotation.
+            placeable.place(Pose(translation = Vector3.Zero, rotation = newLocalRotation))
+        }
+    }
+}
diff --git a/xr/compose/compose/src/main/kotlin/androidx/xr/compose/subspace/layout/SubspaceLayoutCoordinates.kt b/xr/compose/compose/src/main/kotlin/androidx/xr/compose/subspace/layout/SubspaceLayoutCoordinates.kt
index 7bd33ff..277f892 100644
--- a/xr/compose/compose/src/main/kotlin/androidx/xr/compose/subspace/layout/SubspaceLayoutCoordinates.kt
+++ b/xr/compose/compose/src/main/kotlin/androidx/xr/compose/subspace/layout/SubspaceLayoutCoordinates.kt
@@ -29,18 +29,38 @@
     public val pose: Pose
 
     /**
-     * The pose of this layout relative to the root entity of the Compose hierarchy, with
-     * translation in pixels.
-     */
-    public val poseInRoot: Pose
-
-    /**
      * The pose of this layout relative to its parent entity in the Compose hierarchy, with
      * translation in pixels.
      */
     public val poseInParentEntity: Pose
 
     /**
+     * The pose of this layout relative to the root entity of the Compose for XR's hierarchy with
+     * translation values in pixels.
+     */
+    public val poseInRoot: Pose
+
+    /**
+     * The coordinates of the immediate parent in the layout hierarchy.
+     *
+     * For a layout, this is its parent layout. For a modifier, this is the modifier that preceded
+     * it, or the layout it is attached to if it is the first in the chain.
+     *
+     * Returns `null` only for the root of the hierarchy.
+     */
+    public val parentCoordinates: SubspaceLayoutCoordinates?
+
+    /**
+     * The coordinates of the nearest parent layout, skipping any intermediate modifiers.
+     *
+     * This is useful for positioning relative to the containing layout composable, irrespective of
+     * any modifiers applied to it.
+     *
+     * Returns `null` only for the root of the hierarchy.
+     */
+    public val parentLayoutCoordinates: SubspaceLayoutCoordinates?
+
+    /**
      * The size of this layout in the local coordinates space.
      *
      * This is also useful for providing the size of the node to the
diff --git a/xr/compose/compose/src/main/kotlin/androidx/xr/compose/subspace/node/SubspaceLayoutModifierNodeCoordinator.kt b/xr/compose/compose/src/main/kotlin/androidx/xr/compose/subspace/node/SubspaceLayoutModifierNodeCoordinator.kt
index 9e58f38..db758fd 100644
--- a/xr/compose/compose/src/main/kotlin/androidx/xr/compose/subspace/node/SubspaceLayoutModifierNodeCoordinator.kt
+++ b/xr/compose/compose/src/main/kotlin/androidx/xr/compose/subspace/node/SubspaceLayoutModifierNodeCoordinator.kt
@@ -60,30 +60,43 @@
         get() = layoutPose ?: Pose.Identity
 
     /**
-     * The pose of this layout modifier node relative to the root entity of the Compose hierarchy.
-     */
-    override val poseInRoot: Pose
-        get() = coordinatesInRoot?.poseInRoot?.compose(pose) ?: pose
-
-    /**
      * The pose of this layout modifier node relative to its parent entity in the Compose hierarchy.
      */
     override val poseInParentEntity: Pose
         get() = coordinatesInParentEntity?.poseInParentEntity?.compose(pose) ?: pose
 
     /**
-     * The layout coordinates of the parent [SubspaceLayoutNode] up to the root of the hierarchy
-     * including application from any [SubspaceLayoutModifierNode] instances applied to this node.
-     *
-     * This applies the layout changes of all [SubspaceLayoutModifierNode] instances in the modifier
-     * chain and then [layoutNode]'s parent or just [layoutNode]'s parent and this modifier if no
-     * other [SubspaceLayoutModifierNode] is present.
+     * The pose of this layout modifier node relative to the root entity of the Compose hierarchy.
      */
-    private val coordinatesInRoot: SubspaceLayoutCoordinates?
-        get() = parent ?: layoutNode?.measurableLayout?.parentCoordinatesInRoot
+    override val poseInRoot: Pose
+        get() = parentCoordinates?.poseInRoot?.compose(pose) ?: pose
 
     /**
-     * The layout coordinates up to the nearest parent [CoreEntity] including mutations from any
+     * The coordinates of the immediate parent in the layout hierarchy.
+     *
+     * For a modifier, this returns the coordinates of the modifier that preceded it in the chain.
+     * If it is the first modifier, it falls back to returning the coordinates of the parent layout
+     * of the node it is attached to.
+     *
+     * Returns `null` only for a modifier on the root of the hierarchy.
+     */
+    override val parentCoordinates: SubspaceLayoutCoordinates?
+        get() = parent ?: parentLayoutCoordinates
+
+    /**
+     * The coordinates of the nearest parent layout, skipping any intermediate modifiers.
+     *
+     * This bypasses any other modifiers on the same layout node and returns the coordinates of the
+     * parent of the layout node itself.
+     *
+     * Returns `null` only for a modifier on the root of the hierarchy.
+     */
+    override val parentLayoutCoordinates: SubspaceLayoutCoordinates?
+        get() = layoutNode?.measurableLayout?.parentLayoutCoordinates
+
+    /**
+     * The layout coordinates up to the nearest parent
+     * [androidx.xr.compose.subspace.layout.CoreEntity] including mutations from any
      * [SubspaceLayoutModifierNode] instances applied to this node.
      *
      * This applies the layout changes of all [SubspaceLayoutModifierNode] instances in the modifier
diff --git a/xr/compose/compose/src/main/kotlin/androidx/xr/compose/subspace/node/SubspaceLayoutNode.kt b/xr/compose/compose/src/main/kotlin/androidx/xr/compose/subspace/node/SubspaceLayoutNode.kt
index 18f4464..57481f4 100644
--- a/xr/compose/compose/src/main/kotlin/androidx/xr/compose/subspace/node/SubspaceLayoutNode.kt
+++ b/xr/compose/compose/src/main/kotlin/androidx/xr/compose/subspace/node/SubspaceLayoutNode.kt
@@ -379,13 +379,59 @@
         override val pose: Pose
             get() = layoutPose ?: Pose.Identity
 
-        /** The position of this node relative to the root of this Compose hierarchy, in pixels. */
-        override val poseInRoot: Pose
-            get() = coordinatesInRoot?.poseInRoot?.compose(pose) ?: pose
-
         override val poseInParentEntity: Pose
             get() = coordinatesInParentEntity?.poseInParentEntity?.compose(pose) ?: pose
 
+        /** The position of this node relative to the root of this Compose hierarchy, in pixels. */
+        override val poseInRoot: Pose
+            get() = parentCoordinates?.poseInRoot?.compose(pose) ?: pose
+
+        /**
+         * The coordinates of the immediate parent in the layout hierarchy.
+         *
+         * It includes application from any [SubspaceLayoutModifierNode] instances in the modifier
+         * chain of this node. This property first checks for any layout modifiers on the current
+         * node. If modifiers are present, it returns the coordinates of the outermost modifier. If
+         * no modifiers are present, it falls back to returning the coordinates of the parent
+         * layout.
+         *
+         * Returns `null` only for the root of the hierarchy.
+         */
+        override val parentCoordinates: SubspaceLayoutCoordinates?
+            get() =
+                nodes.getLast<SubspaceLayoutModifierNode>()?.requireCoordinator()
+                    ?: parentLayoutCoordinates
+
+        /**
+         * The coordinates of the parent layout, skipping any modifiers on this node.
+         *
+         * Returns `null` only for the root of the hierarchy.
+         */
+        override val parentLayoutCoordinates: SubspaceLayoutCoordinates?
+            get() = parent?.measurableLayout
+
+        /**
+         * The layout coordinates up to the nearest parent [CoreEntity], including mutations from
+         * any [SubspaceLayoutModifierNode] instances applied to this node.
+         *
+         * This applies the layout changes of all [SubspaceLayoutModifierNode] instances in the
+         * modifier chain.
+         *
+         * This property continues the coordinate search up the hierarchy, starting with any local
+         * layout modifiers.
+         *
+         * It returns `null` only under a specific condition: when there are no layout modifiers on
+         * the current node AND its immediate parent either is the root or has a `CoreEntity`.
+         */
+        private val coordinatesInParentEntity: SubspaceLayoutCoordinates?
+            get() =
+                nodes.getLast<SubspaceLayoutModifierNode>()?.requireCoordinator()
+                    ?: parentCoordinatesInParentEntity
+
+        /** Traverse up the parent hierarchy until we reach a node with an entity. */
+        internal val parentCoordinatesInParentEntity: SubspaceLayoutCoordinates?
+            get() = if (parent?.entity == null) parent?.measurableLayout else null
+
         override val semanticsChildren: MutableList<SubspaceSemanticsInfo>
             get() {
                 val list: MutableList<SubspaceSemanticsInfo> = mutableListOf()
@@ -423,41 +469,6 @@
         override val semanticsEntity: Entity?
             get() = coreEntity?.semanticsEntity
 
-        /**
-         * The layout coordinates of the parent [SubspaceLayoutNode] up to the root of the hierarchy
-         * including application from any [SubspaceLayoutModifierNode] instances applied to this
-         * node.
-         *
-         * This applies the layout changes of all [SubspaceLayoutModifierNode] instances in the
-         * modifier chain and then [parentCoordinatesInRoot] or just [parentCoordinatesInRoot] if no
-         * [SubspaceLayoutModifierNode] is present.
-         */
-        private val coordinatesInRoot: SubspaceLayoutCoordinates?
-            get() =
-                nodes.getLast<SubspaceLayoutModifierNode>()?.requireCoordinator()
-                    ?: parentCoordinatesInRoot
-
-        /** Traverse the parent hierarchy up to the root. */
-        internal val parentCoordinatesInRoot: SubspaceLayoutCoordinates?
-            get() = parent?.measurableLayout
-
-        /**
-         * The layout coordinates up to the nearest parent [CoreEntity] including mutations from any
-         * [SubspaceLayoutModifierNode] instances applied to this node.
-         *
-         * This applies the layout changes of all [SubspaceLayoutModifierNode] instances in the
-         * modifier chain and then [parentCoordinatesInParentEntity] or just
-         * [parentCoordinatesInParentEntity] if no [SubspaceLayoutModifierNode] is present.
-         */
-        private val coordinatesInParentEntity: SubspaceLayoutCoordinates?
-            get() =
-                nodes.getLast<SubspaceLayoutModifierNode>()?.requireCoordinator()
-                    ?: parentCoordinatesInParentEntity
-
-        /** Traverse up the parent hierarchy until we reach a node with an entity. */
-        internal val parentCoordinatesInParentEntity: SubspaceLayoutCoordinates?
-            get() = if (parent?.entity == null) parent?.measurableLayout else null
-
         override val size: IntVolumeSize
             get() {
                 return coreEntity?.size
diff --git a/xr/compose/compose/src/test/kotlin/androidx/xr/compose/subspace/layout/GravityAlignedTest.kt b/xr/compose/compose/src/test/kotlin/androidx/xr/compose/subspace/layout/GravityAlignedTest.kt
new file mode 100644
index 0000000..f18427e
--- /dev/null
+++ b/xr/compose/compose/src/test/kotlin/androidx/xr/compose/subspace/layout/GravityAlignedTest.kt
@@ -0,0 +1,404 @@
+/*
+ * Copyright 2025 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 androidx.xr.compose.subspace.layout
+
+import androidx.compose.material3.Text
+import androidx.compose.runtime.CompositionLocalProvider
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.setValue
+import androidx.compose.ui.test.junit4.createAndroidComposeRule
+import androidx.compose.ui.unit.dp
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.xr.compose.spatial.ApplicationSubspace
+import androidx.xr.compose.spatial.LocalSubspaceRootNode
+import androidx.xr.compose.subspace.SpatialBox
+import androidx.xr.compose.subspace.SpatialPanel
+import androidx.xr.compose.testing.SubspaceTestingActivity
+import androidx.xr.compose.testing.assertPositionIsEqualTo
+import androidx.xr.compose.testing.assertRotationInRootIsEqualTo
+import androidx.xr.compose.testing.assertRotationIsEqualTo
+import androidx.xr.compose.testing.createFakeSession
+import androidx.xr.compose.testing.onSubspaceNodeWithTag
+import androidx.xr.compose.testing.session
+import androidx.xr.compose.testing.setContentWithCompatibilityForXr
+import androidx.xr.runtime.math.Pose
+import androidx.xr.runtime.math.Quaternion
+import androidx.xr.scenecore.GroupEntity
+import androidx.xr.scenecore.Space
+import com.google.common.truth.Truth.assertThat
+import kotlin.test.assertNotNull
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(AndroidJUnit4::class)
+class GravityAlignedTest {
+    @get:Rule val composeTestRule = createAndroidComposeRule<SubspaceTestingActivity>()
+
+    @Test
+    fun gravityAligned_parentIsLevel_appliesNoRotation() {
+        composeTestRule.setContentWithCompatibilityForXr {
+            ApplicationSubspace {
+                SpatialBox {
+                    SpatialPanel(SubspaceModifier.testTag("child").gravityAligned()) {
+                        Text(text = "Panel")
+                    }
+                }
+            }
+        }
+
+        // With an identity parent, the result is identity.
+        composeTestRule
+            .onSubspaceNodeWithTag("child")
+            .assertPositionIsEqualTo(0.dp, 0.dp, 0.dp)
+            .assertRotationIsEqualTo(Quaternion.Identity)
+            .assertRotationInRootIsEqualTo(Quaternion.Identity)
+    }
+
+    @Test
+    fun gravityAligned_parentHasPitchAndRoll_appliesCounterRotation() {
+        val parentRotation = Quaternion.fromEulerAngles(pitch = 30f, yaw = 0f, roll = 45f)
+
+        composeTestRule.setContentWithCompatibilityForXr {
+            ApplicationSubspace {
+                SpatialBox(SubspaceModifier.rotate(parentRotation)) {
+                    SpatialPanel(SubspaceModifier.testTag("child").gravityAligned()) {
+                        Text(text = "Panel")
+                    }
+                }
+            }
+        }
+
+        val yawOnlyRotation =
+            Quaternion.fromEulerAngles(pitch = 0f, yaw = parentRotation.eulerAngles.y, roll = 0f)
+        // Quaternion(x = -0.2391f, y = 0.099f, z = -0.3696f, w = 0.8924f)
+        val expectedCounterRotation = parentRotation.inverse * yawOnlyRotation
+        // Quaternion.Identity
+        val expectedRootRotation = parentRotation * expectedCounterRotation
+
+        composeTestRule
+            .onSubspaceNodeWithTag("child")
+            .assertPositionIsEqualTo(0.dp, 0.dp, 0.dp)
+            .assertRotationIsEqualTo(expectedCounterRotation)
+            .assertRotationInRootIsEqualTo(expectedRootRotation)
+    }
+
+    @Test
+    fun gravityAligned_parentHasYaw_preservesYaw() {
+        val parentRotation = Quaternion.fromEulerAngles(pitch = 20f, yaw = 60f, roll = -25f)
+        composeTestRule.setContentWithCompatibilityForXr {
+            ApplicationSubspace {
+                SpatialBox(SubspaceModifier.rotate(parentRotation)) {
+                    SpatialPanel(SubspaceModifier.testTag("child").gravityAligned()) {
+                        Text(text = "Panel")
+                    }
+                }
+            }
+        }
+
+        // Using the simpler version of the gravity aligned logic to derive the counter rotation.
+        // This is okay since this unit test does not hit the DEGENERATE case.
+        val yawOnlyRotation =
+            Quaternion.fromEulerAngles(pitch = 0f, yaw = parentRotation.eulerAngles.y, roll = 0f)
+        // Quaternion(x = -0.1695f, y = -0.0376f, z = 0.2132f, w = 0.9615f)
+        val expectedCounterRotation = parentRotation.inverse * yawOnlyRotation
+        // Quaternion.fromEulerAngles(pitch = 0f, yaw = 60f, roll = 0f)
+        val expectedRootRotation = parentRotation * expectedCounterRotation
+
+        composeTestRule
+            .onSubspaceNodeWithTag("child")
+            .assertPositionIsEqualTo(0.dp, 0.dp, 0.dp)
+            .assertRotationIsEqualTo(expectedCounterRotation)
+            .assertRotationInRootIsEqualTo(expectedRootRotation)
+    }
+
+    @Test
+    fun gravityAligned_parentRotationChanges_updatesCounterRotation() {
+        var parentRotation by
+            mutableStateOf(Quaternion.fromEulerAngles(pitch = 10f, yaw = 0f, roll = 15f))
+
+        composeTestRule.setContentWithCompatibilityForXr {
+            ApplicationSubspace {
+                SpatialBox(SubspaceModifier.rotate(parentRotation)) {
+                    SpatialPanel(SubspaceModifier.testTag("child").gravityAligned()) {
+                        Text(text = "$parentRotation")
+                    }
+                }
+            }
+        }
+
+        var yawOnlyRotation =
+            Quaternion.fromEulerAngles(pitch = 0f, yaw = parentRotation.eulerAngles.y, roll = 0f)
+        // Quaternion(x = -0.0864f, y = 0.0114f, z = -0.13f, w = 0.9877f)
+        var expectedCounterRotation = parentRotation.inverse * yawOnlyRotation
+        // Quaternion.Identity
+        var expectedRootRotation = parentRotation * expectedCounterRotation
+
+        composeTestRule
+            .onSubspaceNodeWithTag("child")
+            .assertRotationIsEqualTo(expectedCounterRotation)
+            .assertRotationInRootIsEqualTo(expectedRootRotation)
+
+        // Update state
+        parentRotation = Quaternion.fromEulerAngles(pitch = -40f, yaw = 20f, roll = -30f)
+        composeTestRule.waitForIdle()
+
+        yawOnlyRotation =
+            Quaternion.fromEulerAngles(pitch = 0f, yaw = parentRotation.eulerAngles.y, roll = 0f)
+        expectedCounterRotation = parentRotation.inverse * yawOnlyRotation
+        // Quaternion.fromEulerAngles(pitch = 0f, yaw = 20f, roll = 0f)
+        expectedRootRotation = parentRotation * expectedCounterRotation
+
+        composeTestRule
+            .onSubspaceNodeWithTag("child")
+            .assertRotationIsEqualTo(expectedCounterRotation)
+            .assertRotationInRootIsEqualTo(expectedRootRotation)
+    }
+
+    @Test
+    fun gravityAligned_parentHasNegativeRotation_appliesCounterRotation() {
+        val parentRotation = Quaternion.fromEulerAngles(pitch = -15f, yaw = 0f, roll = -50f)
+
+        composeTestRule.setContentWithCompatibilityForXr {
+            ApplicationSubspace {
+                SpatialBox(SubspaceModifier.rotate(parentRotation)) {
+                    SpatialPanel(SubspaceModifier.testTag("child").gravityAligned()) {
+                        Text(text = "Panel")
+                    }
+                }
+            }
+        }
+
+        val yawOnlyRotation =
+            Quaternion.fromEulerAngles(pitch = 0f, yaw = parentRotation.eulerAngles.y, roll = 0f)
+        // Quaternion(x = 0.1183f, y = 0.0552f, z = 0.419f, w = 0.8986f)
+        val expectedCounterRotation = parentRotation.inverse * yawOnlyRotation
+        // Quaternion.Identity
+        val expectedRootRotation = parentRotation * expectedCounterRotation
+
+        composeTestRule
+            .onSubspaceNodeWithTag("child")
+            .assertPositionIsEqualTo(0.dp, 0.dp, 0.dp)
+            .assertRotationIsEqualTo(expectedCounterRotation)
+            .assertRotationInRootIsEqualTo(expectedRootRotation)
+    }
+
+    @Test
+    fun gravityAligned_chainedWithRotate_appliesCombinedRotation() {
+        val parentRotation = Quaternion.fromEulerAngles(pitch = -30f, yaw = 11f, roll = 22f)
+        val localRotation = Quaternion.fromEulerAngles(pitch = 17f, yaw = 29f, roll = 39f)
+
+        composeTestRule.setContentWithCompatibilityForXr {
+            ApplicationSubspace {
+                SpatialBox(SubspaceModifier.rotate(parentRotation)) {
+                    SpatialPanel(
+                        SubspaceModifier.rotate(localRotation).gravityAligned().testTag("child")
+                    ) {
+                        Text(text = "Panel")
+                    }
+                }
+            }
+        }
+
+        val totalEffectiveRotation = parentRotation * localRotation
+        val yawOnlyRotation =
+            Quaternion.fromEulerAngles(
+                pitch = 0f,
+                yaw = totalEffectiveRotation.eulerAngles.y,
+                roll = 0f,
+            )
+        val counterRotation = totalEffectiveRotation.inverse * yawOnlyRotation
+        // Quaternion(x = 0f, y = 0.38997f, z = 0f, w = 0.9208f)
+        val expectedRootRotation = totalEffectiveRotation * counterRotation
+
+        composeTestRule
+            .onSubspaceNodeWithTag("child")
+            .assertRotationInRootIsEqualTo(expectedRootRotation)
+    }
+
+    @Test
+    fun gravityAligned_chainedBetweenTwoRotations_appliesCombinedRotation() {
+        val parentRotation = Quaternion.fromEulerAngles(pitch = 20f, yaw = 0f, roll = 20f)
+        val innerLocalRotation = Quaternion.fromEulerAngles(pitch = 10f, yaw = 10f, roll = 0f)
+        val outerLocalRotation = Quaternion.fromEulerAngles(pitch = 0f, yaw = 30f, roll = 0f)
+
+        composeTestRule.setContentWithCompatibilityForXr {
+            ApplicationSubspace {
+                SpatialBox(SubspaceModifier.rotate(parentRotation)) {
+                    SpatialPanel(
+                        SubspaceModifier.rotate(innerLocalRotation)
+                            .gravityAligned()
+                            .rotate(outerLocalRotation)
+                            .testTag("child")
+                    ) {
+                        Text(text = "Panel")
+                    }
+                }
+            }
+        }
+
+        val totalEffectiveRotation = parentRotation * innerLocalRotation
+        val targetYaw = totalEffectiveRotation.eulerAngles.y
+        val targetYawOnlyRotation =
+            Quaternion.fromEulerAngles(pitch = 0f, yaw = targetYaw, roll = 0f)
+        val counterRotation = totalEffectiveRotation.inverse * targetYawOnlyRotation
+        val finalCombinedLocalRotation = totalEffectiveRotation * counterRotation
+        // Quaternion(x = 0f, y = 0.3755f, z = 0f, w = 0.9268f)
+        val expectedRotationInRoot = finalCombinedLocalRotation * outerLocalRotation
+
+        composeTestRule
+            .onSubspaceNodeWithTag("child")
+            .assertRotationInRootIsEqualTo(expectedRotationInRoot)
+    }
+
+    @Test
+    fun gravityAligned_chainedAfterTwoRotations_appliesCombinedRotation() {
+        val parentRotation = Quaternion.fromEulerAngles(pitch = 20f, yaw = 0f, roll = 20f)
+        val childInnerRotation = Quaternion.fromEulerAngles(pitch = 10f, yaw = 10f, roll = 0f)
+        val childOuterRotation = Quaternion.fromEulerAngles(pitch = 0f, yaw = 30f, roll = 0f)
+
+        composeTestRule.setContentWithCompatibilityForXr {
+            ApplicationSubspace {
+                SpatialBox(SubspaceModifier.rotate(parentRotation)) {
+                    SpatialPanel(
+                        SubspaceModifier.rotate(childInnerRotation)
+                            .rotate(childOuterRotation)
+                            .gravityAligned()
+                            .testTag("child")
+                    ) {
+                        Text(text = "Panel")
+                    }
+                }
+            }
+        }
+
+        val totalEffectiveRotation = parentRotation * childInnerRotation * childOuterRotation
+        val targetYaw = totalEffectiveRotation.eulerAngles.y
+        val yawOnlyRotation = Quaternion.fromEulerAngles(pitch = 0f, yaw = targetYaw, roll = 0f)
+        // Quaternion(x = 0f, y = 0.3556f, z = 0f, w = 0.9346f)
+        val counterRotation = totalEffectiveRotation.inverse * yawOnlyRotation
+        val expectedRootRotation = totalEffectiveRotation * counterRotation
+
+        composeTestRule
+            .onSubspaceNodeWithTag("child")
+            .assertRotationInRootIsEqualTo(expectedRootRotation, tolerance = 0.04f)
+    }
+
+    @Test
+    fun gravityAligned_modifierIsRemoved_resetsRotation() {
+        var isGravityAligned by mutableStateOf(true)
+        val parentRotation = Quaternion.fromEulerAngles(pitch = 30f, yaw = 0f, roll = 45f)
+
+        composeTestRule.setContentWithCompatibilityForXr {
+            ApplicationSubspace {
+                SpatialBox(SubspaceModifier.rotate(parentRotation)) {
+                    val modifier =
+                        if (isGravityAligned) {
+                            SubspaceModifier.gravityAligned()
+                        } else {
+                            SubspaceModifier
+                        }
+                    SpatialPanel(modifier.testTag("child")) { Text(text = "Panel") }
+                }
+            }
+        }
+
+        val yawOnlyRotation =
+            Quaternion.fromEulerAngles(pitch = 0f, yaw = parentRotation.eulerAngles.y, roll = 0f)
+        // Quaternion(x = -0.2391f, y = 0.099f, z = -0.3696f, w = 0.8924f)
+        val expectedCounterRotation = parentRotation.inverse * yawOnlyRotation
+        // Quaternion.Identity
+        val expectedRotationInRoot = parentRotation * expectedCounterRotation
+
+        composeTestRule
+            .onSubspaceNodeWithTag("child")
+            .assertRotationIsEqualTo(expectedCounterRotation)
+            .assertRotationInRootIsEqualTo(expectedRotationInRoot)
+
+        isGravityAligned = false
+        composeTestRule.waitForIdle()
+
+        // Without modifier: no calculation needed, local rotation is identity.
+        composeTestRule
+            .onSubspaceNodeWithTag("child")
+            .assertRotationIsEqualTo(Quaternion.Identity)
+            .assertRotationInRootIsEqualTo(parentRotation)
+    }
+
+    @Test
+    fun gravityAligned_onApplicationSubspace_alignsTiltedRootToWorld() {
+        composeTestRule.session = createFakeSession(composeTestRule.activity)
+        val tiltedRootNode =
+            GroupEntity.create(checkNotNull(composeTestRule.session), "tiltedRootNode")
+        val tiltedRootRotation = Quaternion.fromEulerAngles(pitch = 20f, yaw = 60f, roll = -25f)
+        tiltedRootNode.setPose(
+            relativeTo = Space.REAL_WORLD,
+            pose = Pose(rotation = tiltedRootRotation),
+        )
+
+        composeTestRule.setContentWithCompatibilityForXr {
+            CompositionLocalProvider(LocalSubspaceRootNode provides tiltedRootNode) {
+                ApplicationSubspace(modifier = SubspaceModifier.gravityAligned()) {
+                    SpatialPanel(modifier = SubspaceModifier.testTag("panel")) {
+                        Text(text = "Panel")
+                    }
+                }
+            }
+        }
+
+        val yawOnlyRotation =
+            Quaternion.fromEulerAngles(
+                pitch = 0f,
+                yaw = tiltedRootRotation.eulerAngles.y,
+                roll = 0f,
+            )
+        val expectedCounterRotation = tiltedRootRotation.inverse * yawOnlyRotation
+        val panelEntity =
+            composeTestRule.onSubspaceNodeWithTag("panel").fetchSemanticsNode().semanticsEntity
+        assertNotNull(panelEntity)
+        val actualFinalWorldRotation = panelEntity.getPose(relativeTo = Space.REAL_WORLD).rotation
+        val angleDifference = Quaternion.angle(actualFinalWorldRotation, yawOnlyRotation)
+        assertThat(angleDifference).isLessThan(0.01f)
+        composeTestRule
+            .onSubspaceNodeWithTag("panel")
+            .assertRotationIsEqualTo(Quaternion.Identity)
+            .assertRotationInRootIsEqualTo(expectedCounterRotation)
+    }
+
+    @Test
+    fun gravityAligned_degenerateCase_ultimateFallback() {
+        // This parent rotation points straight down.
+        val verticalParentRotation = Quaternion.fromEulerAngles(pitch = 90f, yaw = 45f, roll = 0f)
+
+        composeTestRule.setContentWithCompatibilityForXr {
+            ApplicationSubspace {
+                SpatialBox(SubspaceModifier.rotate(verticalParentRotation)) {
+                    // The child has no additional rotation.
+                    SpatialPanel(SubspaceModifier.gravityAligned().testTag("child")) {
+                        Text(text = "Panel")
+                    }
+                }
+            }
+        }
+
+        val expectedRootRotation = Quaternion.Identity
+
+        composeTestRule
+            .onSubspaceNodeWithTag("child")
+            .assertRotationInRootIsEqualTo(expectedRootRotation)
+    }
+}
diff --git a/xr/compose/integration-tests/testapp/build.gradle b/xr/compose/integration-tests/testapp/build.gradle
index 18fb287..22cd9d2 100644
--- a/xr/compose/integration-tests/testapp/build.gradle
+++ b/xr/compose/integration-tests/testapp/build.gradle
@@ -53,6 +53,7 @@
     implementation(project(":xr:scenecore:scenecore-spatial-rendering"))
     implementation(project(":xr:arcore:arcore"))
 
+    implementation("androidx.annotation:annotation:1.9.1")
     implementation("androidx.core:core-ktx:1.15.0")
     implementation("androidx.activity:activity-compose:1.10.0")
     implementation("androidx.media3:media3-exoplayer:1.6.0")
diff --git a/xr/compose/integration-tests/testapp/src/main/AndroidManifest.xml b/xr/compose/integration-tests/testapp/src/main/AndroidManifest.xml
index 48c91bb..6bbb703 100644
--- a/xr/compose/integration-tests/testapp/src/main/AndroidManifest.xml
+++ b/xr/compose/integration-tests/testapp/src/main/AndroidManifest.xml
@@ -131,6 +131,11 @@
             android:label="PanelEmbeddedSubspace"
             android:theme="@style/Theme.IntegrationTestsApp" />
         <activity
+            android:name=".usersubspace.UserSubspaceActivity"
+            android:exported="true"
+            android:label="UserSubspace"
+            android:theme="@style/Theme.IntegrationTestsApp" />
+        <activity
             android:name=".panelvolume.PanelVolume"
             android:exported="true"
             android:label="PanelVolume"
@@ -210,7 +215,13 @@
             android:enableOnBackInvokedCallback="true"
             android:label="Pose"
             android:theme="@style/Theme.IntegrationTestsApp" />
-
+        <activity
+            android:name=".gravityaligned.GravityAlignedActivity"
+            android:exported="true"
+            android:configChanges="screenSize|smallestScreenSize|orientation|screenLayout"
+            android:enableOnBackInvokedCallback="true"
+            android:label="@string/gravity_aligned_test_case"
+            android:theme="@style/Theme.IntegrationTestsApp" />
 
         <property
             android:name="android.window.PROPERTY_XR_ACTIVITY_START_MODE"
diff --git a/xr/compose/integration-tests/testapp/src/main/kotlin/androidx/xr/compose/testapp/MainActivity.kt b/xr/compose/integration-tests/testapp/src/main/kotlin/androidx/xr/compose/testapp/MainActivity.kt
index 7ffa6bf..272c656 100644
--- a/xr/compose/integration-tests/testapp/src/main/kotlin/androidx/xr/compose/testapp/MainActivity.kt
+++ b/xr/compose/integration-tests/testapp/src/main/kotlin/androidx/xr/compose/testapp/MainActivity.kt
@@ -13,7 +13,6 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
 package androidx.xr.compose.testapp
 
 import android.content.Intent
@@ -74,6 +73,7 @@
 import androidx.xr.compose.testapp.depthstacking.DepthStacking
 import androidx.xr.compose.testapp.focuschange.FSMFocusChangeActivity
 import androidx.xr.compose.testapp.focuschange.HSMFocusChangeActivity
+import androidx.xr.compose.testapp.gravityaligned.GravityAlignedActivity
 import androidx.xr.compose.testapp.lifecycle.LifecycleDataStore
 import androidx.xr.compose.testapp.lifecycle.OpenCloseActivity
 import androidx.xr.compose.testapp.lifecycle.ResizeActivity
@@ -99,16 +99,15 @@
 import androidx.xr.compose.testapp.ui.theme.IntegrationTestsAppTheme
 import androidx.xr.compose.testapp.ui.theme.Purple40
 import androidx.xr.compose.testapp.ui.theme.Purple80
+import androidx.xr.compose.testapp.usersubspace.UserSubspaceActivity
 import androidx.xr.compose.testapp.videoplayer.VideoPlayerActivity
 import java.text.SimpleDateFormat
 import java.util.Locale
 
 class MainActivity : ComponentActivity() {
-
     @OptIn(ExperimentalMaterial3Api::class)
     override fun onCreate(savedInstanceState: Bundle?) {
         super.onCreate(savedInstanceState)
-
         enableEdgeToEdge()
         obtainUserPermissions()
         setContent {
@@ -245,7 +244,6 @@
     @Composable
     private fun TestCases() {
         val context = LocalContext.current
-
         Row(modifier = Modifier.fillMaxWidth()) {
             Box(modifier = Modifier.fillMaxWidth()) {
                 Column(modifier = Modifier.padding(10.dp).verticalScroll(rememberScrollState())) {
@@ -267,11 +265,9 @@
                     TestCaseColumnRowItem(getString(R.string.cuj_gltf_entity_input_test_case)) {
                         startTest<SplitEngine>(getString(R.string.cuj_gltf_entity_input_test_case))
                     }
-
                     TestCaseColumnRowItem(getString(R.string.spatial_elevation_test)) {
                         startTest<SpatialElevation>()
                     }
-
                     TestCaseColumnRowItem(getString(R.string.spatial_layout_test)) {
                         startTest<SpatialCompose>(getString(R.string.spatial_layout_test))
                     }
@@ -281,7 +277,6 @@
                     TestCaseColumnRowItem(getString(R.string.backhandling_panel_test)) {
                         startTest<SpatialCompose>(getString(R.string.backhandling_panel_test))
                     }
-
                     TestCaseColumnRowItem(getString(R.string.mode_change_test)) {
                         startTest<ModeChange>()
                     }
@@ -315,6 +310,9 @@
                     TestCaseColumnRowItem(getString(R.string.panel_embedded_subspace_test_case)) {
                         startTest<PanelEmbeddedSubspace>()
                     }
+                    TestCaseColumnRowItem(getString(R.string.user_subspace_test_case)) {
+                        startTest<UserSubspaceActivity>()
+                    }
                     TestCaseColumnRowItem(getString(R.string.panel_volume_test_case)) {
                         startTest<PanelVolume>()
                     }
@@ -352,6 +350,9 @@
                         startTest<RuntimeSessionActivity>()
                     }
                     TestCaseColumnRowItem(getString(R.string.pose_test)) { startTest<Pose>() }
+                    TestCaseColumnRowItem(getString(R.string.gravity_aligned_test_case)) {
+                        startTest<GravityAlignedActivity>()
+                    }
                 }
             }
         }
diff --git a/xr/compose/integration-tests/testapp/src/main/kotlin/androidx/xr/compose/testapp/gravityaligned/GravityAlignedActivity.kt b/xr/compose/integration-tests/testapp/src/main/kotlin/androidx/xr/compose/testapp/gravityaligned/GravityAlignedActivity.kt
new file mode 100644
index 0000000..9000fe9
--- /dev/null
+++ b/xr/compose/integration-tests/testapp/src/main/kotlin/androidx/xr/compose/testapp/gravityaligned/GravityAlignedActivity.kt
@@ -0,0 +1,381 @@
+/*
+ * Copyright 2025 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 androidx.xr.compose.testapp.gravityaligned
+
+import android.os.Bundle
+import androidx.activity.ComponentActivity
+import androidx.activity.compose.setContent
+import androidx.compose.foundation.background
+import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.padding
+import androidx.compose.material3.Slider
+import androidx.compose.material3.Switch
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.derivedStateOf
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableFloatStateOf
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.remember
+import androidx.compose.runtime.setValue
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.text.font.FontWeight
+import androidx.compose.ui.text.style.TextAlign
+import androidx.compose.ui.unit.dp
+import androidx.compose.ui.unit.sp
+import androidx.xr.compose.spatial.ApplicationSubspace
+import androidx.xr.compose.subspace.SpatialBox
+import androidx.xr.compose.subspace.SpatialColumn
+import androidx.xr.compose.subspace.SpatialPanel
+import androidx.xr.compose.subspace.SpatialRow
+import androidx.xr.compose.subspace.SubspaceComposable
+import androidx.xr.compose.subspace.layout.SpatialArrangement
+import androidx.xr.compose.subspace.layout.SubspaceModifier
+import androidx.xr.compose.subspace.layout.gravityAligned
+import androidx.xr.compose.subspace.layout.height
+import androidx.xr.compose.subspace.layout.rotate
+import androidx.xr.compose.subspace.layout.testTag
+import androidx.xr.compose.subspace.layout.width
+import androidx.xr.compose.testapp.ui.theme.IntegrationTestsAppTheme
+import androidx.xr.runtime.math.Quaternion
+
+/**
+ * Test Activity for the [gravityAligned] modifier. This app displays 5 different test cases in
+ * vertical columns to validate the modifier's behavior under various rotation and hierarchy
+ * scenarios.
+ */
+class GravityAlignedActivity : ComponentActivity() {
+    override fun onCreate(savedInstanceState: Bundle?) {
+        super.onCreate(savedInstanceState)
+        setContent {
+            IntegrationTestsAppTheme {
+                ApplicationSubspace(
+                    modifier =
+                        SubspaceModifier.width(1600.dp)
+                            .height(2200.dp)
+                            .testTag("ApplicationSubspace")
+                ) {
+                    // Main layout: a Row containing two Columns
+                    SpatialRow(
+                        modifier = SubspaceModifier.testTag("TestBedRoot"),
+                        horizontalArrangement = SpatialArrangement.spacedBy(24.dp),
+                    ) {
+                        // Left Column (Cases 1 & 2)
+                        SpatialColumn(verticalArrangement = SpatialArrangement.spacedBy(50.dp)) {
+                            // Case 1: No nested rotation, no chained rotate modifiers
+                            TestCaseRow(
+                                title = "Case 1:\nLevel Row + Panel in Single Rotate Box",
+                                rowRotation = Quaternion.Identity,
+                            ) {
+                                GravityAlignedTestPanel()
+                            }
+
+                            // Case 2: No nested rotation, chained rotate modifiers
+                            TestCaseRow(
+                                title = "Case 2:\nLevel Row + Panel in Double Rotate Box",
+                                rowRotation = Quaternion.Identity,
+                            ) {
+                                GravityAlignedDoubleRotateTestPanel()
+                            }
+                        }
+
+                        // Right Column (Cases 3, 4, & 5)
+                        SpatialColumn(verticalArrangement = SpatialArrangement.spacedBy(50.dp)) {
+                            // Case 3: Nested rotation, no chained rotate modifiers
+                            TestCaseRow(
+                                title = "Case 3:\nTilted Row + Panel Single Rotate Box",
+                                rowRotation = Quaternion.fromEulerAngles(20f, -20f, 0f),
+                            ) {
+                                GravityAlignedTestPanel()
+                            }
+
+                            // Case 4: Nested rotation, chained rotate modifiers
+                            TestCaseRow(
+                                title = "Case 4:\nTilted Row + Panel in Double Rotate Box",
+                                rowRotation = Quaternion.fromEulerAngles(20f, -17f, -61f),
+                            ) {
+                                GravityAlignedDoubleRotateTestPanel()
+                            }
+
+                            // Case 5: Nested rotation, and chained rotate modifier on the child
+                            // panel
+                            TestCaseRow(
+                                title =
+                                    "Case 5:\nTilted Row + Rotated then GravityAligned Panel in Double Rotate Box",
+                                rowRotation = Quaternion.fromEulerAngles(-30f, 11f, 22f),
+                            ) {
+                                CaseChainedGravityTestPanel()
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+}
+
+/**
+ * A reusable container for a single test case row. A title panel is on the left and the test target
+ * content is on right side. It applies a rotation only to the content.
+ */
+@SubspaceComposable
+@Composable
+private fun TestCaseRow(
+    title: String,
+    rowRotation: Quaternion,
+    content: @Composable @SubspaceComposable () -> Unit,
+) {
+    SpatialRow(
+        modifier = SubspaceModifier.width(800.dp).height(300.dp),
+        horizontalArrangement = SpatialArrangement.spacedBy(24.dp),
+    ) {
+        // Title Panel, always level.
+        SpatialPanel(modifier = SubspaceModifier.width(300.dp)) {
+            Box(
+                modifier = Modifier.fillMaxSize().background(Color(0xFF222233)).padding(16.dp),
+                contentAlignment = Alignment.Center,
+            ) {
+                Text(
+                    text = title,
+                    color = Color.White,
+                    fontSize = 22.sp,
+                    fontWeight = FontWeight.Bold,
+                    textAlign = TextAlign.Start,
+                )
+            }
+        }
+
+        // Test target, this is the row that gets rotated.
+        SpatialRow(
+            modifier = SubspaceModifier.width(426.dp).height(400.dp).rotate(rowRotation),
+            horizontalArrangement = SpatialArrangement.spacedBy(24.dp),
+        ) {
+            content()
+        }
+    }
+}
+
+/**
+ * A shared, stateless 2D Composable that renders the UI controls (sliders and switch). This removes
+ * code duplication from the interactive test panels.
+ */
+@Composable
+private fun GravityTestControls(
+    isGravityAligned: Boolean,
+    onGravityAlignedChange: (Boolean) -> Unit,
+    pitch: Float,
+    onPitchChange: (Float) -> Unit,
+    roll: Float,
+    onRollChange: (Float) -> Unit,
+    yaw: Float,
+    onYawChange: (Float) -> Unit,
+    title: String? = null,
+) {
+    Column(
+        modifier =
+            Modifier.fillMaxSize()
+                .background(Color(0xFF333333)) // Dark background
+                .padding(16.dp),
+        horizontalAlignment = Alignment.CenterHorizontally,
+        verticalArrangement = Arrangement.spacedBy(1.dp),
+    ) {
+        // Title and Toggle Row
+        Row(
+            modifier = Modifier.fillMaxWidth().padding(vertical = 8.dp),
+            verticalAlignment = Alignment.CenterVertically,
+            horizontalArrangement = Arrangement.SpaceBetween,
+        ) {
+            if (title != null) {
+                Text(title, color = Color.White, fontSize = 24.sp, fontWeight = FontWeight.SemiBold)
+            }
+            Row( // Inner row to keep toggle and text together
+                verticalAlignment = Alignment.CenterVertically,
+                horizontalArrangement = Arrangement.spacedBy(8.dp),
+            ) {
+                Text(
+                    "gravityAligned()",
+                    color = if (isGravityAligned) Color.Cyan else Color.White,
+                    fontSize = 20.sp,
+                )
+                Switch(checked = isGravityAligned, onCheckedChange = onGravityAlignedChange)
+            }
+        }
+
+        // Sliders for parent rotation
+        Row(
+            modifier = Modifier.fillMaxWidth().padding(vertical = 8.dp),
+            verticalAlignment = Alignment.CenterVertically,
+            horizontalArrangement = Arrangement.spacedBy(4.dp),
+        ) {
+            Text("Parent Pitch: ${pitch.toInt()}°", color = Color.White, fontSize = 16.sp)
+            Slider(value = pitch, onValueChange = onPitchChange, valueRange = -90f..90f)
+        }
+
+        Row(
+            modifier = Modifier.fillMaxWidth().padding(vertical = 8.dp),
+            verticalAlignment = Alignment.CenterVertically,
+            horizontalArrangement = Arrangement.spacedBy(4.dp),
+        ) {
+            Text("Parent Roll: ${roll.toInt()}°", color = Color.White, fontSize = 16.sp)
+            Slider(value = roll, onValueChange = onRollChange, valueRange = -90f..90f)
+        }
+
+        Row(
+            modifier = Modifier.fillMaxWidth().padding(vertical = 8.dp),
+            verticalAlignment = Alignment.CenterVertically,
+            horizontalArrangement = Arrangement.spacedBy(4.dp),
+        ) {
+            Text("Parent Yaw: ${yaw.toInt()}°", color = Color.White, fontSize = 16.sp)
+            Slider(value = yaw, onValueChange = onYawChange, valueRange = -180f..180f)
+        }
+    }
+}
+
+/**
+ * Interactive Test Panel: Tests [SpatialBox(rotate)] -> [SpatialPanel(gravityAligned)] (Used for
+ * Cases 1 and 3)
+ */
+@SubspaceComposable
+@Composable
+private fun GravityAlignedTestPanel(modifier: SubspaceModifier = SubspaceModifier) {
+    var parentPitch by remember { mutableFloatStateOf(17f) }
+    var parentYaw by remember { mutableFloatStateOf(29f) }
+    var parentRoll by remember { mutableFloatStateOf(39f) }
+    var isGravityAligned by remember { mutableStateOf(true) }
+    val parentRotation by remember {
+        derivedStateOf {
+            Quaternion.fromEulerAngles(pitch = parentPitch, yaw = parentYaw, roll = parentRoll)
+        }
+    }
+    SpatialBox(
+        modifier =
+            SubspaceModifier.width(450.dp)
+                .height(400.dp)
+                .rotate(parentRotation)
+                .testTag("SingleRotateBox")
+    ) {
+        val updatedModifier = if (isGravityAligned) modifier.gravityAligned() else modifier
+        SpatialPanel(modifier = updatedModifier.testTag("TestPanel")) {
+            GravityTestControls(
+                isGravityAligned = isGravityAligned,
+                onGravityAlignedChange = { isGravityAligned = it },
+                pitch = parentPitch,
+                onPitchChange = { parentPitch = it },
+                roll = parentRoll,
+                onRollChange = { parentRoll = it },
+                yaw = parentYaw,
+                onYawChange = { parentYaw = it },
+            )
+        }
+    }
+}
+
+/**
+ * Interactive Test Panel: Tests [SpatialBox(rotate.rotate)] -> [SpatialPanel(gravityAligned)] (Used
+ * for Cases 2 and 4)
+ */
+@SubspaceComposable
+@Composable
+private fun GravityAlignedDoubleRotateTestPanel(modifier: SubspaceModifier = SubspaceModifier) {
+    var pitch by remember { mutableFloatStateOf(30f) }
+    var roll by remember { mutableFloatStateOf(30f) }
+    var yaw by remember { mutableFloatStateOf(0f) }
+    var isGravityAligned by remember { mutableStateOf(true) }
+    // Create two separate rotation objects from the same slider state
+    val outerRotation by remember {
+        derivedStateOf { Quaternion.fromEulerAngles(pitch = pitch, yaw = yaw, roll = roll) }
+    }
+    val innerRotation by remember {
+        derivedStateOf { Quaternion.fromEulerAngles(pitch = pitch, yaw = yaw, roll = roll) }
+    }
+
+    SpatialBox(
+        modifier =
+            SubspaceModifier.width(426.dp)
+                .height(400.dp)
+                .rotate(innerRotation)
+                .rotate(outerRotation)
+                .testTag("DoubleRotateBox")
+    ) {
+        val updatedModifier = if (isGravityAligned) modifier.gravityAligned() else modifier
+        SpatialPanel(modifier = updatedModifier.testTag("TestPanel")) {
+            GravityTestControls(
+                isGravityAligned = isGravityAligned,
+                onGravityAlignedChange = { isGravityAligned = it },
+                pitch = pitch,
+                onPitchChange = { pitch = it },
+                roll = roll,
+                onRollChange = { roll = it },
+                yaw = yaw,
+                onYawChange = { yaw = it },
+            )
+        }
+    }
+}
+
+/**
+ * Interactive Test Panel: Tests [SpatialBox(rotate)] -> [SpatialPanel(rotate.gravityAligned)] This
+ * panel lives in a tilted row, AND has its OWN local rotation controlled by sliders, which is then
+ * passed to the gravityAligned modifier. (Used for Case 5)
+ */
+@SubspaceComposable
+@Composable
+private fun CaseChainedGravityTestPanel(modifier: SubspaceModifier = SubspaceModifier) {
+    var pitch by remember { mutableFloatStateOf(17f) }
+    var yaw by remember { mutableFloatStateOf(29f) }
+    var roll by remember { mutableFloatStateOf(-29f) }
+    var isGravityAligned by remember { mutableStateOf(true) }
+    // This is the static rotation of the Box BETWEEN the Tilted Row and the Panel.
+    val parentBoxRotation = Quaternion.fromEulerAngles(10f, -50f, 10f)
+    // This rotation is applied LOCALLY to the panel, *before* gravityAligned
+    val childLocalRotation by remember {
+        derivedStateOf { Quaternion.fromEulerAngles(pitch = pitch, yaw = yaw, roll = roll) }
+    }
+    val panelModifier =
+        if (isGravityAligned) {
+            SubspaceModifier.rotate(childLocalRotation).gravityAligned()
+        } else {
+            SubspaceModifier.rotate(childLocalRotation)
+        }
+    SpatialBox(
+        modifier =
+            SubspaceModifier.width(426.dp)
+                .height(400.dp)
+                .rotate(parentBoxRotation) // Add the extra layer of parent rotation
+                .testTag("ChainedTestBox")
+    ) {
+        SpatialPanel(modifier = panelModifier.testTag("ChainedTestPanel")) {
+            GravityTestControls(
+                isGravityAligned = isGravityAligned,
+                onGravityAlignedChange = { isGravityAligned = it },
+                pitch = pitch,
+                onPitchChange = { pitch = it },
+                roll = roll,
+                onRollChange = { roll = it },
+                yaw = yaw,
+                onYawChange = { yaw = it },
+            )
+        }
+    }
+}
diff --git a/xr/compose/integration-tests/testapp/src/main/kotlin/androidx/xr/compose/testapp/usersubspace/UserSubspaceActivity.kt b/xr/compose/integration-tests/testapp/src/main/kotlin/androidx/xr/compose/testapp/usersubspace/UserSubspaceActivity.kt
new file mode 100644
index 0000000..a8a79272
--- /dev/null
+++ b/xr/compose/integration-tests/testapp/src/main/kotlin/androidx/xr/compose/testapp/usersubspace/UserSubspaceActivity.kt
@@ -0,0 +1,349 @@
+/*
+ * Copyright 2025 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 androidx.xr.compose.testapp.usersubspace
+
+import android.os.Bundle
+import androidx.activity.ComponentActivity
+import androidx.activity.compose.setContent
+import androidx.activity.enableEdgeToEdge
+import androidx.compose.foundation.background
+import androidx.compose.foundation.clickable
+import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.Spacer
+import androidx.compose.foundation.layout.fillMaxHeight
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.height
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.size
+import androidx.compose.foundation.layout.width
+import androidx.compose.material.icons.Icons
+import androidx.compose.material.icons.filled.Check
+import androidx.compose.material.icons.filled.Circle
+import androidx.compose.material3.Card
+import androidx.compose.material3.CardDefaults
+import androidx.compose.material3.ExperimentalMaterial3Api
+import androidx.compose.material3.Icon
+import androidx.compose.material3.Slider
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableIntStateOf
+import androidx.compose.runtime.mutableStateListOf
+import androidx.compose.runtime.remember
+import androidx.compose.runtime.setValue
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.text.SpanStyle
+import androidx.compose.ui.text.buildAnnotatedString
+import androidx.compose.ui.text.font.FontWeight
+import androidx.compose.ui.text.withStyle
+import androidx.compose.ui.unit.dp
+import androidx.compose.ui.unit.sp
+import androidx.xr.compose.platform.LocalSession
+import androidx.xr.compose.spatial.ExperimentalUserSubspaceApi
+import androidx.xr.compose.spatial.UserSubspace
+import androidx.xr.compose.subspace.BodyPart
+import androidx.xr.compose.subspace.LockDimensions
+import androidx.xr.compose.subspace.LockingBehavior
+import androidx.xr.compose.subspace.SpatialColumn
+import androidx.xr.compose.subspace.SpatialCurvedRow
+import androidx.xr.compose.subspace.SpatialPanel
+import androidx.xr.compose.subspace.layout.SubspaceModifier
+import androidx.xr.compose.subspace.layout.height
+import androidx.xr.compose.subspace.layout.offset
+import androidx.xr.compose.subspace.layout.width
+import androidx.xr.compose.testapp.ui.components.TopBarWithBackArrow
+import androidx.xr.runtime.Config
+import java.time.LocalDate
+import java.time.format.TextStyle
+import java.util.Locale
+
+data class TodoItem(val description: String, val isCompleted: Boolean)
+
+class UserSubspaceActivity : ComponentActivity() {
+    override fun onCreate(savedInstanceState: Bundle?) {
+        super.onCreate(savedInstanceState)
+        enableEdgeToEdge()
+        setContent { MainContent() }
+    }
+
+    @OptIn(ExperimentalUserSubspaceApi::class, ExperimentalMaterial3Api::class)
+    @Composable
+    private fun MainContent() {
+        val session = checkNotNull(LocalSession.current) { "session must be initialized" }
+        session.configure(
+            config = session.config.copy(headTracking = Config.HeadTrackingMode.LAST_KNOWN)
+        )
+
+        val todoItems = remember {
+            mutableStateListOf(
+                TodoItem("Buy groceries", true),
+                TodoItem("Finish report", false),
+                TodoItem("Review PRs", false),
+            )
+        }
+        // State for the lazy lock duration slider
+        var lazyLockDuration by remember { mutableIntStateOf(1500) }
+
+        UserSubspace(
+            behavior = LockingBehavior.static(),
+            modifier = SubspaceModifier.offset(z = (-200).dp),
+        ) {
+            SpatialPanel(SubspaceModifier.height(400.dp).width(600.dp)) {
+                Column(
+                    Modifier.fillMaxWidth()
+                        .fillMaxHeight()
+                        .background(Color.White)
+                        .padding(all = 32.dp)
+                ) {
+                    Text(
+                        text =
+                            buildAnnotatedString {
+                                withStyle(style = SpanStyle(fontWeight = FontWeight.Bold)) {
+                                    append("Duration")
+                                }
+                                append(
+                                    " - Adjusts the time, in milliseconds, it takes for the " +
+                                        "content to catch up to the user.\n"
+                                )
+                            },
+                        fontSize = 16.sp,
+                    )
+                }
+            }
+        }
+        UserSubspace(
+            lockTo = BodyPart.Head,
+            behavior = LockingBehavior.lazy(durationMs = lazyLockDuration),
+        ) {
+            SpatialPanel(SubspaceModifier.height(300.dp).width(600.dp).offset(y = (-250).dp)) {
+                Box(Modifier.fillMaxSize().background(Color.Cyan)) {
+                    Row(modifier = Modifier.fillMaxWidth()) {
+                        TopBarWithBackArrow(
+                            scrollBehavior = null,
+                            title = "",
+                            onClick = { this@UserSubspaceActivity.finish() },
+                        )
+                    }
+                    Column(
+                        modifier = Modifier.fillMaxSize().padding(top = 50.dp),
+                        horizontalAlignment = Alignment.CenterHorizontally,
+                        verticalArrangement = Arrangement.Center,
+                    ) {
+                        PanelHeader("CONTROL PANEL - HEAD LOCKED")
+                        LazyLockSlider(
+                            duration = lazyLockDuration,
+                            onDurationChange = { lazyLockDuration = it.toInt() },
+                        )
+                    }
+                }
+            }
+        }
+        UserSubspace(
+            lockDimensions =
+                LockDimensions(
+                    isTranslationXTracked = true,
+                    isTranslationYTracked = true,
+                    isTranslationZTracked = true,
+                ),
+            behavior = LockingBehavior.lazy(durationMs = lazyLockDuration.toInt()),
+        ) {
+            SpatialCurvedRow(SubspaceModifier.width(1000.dp).height(300.dp), curveRadius = 500.dp) {
+                // To-Do List Card
+                SpatialColumn(SubspaceModifier.width(250.dp)) {
+                    TodoListCard(todoItems) { updatedItem ->
+                        val index =
+                            todoItems.indexOfFirst { it.description == updatedItem.description }
+                        if (index != -1) {
+                            todoItems[index] =
+                                updatedItem.copy(isCompleted = !updatedItem.isCompleted)
+                        }
+                    }
+                }
+                // Empty spacer
+                SpatialColumn(SubspaceModifier.width(500.dp)) {}
+                // Calendar Card
+                SpatialColumn(SubspaceModifier.width(250.dp)) { CalendarCard() }
+            }
+        }
+    }
+
+    @Composable
+    private fun LazyLockSlider(duration: Int, onDurationChange: (Float) -> Unit) {
+        Column(
+            modifier = Modifier.width(400.dp).padding(horizontal = 16.dp),
+            horizontalAlignment = Alignment.CenterHorizontally,
+        ) {
+            Text(
+                text = "Duration: $duration milliseconds",
+                fontWeight = FontWeight.Bold,
+                fontSize = 14.sp,
+            )
+            val min = 1f
+            val max = 3000f
+            val increment = 100f
+            val totalValues = ((max - min) / increment) + 1
+            val steps = (totalValues - 1).toInt()
+            Slider(
+                value = duration.toFloat(),
+                onValueChange = onDurationChange,
+                valueRange = min..max,
+                steps = steps,
+            )
+        }
+    }
+
+    @Composable
+    private fun TodoListCard(todoItems: List<TodoItem>, onItemClick: (TodoItem) -> Unit) {
+        SpatialPanel {
+            Card(
+                modifier = Modifier.fillMaxSize(),
+                colors = CardDefaults.cardColors(containerColor = Color(0xFFE2F0EA)),
+            ) {
+                Column(modifier = Modifier.padding(16.dp)) {
+                    PanelHeader("TODO LIST - BODY LOCKED")
+                    todoItems.forEachIndexed { index, item ->
+                        Row(
+                            modifier = Modifier.fillMaxWidth().clickable { onItemClick(item) },
+                            verticalAlignment = Alignment.CenterVertically,
+                        ) {
+                            if (item.isCompleted) {
+                                Icon(
+                                    imageVector = Icons.Default.Check,
+                                    contentDescription = "Completed",
+                                    tint = Color(0xFF4CAF50),
+                                    modifier = Modifier.size(24.dp),
+                                )
+                            } else {
+                                Icon(
+                                    imageVector = Icons.Default.Circle,
+                                    contentDescription = "Incomplete",
+                                    tint = Color(0xFF757575),
+                                    modifier = Modifier.size(24.dp),
+                                )
+                            }
+                            Spacer(Modifier.width(8.dp))
+                            Text(
+                                item.description,
+                                fontSize = 16.sp,
+                                color = if (item.isCompleted) Color.Gray else Color.Black,
+                            )
+                        }
+                        Spacer(Modifier.height(8.dp))
+                    }
+                }
+            }
+        }
+    }
+
+    @Composable
+    private fun CalendarCard() {
+        val currentDate = LocalDate.now()
+        val currentMonth = currentDate.month.getDisplayName(TextStyle.FULL, Locale.getDefault())
+        val currentYear = currentDate.year
+        val currentDay = currentDate.dayOfMonth
+        val daysInMonth = currentDate.lengthOfMonth()
+        val firstDayOfMonth = currentDate.withDayOfMonth(1)
+        val firstDayOfWeekIndex = firstDayOfMonth.dayOfWeek.value % 7
+        SpatialPanel {
+            Card(
+                modifier = Modifier.fillMaxSize(),
+                colors = CardDefaults.cardColors(containerColor = Color(0xFFE2F0EA)),
+            ) {
+                Column(
+                    modifier = Modifier.padding(16.dp),
+                    horizontalAlignment = Alignment.CenterHorizontally,
+                ) {
+                    PanelHeader("CALENDAR - BODY LOCKED")
+                    Text(
+                        text = "$currentMonth $currentYear",
+                        fontSize = 18.sp,
+                        fontWeight = FontWeight.SemiBold,
+                    )
+                    Spacer(Modifier.height(16.dp))
+                    Row(
+                        modifier = Modifier.fillMaxWidth(),
+                        horizontalArrangement = Arrangement.SpaceAround,
+                    ) {
+                        listOf("Mo", "Tu", "We", "Th", "Fr", "Sa", "Su").forEach {
+                            Text(it, fontWeight = FontWeight.Bold, fontSize = 14.sp)
+                        }
+                    }
+                    Spacer(Modifier.height(8.dp))
+                    Column {
+                        val daysList = (1..daysInMonth).toList().toIntArray()
+                        var dayIndex = 0
+                        for (week in 0 until 6) {
+                            Row(
+                                modifier = Modifier.fillMaxWidth(),
+                                horizontalArrangement = Arrangement.SpaceAround,
+                            ) {
+                                for (dayOfWeek in 0..6) {
+                                    val cellIndex = week * 7 + dayOfWeek
+                                    val dayToDisplay =
+                                        if (
+                                            cellIndex >= firstDayOfWeekIndex &&
+                                                dayIndex < daysList.size
+                                        ) {
+                                            daysList[dayIndex].also { dayIndex++ }
+                                        } else {
+                                            null
+                                        }
+                                    if (dayToDisplay != null) {
+                                        Box(
+                                            modifier =
+                                                Modifier.size(24.dp)
+                                                    .background(
+                                                        if (dayToDisplay == currentDay)
+                                                            Color(0xFF4CAF50)
+                                                        else Color.Transparent
+                                                    ),
+                                            contentAlignment = Alignment.Center,
+                                        ) {
+                                            Text(
+                                                "$dayToDisplay",
+                                                fontSize = 12.sp,
+                                                color =
+                                                    if (dayToDisplay == currentDay) Color.White
+                                                    else Color.Black,
+                                            )
+                                        }
+                                    } else {
+                                        Spacer(Modifier.size(24.dp))
+                                    }
+                                }
+                            }
+                            Spacer(Modifier.height(4.dp))
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    @Composable
+    private fun PanelHeader(title: String) {
+        Text(text = title, fontWeight = FontWeight.Bold, fontSize = 15.sp)
+        Spacer(Modifier.height(8.dp))
+        Box(Modifier.width(150.dp).height(2.dp).background(Color.DarkGray))
+        Spacer(Modifier.height(16.dp))
+    }
+}
diff --git a/xr/compose/integration-tests/testapp/src/main/res/values/strings.xml b/xr/compose/integration-tests/testapp/src/main/res/values/strings.xml
index 917af01..53d7bbc 100644
--- a/xr/compose/integration-tests/testapp/src/main/res/values/strings.xml
+++ b/xr/compose/integration-tests/testapp/src/main/res/values/strings.xml
@@ -3,7 +3,6 @@
     <string name="title_activity_mode_change">Compose Mode Change Test Case</string>
     <string name="title_activity_media_player">Video in Spatial Panel Test Case</string>
     <string name="title_activity_rotation">Panel/Layout rotation Test Case</string>
-
     <string name="mode_change_test">Compose Mode Change Test Case</string>
     <string name="panel_rotation_test">Panel/Layout rotation Test Case</string>
     <string name="media_player_panel_test">CUJ: Media Player Panel Test</string>
@@ -26,6 +25,7 @@
     <string name="cuj_gltf_animation_test_case">GLTF Animation Test Case</string>
     <string name="depthstacking_modifier_order_test_case">DepthStacking and ModifierOrder Layout Test Case</string>
     <string name="panel_embedded_subspace_test_case">Panel Embedded Subspace Layout Test Case</string>
+    <string name="user_subspace_test_case">User Subspace Layout Test Case</string>
     <string name="panel_volume_test_case">Panel Volume Layout Test Case</string>
     <string name="resizable_panel_test_case">Resizable Panel Test Case</string>
     <string name="spatial_alignment_usage_test_case">Spatial Alignment Usage Test Case</string>
@@ -38,10 +38,9 @@
     <string name="lifecycle_resize_test">Resizing Panel Test Case</string>
     <string name="lifecycle_runtime_session_test">Runtime Session Test Case</string>
     <string name="pose_test">Pose Test Case</string>
-
-
+    <string name="gravity_aligned_test_case">Gravity Aligned Test Case</string>
     <string name="hello_android_xr">Hello Android XR.</string>
     <string name="switch_to_home_space_mode">Switch to Home Space Mode</string>
     <string name="switch_to_full_space_mode">Switch to Full Space Mode</string>
     <string name="accessibility_test">Accessibility test case</string>
-</resources>
\ No newline at end of file
+</resources>
diff --git a/xr/compose/material3/material3/src/main/res/values-af/strings.xml b/xr/compose/material3/material3/src/main/res/values-af/strings.xml
deleted file mode 100644
index 9ee5ec3..0000000
--- a/xr/compose/material3/material3/src/main/res/values-af/strings.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-  Copyright 2025 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.
-   -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="xr_compose_material3_space_mode_switch_collapse" msgid="2304391857258488376">"Vou in HomeSpaceMode in"</string>
-    <string name="xr_compose_material3_space_mode_switch_expand" msgid="2967869985415673240">"Vou in FullSpaceMode uit"</string>
-</resources>
diff --git a/xr/compose/material3/material3/src/main/res/values-am/strings.xml b/xr/compose/material3/material3/src/main/res/values-am/strings.xml
deleted file mode 100644
index fbb8e16..0000000
--- a/xr/compose/material3/material3/src/main/res/values-am/strings.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-  Copyright 2025 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.
-   -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="xr_compose_material3_space_mode_switch_collapse" msgid="2304391857258488376">"ወደ HomeSpaceMode ሰብስብ"</string>
-    <string name="xr_compose_material3_space_mode_switch_expand" msgid="2967869985415673240">"ወደ FullSpaceMode ዘርጋ"</string>
-</resources>
diff --git a/xr/compose/material3/material3/src/main/res/values-ar/strings.xml b/xr/compose/material3/material3/src/main/res/values-ar/strings.xml
deleted file mode 100644
index c06985f..0000000
--- a/xr/compose/material3/material3/src/main/res/values-ar/strings.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-  Copyright 2025 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.
-   -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="xr_compose_material3_space_mode_switch_collapse" msgid="2304391857258488376">"التصغير إلى وضع \"مساحة الصفحة الرئيسية\""</string>
-    <string name="xr_compose_material3_space_mode_switch_expand" msgid="2967869985415673240">"التوسيع إلى وضع \"المساحة الكاملة\""</string>
-</resources>
diff --git a/xr/compose/material3/material3/src/main/res/values-as/strings.xml b/xr/compose/material3/material3/src/main/res/values-as/strings.xml
deleted file mode 100644
index 9be6b96..0000000
--- a/xr/compose/material3/material3/src/main/res/values-as/strings.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-  Copyright 2025 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.
-   -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="xr_compose_material3_space_mode_switch_collapse" msgid="2304391857258488376">"HomeSpaceModeলৈ সংকোচন কৰক"</string>
-    <string name="xr_compose_material3_space_mode_switch_expand" msgid="2967869985415673240">"FullSpaceModeলৈ বিস্তাৰ কৰক"</string>
-</resources>
diff --git a/xr/compose/material3/material3/src/main/res/values-az/strings.xml b/xr/compose/material3/material3/src/main/res/values-az/strings.xml
deleted file mode 100644
index cd923e3..0000000
--- a/xr/compose/material3/material3/src/main/res/values-az/strings.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-  Copyright 2025 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.
-   -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="xr_compose_material3_space_mode_switch_collapse" msgid="2304391857258488376">"HomeSpaceMode-a yığcamlaşdırın"</string>
-    <string name="xr_compose_material3_space_mode_switch_expand" msgid="2967869985415673240">"FullSpaceMode-a genişləndirin"</string>
-</resources>
diff --git a/xr/compose/material3/material3/src/main/res/values-b+sr+Latn/strings.xml b/xr/compose/material3/material3/src/main/res/values-b+sr+Latn/strings.xml
deleted file mode 100644
index 36615d6..0000000
--- a/xr/compose/material3/material3/src/main/res/values-b+sr+Latn/strings.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-  Copyright 2025 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.
-   -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="xr_compose_material3_space_mode_switch_collapse" msgid="2304391857258488376">"Skupi na početni režim prostora"</string>
-    <string name="xr_compose_material3_space_mode_switch_expand" msgid="2967869985415673240">"Proširi na puni režim prostora"</string>
-</resources>
diff --git a/xr/compose/material3/material3/src/main/res/values-be/strings.xml b/xr/compose/material3/material3/src/main/res/values-be/strings.xml
deleted file mode 100644
index c4fac8b..0000000
--- a/xr/compose/material3/material3/src/main/res/values-be/strings.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-  Copyright 2025 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.
-   -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="xr_compose_material3_space_mode_switch_collapse" msgid="2304391857258488376">"Згарнуць у рэжым галоўнага экрана"</string>
-    <string name="xr_compose_material3_space_mode_switch_expand" msgid="2967869985415673240">"Разгарнуць у поўнаэкранны рэжым"</string>
-</resources>
diff --git a/xr/compose/material3/material3/src/main/res/values-bg/strings.xml b/xr/compose/material3/material3/src/main/res/values-bg/strings.xml
deleted file mode 100644
index 061fd35..0000000
--- a/xr/compose/material3/material3/src/main/res/values-bg/strings.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-  Copyright 2025 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.
-   -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="xr_compose_material3_space_mode_switch_collapse" msgid="2304391857258488376">"Свиване в HomeSpaceMode"</string>
-    <string name="xr_compose_material3_space_mode_switch_expand" msgid="2967869985415673240">"Разгъване в FullSpaceMode"</string>
-</resources>
diff --git a/xr/compose/material3/material3/src/main/res/values-bn/strings.xml b/xr/compose/material3/material3/src/main/res/values-bn/strings.xml
deleted file mode 100644
index 27e97b4..0000000
--- a/xr/compose/material3/material3/src/main/res/values-bn/strings.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-  Copyright 2025 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.
-   -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="xr_compose_material3_space_mode_switch_collapse" msgid="2304391857258488376">"HomeSpaceMode-এ আড়াল করুন"</string>
-    <string name="xr_compose_material3_space_mode_switch_expand" msgid="2967869985415673240">"FullSpaceMode-এ বড় করে দেখুন"</string>
-</resources>
diff --git a/xr/compose/material3/material3/src/main/res/values-bs/strings.xml b/xr/compose/material3/material3/src/main/res/values-bs/strings.xml
deleted file mode 100644
index 02831b3..0000000
--- a/xr/compose/material3/material3/src/main/res/values-bs/strings.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-  Copyright 2025 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.
-   -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="xr_compose_material3_space_mode_switch_collapse" msgid="2304391857258488376">"Suzi u HomeSpaceMode"</string>
-    <string name="xr_compose_material3_space_mode_switch_expand" msgid="2967869985415673240">"Proširi u FullSpaceMode"</string>
-</resources>
diff --git a/xr/compose/material3/material3/src/main/res/values-ca/strings.xml b/xr/compose/material3/material3/src/main/res/values-ca/strings.xml
deleted file mode 100644
index d2b15a4..0000000
--- a/xr/compose/material3/material3/src/main/res/values-ca/strings.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-  Copyright 2025 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.
-   -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="xr_compose_material3_space_mode_switch_collapse" msgid="2304391857258488376">"Replega al mode d\'espai d\'inici"</string>
-    <string name="xr_compose_material3_space_mode_switch_expand" msgid="2967869985415673240">"Desplega al mode d\'espai complet"</string>
-</resources>
diff --git a/xr/compose/material3/material3/src/main/res/values-cs/strings.xml b/xr/compose/material3/material3/src/main/res/values-cs/strings.xml
deleted file mode 100644
index 0c02905..0000000
--- a/xr/compose/material3/material3/src/main/res/values-cs/strings.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-  Copyright 2025 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.
-   -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="xr_compose_material3_space_mode_switch_collapse" msgid="2304391857258488376">"Sbalit do režimu HomeSpaceMode"</string>
-    <string name="xr_compose_material3_space_mode_switch_expand" msgid="2967869985415673240">"Rozbalit do režimu FullSpaceMode"</string>
-</resources>
diff --git a/xr/compose/material3/material3/src/main/res/values-da/strings.xml b/xr/compose/material3/material3/src/main/res/values-da/strings.xml
deleted file mode 100644
index 697e333..0000000
--- a/xr/compose/material3/material3/src/main/res/values-da/strings.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-  Copyright 2025 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.
-   -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="xr_compose_material3_space_mode_switch_collapse" msgid="2304391857258488376">"Skjul i HomeSpace-tilstand"</string>
-    <string name="xr_compose_material3_space_mode_switch_expand" msgid="2967869985415673240">"Udvid i FullSpace-tilstand"</string>
-</resources>
diff --git a/xr/compose/material3/material3/src/main/res/values-de/strings.xml b/xr/compose/material3/material3/src/main/res/values-de/strings.xml
deleted file mode 100644
index bcf731b..0000000
--- a/xr/compose/material3/material3/src/main/res/values-de/strings.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-  Copyright 2025 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.
-   -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="xr_compose_material3_space_mode_switch_collapse" msgid="2304391857258488376">"In den HomeSpaceMode wechseln"</string>
-    <string name="xr_compose_material3_space_mode_switch_expand" msgid="2967869985415673240">"In den FullSpaceMode wechseln"</string>
-</resources>
diff --git a/xr/compose/material3/material3/src/main/res/values-el/strings.xml b/xr/compose/material3/material3/src/main/res/values-el/strings.xml
deleted file mode 100644
index 1928617..0000000
--- a/xr/compose/material3/material3/src/main/res/values-el/strings.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-  Copyright 2025 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.
-   -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="xr_compose_material3_space_mode_switch_collapse" msgid="2304391857258488376">"Σύμπτυξη σε HomeSpaceMode"</string>
-    <string name="xr_compose_material3_space_mode_switch_expand" msgid="2967869985415673240">"Ανάπτυξη σε FullSpaceMode"</string>
-</resources>
diff --git a/xr/compose/material3/material3/src/main/res/values-en-rAU/strings.xml b/xr/compose/material3/material3/src/main/res/values-en-rAU/strings.xml
deleted file mode 100644
index 63495e3..0000000
--- a/xr/compose/material3/material3/src/main/res/values-en-rAU/strings.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-  Copyright 2025 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.
-   -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="xr_compose_material3_space_mode_switch_collapse" msgid="2304391857258488376">"Collapse into HomeSpaceMode"</string>
-    <string name="xr_compose_material3_space_mode_switch_expand" msgid="2967869985415673240">"Expand into FullSpaceMode"</string>
-</resources>
diff --git a/xr/compose/material3/material3/src/main/res/values-en-rCA/strings.xml b/xr/compose/material3/material3/src/main/res/values-en-rCA/strings.xml
index 63495e3..a25316d4 100644
--- a/xr/compose/material3/material3/src/main/res/values-en-rCA/strings.xml
+++ b/xr/compose/material3/material3/src/main/res/values-en-rCA/strings.xml
@@ -17,6 +17,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="xr_compose_material3_space_mode_switch_collapse" msgid="2304391857258488376">"Collapse into HomeSpaceMode"</string>
-    <string name="xr_compose_material3_space_mode_switch_expand" msgid="2967869985415673240">"Expand into FullSpaceMode"</string>
+    <string name="xr_compose_material3_space_mode_switch_collapse" msgid="5797879265427018835">"Collapse into "<notranslate>"Home Space"</notranslate></string>
+    <string name="xr_compose_material3_space_mode_switch_expand" msgid="4666431554142220795">"Expand into "<notranslate>"Full Space"</notranslate></string>
 </resources>
diff --git a/xr/compose/material3/material3/src/main/res/values-en-rGB/strings.xml b/xr/compose/material3/material3/src/main/res/values-en-rGB/strings.xml
deleted file mode 100644
index 63495e3..0000000
--- a/xr/compose/material3/material3/src/main/res/values-en-rGB/strings.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-  Copyright 2025 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.
-   -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="xr_compose_material3_space_mode_switch_collapse" msgid="2304391857258488376">"Collapse into HomeSpaceMode"</string>
-    <string name="xr_compose_material3_space_mode_switch_expand" msgid="2967869985415673240">"Expand into FullSpaceMode"</string>
-</resources>
diff --git a/xr/compose/material3/material3/src/main/res/values-en-rIN/strings.xml b/xr/compose/material3/material3/src/main/res/values-en-rIN/strings.xml
deleted file mode 100644
index 63495e3..0000000
--- a/xr/compose/material3/material3/src/main/res/values-en-rIN/strings.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-  Copyright 2025 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.
-   -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="xr_compose_material3_space_mode_switch_collapse" msgid="2304391857258488376">"Collapse into HomeSpaceMode"</string>
-    <string name="xr_compose_material3_space_mode_switch_expand" msgid="2967869985415673240">"Expand into FullSpaceMode"</string>
-</resources>
diff --git a/xr/compose/material3/material3/src/main/res/values-es-rUS/strings.xml b/xr/compose/material3/material3/src/main/res/values-es-rUS/strings.xml
deleted file mode 100644
index 4189380..0000000
--- a/xr/compose/material3/material3/src/main/res/values-es-rUS/strings.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-  Copyright 2025 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.
-   -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="xr_compose_material3_space_mode_switch_collapse" msgid="2304391857258488376">"Contraer en el modo de espacio principal"</string>
-    <string name="xr_compose_material3_space_mode_switch_expand" msgid="2967869985415673240">"Expandir al modo de espacio completo"</string>
-</resources>
diff --git a/xr/compose/material3/material3/src/main/res/values-es/strings.xml b/xr/compose/material3/material3/src/main/res/values-es/strings.xml
deleted file mode 100644
index e743646..0000000
--- a/xr/compose/material3/material3/src/main/res/values-es/strings.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-  Copyright 2025 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.
-   -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="xr_compose_material3_space_mode_switch_collapse" msgid="2304391857258488376">"Contraer al modo Espacio de inicio"</string>
-    <string name="xr_compose_material3_space_mode_switch_expand" msgid="2967869985415673240">"Ampliar al modo Espacio completo"</string>
-</resources>
diff --git a/xr/compose/material3/material3/src/main/res/values-et/strings.xml b/xr/compose/material3/material3/src/main/res/values-et/strings.xml
deleted file mode 100644
index 7b2e4ba..0000000
--- a/xr/compose/material3/material3/src/main/res/values-et/strings.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-  Copyright 2025 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.
-   -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="xr_compose_material3_space_mode_switch_collapse" msgid="2304391857258488376">"Ahenda režiimiks HomeSpaceMode"</string>
-    <string name="xr_compose_material3_space_mode_switch_expand" msgid="2967869985415673240">"Laienda režiimiks FullSpaceMode"</string>
-</resources>
diff --git a/xr/compose/material3/material3/src/main/res/values-eu/strings.xml b/xr/compose/material3/material3/src/main/res/values-eu/strings.xml
deleted file mode 100644
index c3ce041..0000000
--- a/xr/compose/material3/material3/src/main/res/values-eu/strings.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-  Copyright 2025 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.
-   -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="xr_compose_material3_space_mode_switch_collapse" msgid="2304391857258488376">"Tolestu HomeSpaceMode-ra"</string>
-    <string name="xr_compose_material3_space_mode_switch_expand" msgid="2967869985415673240">"Zabaldu FullSpaceMode-ra"</string>
-</resources>
diff --git a/xr/compose/material3/material3/src/main/res/values-fa/strings.xml b/xr/compose/material3/material3/src/main/res/values-fa/strings.xml
deleted file mode 100644
index a599f68..0000000
--- a/xr/compose/material3/material3/src/main/res/values-fa/strings.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-  Copyright 2025 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.
-   -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="xr_compose_material3_space_mode_switch_collapse" msgid="2304391857258488376">"‏جمع کردن در HomeSpaceMode"</string>
-    <string name="xr_compose_material3_space_mode_switch_expand" msgid="2967869985415673240">"‏ازهم باز کردن در FullSpaceMode"</string>
-</resources>
diff --git a/xr/compose/material3/material3/src/main/res/values-fi/strings.xml b/xr/compose/material3/material3/src/main/res/values-fi/strings.xml
deleted file mode 100644
index d613751..0000000
--- a/xr/compose/material3/material3/src/main/res/values-fi/strings.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-  Copyright 2025 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.
-   -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="xr_compose_material3_space_mode_switch_collapse" msgid="2304391857258488376">"Tiivistä: HomeSpaceMode"</string>
-    <string name="xr_compose_material3_space_mode_switch_expand" msgid="2967869985415673240">"Laajenna: FullSpaceMode"</string>
-</resources>
diff --git a/xr/compose/material3/material3/src/main/res/values-fr-rCA/strings.xml b/xr/compose/material3/material3/src/main/res/values-fr-rCA/strings.xml
deleted file mode 100644
index 07410d4..0000000
--- a/xr/compose/material3/material3/src/main/res/values-fr-rCA/strings.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-  Copyright 2025 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.
-   -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="xr_compose_material3_space_mode_switch_collapse" msgid="2304391857258488376">"Réduire en mode Affichage restreint"</string>
-    <string name="xr_compose_material3_space_mode_switch_expand" msgid="2967869985415673240">"Développer en mode Affichage complet"</string>
-</resources>
diff --git a/xr/compose/material3/material3/src/main/res/values-fr/strings.xml b/xr/compose/material3/material3/src/main/res/values-fr/strings.xml
deleted file mode 100644
index a3760e0..0000000
--- a/xr/compose/material3/material3/src/main/res/values-fr/strings.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-  Copyright 2025 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.
-   -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="xr_compose_material3_space_mode_switch_collapse" msgid="2304391857258488376">"Réduire en mode d\'affichage restreint"</string>
-    <string name="xr_compose_material3_space_mode_switch_expand" msgid="2967869985415673240">"Développer en mode d\'affichage complet"</string>
-</resources>
diff --git a/xr/compose/material3/material3/src/main/res/values-gl/strings.xml b/xr/compose/material3/material3/src/main/res/values-gl/strings.xml
deleted file mode 100644
index 692771c..0000000
--- a/xr/compose/material3/material3/src/main/res/values-gl/strings.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-  Copyright 2025 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.
-   -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="xr_compose_material3_space_mode_switch_collapse" msgid="2304391857258488376">"Contraer no modo Espazo de inicio"</string>
-    <string name="xr_compose_material3_space_mode_switch_expand" msgid="2967869985415673240">"Despregar no modo Espazo completo"</string>
-</resources>
diff --git a/xr/compose/material3/material3/src/main/res/values-gu/strings.xml b/xr/compose/material3/material3/src/main/res/values-gu/strings.xml
deleted file mode 100644
index 0fdc391..0000000
--- a/xr/compose/material3/material3/src/main/res/values-gu/strings.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-  Copyright 2025 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.
-   -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="xr_compose_material3_space_mode_switch_collapse" msgid="2304391857258488376">"નાનું કરીને HomeSpaceMode કરો"</string>
-    <string name="xr_compose_material3_space_mode_switch_expand" msgid="2967869985415673240">"મોટું કરીને FullSpaceMode કરો"</string>
-</resources>
diff --git a/xr/compose/material3/material3/src/main/res/values-hi/strings.xml b/xr/compose/material3/material3/src/main/res/values-hi/strings.xml
deleted file mode 100644
index 0ac7fe3..0000000
--- a/xr/compose/material3/material3/src/main/res/values-hi/strings.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-  Copyright 2025 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.
-   -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="xr_compose_material3_space_mode_switch_collapse" msgid="2304391857258488376">"HomeSpaceMode में छोटा करें"</string>
-    <string name="xr_compose_material3_space_mode_switch_expand" msgid="2967869985415673240">"FullSpaceMode में बड़ा करें"</string>
-</resources>
diff --git a/xr/compose/material3/material3/src/main/res/values-hr/strings.xml b/xr/compose/material3/material3/src/main/res/values-hr/strings.xml
deleted file mode 100644
index 159fea1..0000000
--- a/xr/compose/material3/material3/src/main/res/values-hr/strings.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-  Copyright 2025 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.
-   -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="xr_compose_material3_space_mode_switch_collapse" msgid="2304391857258488376">"Sažmi u HomeSpaceMode"</string>
-    <string name="xr_compose_material3_space_mode_switch_expand" msgid="2967869985415673240">"Proširi u FullSpaceMode"</string>
-</resources>
diff --git a/xr/compose/material3/material3/src/main/res/values-hu/strings.xml b/xr/compose/material3/material3/src/main/res/values-hu/strings.xml
deleted file mode 100644
index d7974dc..0000000
--- a/xr/compose/material3/material3/src/main/res/values-hu/strings.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-  Copyright 2025 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.
-   -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="xr_compose_material3_space_mode_switch_collapse" msgid="2304391857258488376">"Összecsukás Home Space módba"</string>
-    <string name="xr_compose_material3_space_mode_switch_expand" msgid="2967869985415673240">"Kibontás Full Space módba"</string>
-</resources>
diff --git a/xr/compose/material3/material3/src/main/res/values-hy/strings.xml b/xr/compose/material3/material3/src/main/res/values-hy/strings.xml
deleted file mode 100644
index 04c4e36..0000000
--- a/xr/compose/material3/material3/src/main/res/values-hy/strings.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-  Copyright 2025 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.
-   -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="xr_compose_material3_space_mode_switch_collapse" msgid="2304391857258488376">"Ծալել հիմնական էկրանի ռեժիմում"</string>
-    <string name="xr_compose_material3_space_mode_switch_expand" msgid="2967869985415673240">"Ծավալել լիաէկրան ռեժիմում"</string>
-</resources>
diff --git a/xr/compose/material3/material3/src/main/res/values-in/strings.xml b/xr/compose/material3/material3/src/main/res/values-in/strings.xml
deleted file mode 100644
index 948c837..0000000
--- a/xr/compose/material3/material3/src/main/res/values-in/strings.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-  Copyright 2025 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.
-   -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="xr_compose_material3_space_mode_switch_collapse" msgid="2304391857258488376">"Ciutkan ke HomeSpaceMode"</string>
-    <string name="xr_compose_material3_space_mode_switch_expand" msgid="2967869985415673240">"Luaskan ke FullSpaceMode"</string>
-</resources>
diff --git a/xr/compose/material3/material3/src/main/res/values-is/strings.xml b/xr/compose/material3/material3/src/main/res/values-is/strings.xml
deleted file mode 100644
index c658577..0000000
--- a/xr/compose/material3/material3/src/main/res/values-is/strings.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-  Copyright 2025 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.
-   -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="xr_compose_material3_space_mode_switch_collapse" msgid="2304391857258488376">"Minnka í HomeSpaceMode"</string>
-    <string name="xr_compose_material3_space_mode_switch_expand" msgid="2967869985415673240">"Stækka í FullSpaceMode"</string>
-</resources>
diff --git a/xr/compose/material3/material3/src/main/res/values-it/strings.xml b/xr/compose/material3/material3/src/main/res/values-it/strings.xml
deleted file mode 100644
index 15868d3..0000000
--- a/xr/compose/material3/material3/src/main/res/values-it/strings.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-  Copyright 2025 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.
-   -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="xr_compose_material3_space_mode_switch_collapse" msgid="2304391857258488376">"Comprimi in modalità Spazio Home"</string>
-    <string name="xr_compose_material3_space_mode_switch_expand" msgid="2967869985415673240">"Espandi in modalità Spazio intero"</string>
-</resources>
diff --git a/xr/compose/material3/material3/src/main/res/values-iw/strings.xml b/xr/compose/material3/material3/src/main/res/values-iw/strings.xml
deleted file mode 100644
index cfd3c19..0000000
--- a/xr/compose/material3/material3/src/main/res/values-iw/strings.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-  Copyright 2025 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.
-   -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="xr_compose_material3_space_mode_switch_collapse" msgid="2304391857258488376">"‏כיווץ למצב HomeSpaceMode"</string>
-    <string name="xr_compose_material3_space_mode_switch_expand" msgid="2967869985415673240">"‏הרחבה למצב FullSpaceMode"</string>
-</resources>
diff --git a/xr/compose/material3/material3/src/main/res/values-ja/strings.xml b/xr/compose/material3/material3/src/main/res/values-ja/strings.xml
deleted file mode 100644
index ef52649..0000000
--- a/xr/compose/material3/material3/src/main/res/values-ja/strings.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-  Copyright 2025 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.
-   -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="xr_compose_material3_space_mode_switch_collapse" msgid="2304391857258488376">"閉じて HomeSpaceMode にする"</string>
-    <string name="xr_compose_material3_space_mode_switch_expand" msgid="2967869985415673240">"開いて FullSpaceMode にする"</string>
-</resources>
diff --git a/xr/compose/material3/material3/src/main/res/values-ka/strings.xml b/xr/compose/material3/material3/src/main/res/values-ka/strings.xml
deleted file mode 100644
index c563f74..0000000
--- a/xr/compose/material3/material3/src/main/res/values-ka/strings.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-  Copyright 2025 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.
-   -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="xr_compose_material3_space_mode_switch_collapse" msgid="2304391857258488376">"სახლის სივრცის რეჟიმზე ჩაკეცვა"</string>
-    <string name="xr_compose_material3_space_mode_switch_expand" msgid="2967869985415673240">"სრული სივრცის რეჟიმზე გაფართოება"</string>
-</resources>
diff --git a/xr/compose/material3/material3/src/main/res/values-kk/strings.xml b/xr/compose/material3/material3/src/main/res/values-kk/strings.xml
deleted file mode 100644
index 5733f2b..0000000
--- a/xr/compose/material3/material3/src/main/res/values-kk/strings.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-  Copyright 2025 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.
-   -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="xr_compose_material3_space_mode_switch_collapse" msgid="2304391857258488376">"Жию (HomeSpaceMode)"</string>
-    <string name="xr_compose_material3_space_mode_switch_expand" msgid="2967869985415673240">"Жаю (FullSpaceMode)"</string>
-</resources>
diff --git a/xr/compose/material3/material3/src/main/res/values-km/strings.xml b/xr/compose/material3/material3/src/main/res/values-km/strings.xml
deleted file mode 100644
index 12e69c7..0000000
--- a/xr/compose/material3/material3/src/main/res/values-km/strings.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-  Copyright 2025 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.
-   -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="xr_compose_material3_space_mode_switch_collapse" msgid="2304391857258488376">"បង្រួមទៅជា HomeSpaceMode"</string>
-    <string name="xr_compose_material3_space_mode_switch_expand" msgid="2967869985415673240">"ពង្រីកទៅជា FullSpaceMode"</string>
-</resources>
diff --git a/xr/compose/material3/material3/src/main/res/values-kn/strings.xml b/xr/compose/material3/material3/src/main/res/values-kn/strings.xml
deleted file mode 100644
index 484ae742..0000000
--- a/xr/compose/material3/material3/src/main/res/values-kn/strings.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-  Copyright 2025 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.
-   -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="xr_compose_material3_space_mode_switch_collapse" msgid="2304391857258488376">"HomeSpaceMode ಗೆ ಕುಗ್ಗಿಸಿ"</string>
-    <string name="xr_compose_material3_space_mode_switch_expand" msgid="2967869985415673240">"FullSpaceMode ಗೆ ವಿಸ್ತರಿಸಿ"</string>
-</resources>
diff --git a/xr/compose/material3/material3/src/main/res/values-ko/strings.xml b/xr/compose/material3/material3/src/main/res/values-ko/strings.xml
deleted file mode 100644
index 1bef611..0000000
--- a/xr/compose/material3/material3/src/main/res/values-ko/strings.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-  Copyright 2025 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.
-   -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="xr_compose_material3_space_mode_switch_collapse" msgid="2304391857258488376">"홈 공간 모드로 접기"</string>
-    <string name="xr_compose_material3_space_mode_switch_expand" msgid="2967869985415673240">"전체 공간 모드로 확장"</string>
-</resources>
diff --git a/xr/compose/material3/material3/src/main/res/values-ky/strings.xml b/xr/compose/material3/material3/src/main/res/values-ky/strings.xml
deleted file mode 100644
index b41247e..0000000
--- a/xr/compose/material3/material3/src/main/res/values-ky/strings.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-  Copyright 2025 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.
-   -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="xr_compose_material3_space_mode_switch_collapse" msgid="2304391857258488376">"HomeSpaceMode режимине жыйыштыруу"</string>
-    <string name="xr_compose_material3_space_mode_switch_expand" msgid="2967869985415673240">"FullSpaceMode режимине жайып көрсөтүү"</string>
-</resources>
diff --git a/xr/compose/material3/material3/src/main/res/values-lo/strings.xml b/xr/compose/material3/material3/src/main/res/values-lo/strings.xml
deleted file mode 100644
index 8233782..0000000
--- a/xr/compose/material3/material3/src/main/res/values-lo/strings.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-  Copyright 2025 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.
-   -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="xr_compose_material3_space_mode_switch_collapse" msgid="2304391857258488376">"ຫຍໍ້ລົງເປັນ HomeSpaceMode"</string>
-    <string name="xr_compose_material3_space_mode_switch_expand" msgid="2967869985415673240">"ຂະຫຍາຍເປັນ FullSpaceMode"</string>
-</resources>
diff --git a/xr/compose/material3/material3/src/main/res/values-lt/strings.xml b/xr/compose/material3/material3/src/main/res/values-lt/strings.xml
deleted file mode 100644
index 6d4e940..0000000
--- a/xr/compose/material3/material3/src/main/res/values-lt/strings.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-  Copyright 2025 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.
-   -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="xr_compose_material3_space_mode_switch_collapse" msgid="2304391857258488376">"Sutraukti į „HomeSpaceMode“"</string>
-    <string name="xr_compose_material3_space_mode_switch_expand" msgid="2967869985415673240">"Išskleisti į „FullSpaceMode“"</string>
-</resources>
diff --git a/xr/compose/material3/material3/src/main/res/values-lv/strings.xml b/xr/compose/material3/material3/src/main/res/values-lv/strings.xml
deleted file mode 100644
index 4d431e2..0000000
--- a/xr/compose/material3/material3/src/main/res/values-lv/strings.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-  Copyright 2025 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.
-   -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="xr_compose_material3_space_mode_switch_collapse" msgid="2304391857258488376">"Sakļaut vairāku lietotņu skata režīmā"</string>
-    <string name="xr_compose_material3_space_mode_switch_expand" msgid="2967869985415673240">"Izvērst vienas lietotnes skata režīmā"</string>
-</resources>
diff --git a/xr/compose/material3/material3/src/main/res/values-mk/strings.xml b/xr/compose/material3/material3/src/main/res/values-mk/strings.xml
deleted file mode 100644
index 5c4fdc4..0000000
--- a/xr/compose/material3/material3/src/main/res/values-mk/strings.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-  Copyright 2025 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.
-   -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="xr_compose_material3_space_mode_switch_collapse" msgid="2304391857258488376">"Собери во HomeSpaceMode"</string>
-    <string name="xr_compose_material3_space_mode_switch_expand" msgid="2967869985415673240">"Прошири во FullSpaceMode"</string>
-</resources>
diff --git a/xr/compose/material3/material3/src/main/res/values-ml/strings.xml b/xr/compose/material3/material3/src/main/res/values-ml/strings.xml
deleted file mode 100644
index 4f5a661..0000000
--- a/xr/compose/material3/material3/src/main/res/values-ml/strings.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-  Copyright 2025 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.
-   -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="xr_compose_material3_space_mode_switch_collapse" msgid="2304391857258488376">"HomeSpaceMode-ലേക്ക് ചുരുക്കുക"</string>
-    <string name="xr_compose_material3_space_mode_switch_expand" msgid="2967869985415673240">"FullSpaceMode-ലേക്ക് വികസിപ്പിക്കുക"</string>
-</resources>
diff --git a/xr/compose/material3/material3/src/main/res/values-mn/strings.xml b/xr/compose/material3/material3/src/main/res/values-mn/strings.xml
deleted file mode 100644
index 7630ed2..0000000
--- a/xr/compose/material3/material3/src/main/res/values-mn/strings.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-  Copyright 2025 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.
-   -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="xr_compose_material3_space_mode_switch_collapse" msgid="2304391857258488376">"HomeSpaceMode болгож хураах"</string>
-    <string name="xr_compose_material3_space_mode_switch_expand" msgid="2967869985415673240">"FullSpaceMode болгож дэлгэх"</string>
-</resources>
diff --git a/xr/compose/material3/material3/src/main/res/values-mr/strings.xml b/xr/compose/material3/material3/src/main/res/values-mr/strings.xml
deleted file mode 100644
index 1c9cbd8..0000000
--- a/xr/compose/material3/material3/src/main/res/values-mr/strings.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-  Copyright 2025 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.
-   -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="xr_compose_material3_space_mode_switch_collapse" msgid="2304391857258488376">"HomeSpaceMode मध्ये कोलॅप्स करा"</string>
-    <string name="xr_compose_material3_space_mode_switch_expand" msgid="2967869985415673240">"FullSpaceMode मध्ये विस्तार करा"</string>
-</resources>
diff --git a/xr/compose/material3/material3/src/main/res/values-ms/strings.xml b/xr/compose/material3/material3/src/main/res/values-ms/strings.xml
deleted file mode 100644
index 69f1fa6..0000000
--- a/xr/compose/material3/material3/src/main/res/values-ms/strings.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-  Copyright 2025 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.
-   -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="xr_compose_material3_space_mode_switch_collapse" msgid="2304391857258488376">"Kuncupkan kepada HomeSpaceMode"</string>
-    <string name="xr_compose_material3_space_mode_switch_expand" msgid="2967869985415673240">"Kembangkan kepada FullSpaceMode"</string>
-</resources>
diff --git a/xr/compose/material3/material3/src/main/res/values-my/strings.xml b/xr/compose/material3/material3/src/main/res/values-my/strings.xml
deleted file mode 100644
index 219c0bb..0000000
--- a/xr/compose/material3/material3/src/main/res/values-my/strings.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-  Copyright 2025 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.
-   -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="xr_compose_material3_space_mode_switch_collapse" msgid="2304391857258488376">"HomeSpaceMode သို့ လျှော့ပြပါ"</string>
-    <string name="xr_compose_material3_space_mode_switch_expand" msgid="2967869985415673240">"FullSpaceMode သို့ ပိုပြပါ"</string>
-</resources>
diff --git a/xr/compose/material3/material3/src/main/res/values-nb/strings.xml b/xr/compose/material3/material3/src/main/res/values-nb/strings.xml
deleted file mode 100644
index 4024874..0000000
--- a/xr/compose/material3/material3/src/main/res/values-nb/strings.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-  Copyright 2025 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.
-   -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="xr_compose_material3_space_mode_switch_collapse" msgid="2304391857258488376">"Legg sammen til HomeSpaceMode"</string>
-    <string name="xr_compose_material3_space_mode_switch_expand" msgid="2967869985415673240">"Utvid til FullSpaceMode"</string>
-</resources>
diff --git a/xr/compose/material3/material3/src/main/res/values-nl/strings.xml b/xr/compose/material3/material3/src/main/res/values-nl/strings.xml
deleted file mode 100644
index 39d8278..0000000
--- a/xr/compose/material3/material3/src/main/res/values-nl/strings.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-  Copyright 2025 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.
-   -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="xr_compose_material3_space_mode_switch_collapse" msgid="2304391857258488376">"Samenvouwen in HomeSpaceMode"</string>
-    <string name="xr_compose_material3_space_mode_switch_expand" msgid="2967869985415673240">"Uitvouwen in FullSpaceMode"</string>
-</resources>
diff --git a/xr/compose/material3/material3/src/main/res/values-or/strings.xml b/xr/compose/material3/material3/src/main/res/values-or/strings.xml
deleted file mode 100644
index 2034b43..0000000
--- a/xr/compose/material3/material3/src/main/res/values-or/strings.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-  Copyright 2025 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.
-   -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="xr_compose_material3_space_mode_switch_collapse" msgid="2304391857258488376">"HomeSpaceModeକୁ ସଙ୍କୁଚିତ କରନ୍ତୁ"</string>
-    <string name="xr_compose_material3_space_mode_switch_expand" msgid="2967869985415673240">"FullSpaceModeକୁ ବିସ୍ତାର କରନ୍ତୁ"</string>
-</resources>
diff --git a/xr/compose/material3/material3/src/main/res/values-pa/strings.xml b/xr/compose/material3/material3/src/main/res/values-pa/strings.xml
deleted file mode 100644
index 2c7c3b7..0000000
--- a/xr/compose/material3/material3/src/main/res/values-pa/strings.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-  Copyright 2025 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.
-   -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="xr_compose_material3_space_mode_switch_collapse" msgid="2304391857258488376">"HomeSpaceMode ਵਿੱਚ ਸਮੇਟੋ"</string>
-    <string name="xr_compose_material3_space_mode_switch_expand" msgid="2967869985415673240">"FullSpaceMode ਵਿੱਚ ਵਿਸਤਾਰ ਕਰੋ"</string>
-</resources>
diff --git a/xr/compose/material3/material3/src/main/res/values-pl/strings.xml b/xr/compose/material3/material3/src/main/res/values-pl/strings.xml
deleted file mode 100644
index 61437db..0000000
--- a/xr/compose/material3/material3/src/main/res/values-pl/strings.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-  Copyright 2025 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.
-   -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="xr_compose_material3_space_mode_switch_collapse" msgid="2304391857258488376">"Zwiń do trybu przestrzeni domowej"</string>
-    <string name="xr_compose_material3_space_mode_switch_expand" msgid="2967869985415673240">"Rozwiń do trybu pełnej przestrzeni"</string>
-</resources>
diff --git a/xr/compose/material3/material3/src/main/res/values-pt-rBR/strings.xml b/xr/compose/material3/material3/src/main/res/values-pt-rBR/strings.xml
deleted file mode 100644
index b067c38..0000000
--- a/xr/compose/material3/material3/src/main/res/values-pt-rBR/strings.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-  Copyright 2025 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.
-   -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="xr_compose_material3_space_mode_switch_collapse" msgid="2304391857258488376">"Recolher para o Modo de Espaço Compacto"</string>
-    <string name="xr_compose_material3_space_mode_switch_expand" msgid="2967869985415673240">"Abrir no Modo de Espaço Ampliado"</string>
-</resources>
diff --git a/xr/compose/material3/material3/src/main/res/values-pt-rPT/strings.xml b/xr/compose/material3/material3/src/main/res/values-pt-rPT/strings.xml
deleted file mode 100644
index e93b21d..0000000
--- a/xr/compose/material3/material3/src/main/res/values-pt-rPT/strings.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-  Copyright 2025 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.
-   -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="xr_compose_material3_space_mode_switch_collapse" msgid="2304391857258488376">"Reduzir para HomeSpaceMode"</string>
-    <string name="xr_compose_material3_space_mode_switch_expand" msgid="2967869985415673240">"Expandir para FullSpaceMode"</string>
-</resources>
diff --git a/xr/compose/material3/material3/src/main/res/values-pt/strings.xml b/xr/compose/material3/material3/src/main/res/values-pt/strings.xml
deleted file mode 100644
index b067c38..0000000
--- a/xr/compose/material3/material3/src/main/res/values-pt/strings.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-  Copyright 2025 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.
-   -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="xr_compose_material3_space_mode_switch_collapse" msgid="2304391857258488376">"Recolher para o Modo de Espaço Compacto"</string>
-    <string name="xr_compose_material3_space_mode_switch_expand" msgid="2967869985415673240">"Abrir no Modo de Espaço Ampliado"</string>
-</resources>
diff --git a/xr/compose/material3/material3/src/main/res/values-ro/strings.xml b/xr/compose/material3/material3/src/main/res/values-ro/strings.xml
deleted file mode 100644
index 927003a..0000000
--- a/xr/compose/material3/material3/src/main/res/values-ro/strings.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-  Copyright 2025 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.
-   -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="xr_compose_material3_space_mode_switch_collapse" msgid="2304391857258488376">"Restrânge în modul spațiu de pornire"</string>
-    <string name="xr_compose_material3_space_mode_switch_expand" msgid="2967869985415673240">"Extinde în modul spațiu complet"</string>
-</resources>
diff --git a/xr/compose/material3/material3/src/main/res/values-ru/strings.xml b/xr/compose/material3/material3/src/main/res/values-ru/strings.xml
deleted file mode 100644
index a8a3a2b..0000000
--- a/xr/compose/material3/material3/src/main/res/values-ru/strings.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-  Copyright 2025 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.
-   -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="xr_compose_material3_space_mode_switch_collapse" msgid="2304391857258488376">"Свернуть в стандартный режим"</string>
-    <string name="xr_compose_material3_space_mode_switch_expand" msgid="2967869985415673240">"Развернуть полное пространство"</string>
-</resources>
diff --git a/xr/compose/material3/material3/src/main/res/values-si/strings.xml b/xr/compose/material3/material3/src/main/res/values-si/strings.xml
deleted file mode 100644
index 9b1a9b3..0000000
--- a/xr/compose/material3/material3/src/main/res/values-si/strings.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-  Copyright 2025 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.
-   -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="xr_compose_material3_space_mode_switch_collapse" msgid="2304391857258488376">"HomeSpaceMode වෙත හකුළන්න"</string>
-    <string name="xr_compose_material3_space_mode_switch_expand" msgid="2967869985415673240">"FullSpaceMode වෙත දිගහරින්න"</string>
-</resources>
diff --git a/xr/compose/material3/material3/src/main/res/values-sk/strings.xml b/xr/compose/material3/material3/src/main/res/values-sk/strings.xml
deleted file mode 100644
index c60bc69..0000000
--- a/xr/compose/material3/material3/src/main/res/values-sk/strings.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-  Copyright 2025 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.
-   -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="xr_compose_material3_space_mode_switch_collapse" msgid="2304391857258488376">"Zbaliť do režimu domáceho priestoru"</string>
-    <string name="xr_compose_material3_space_mode_switch_expand" msgid="2967869985415673240">"Rozbaliť do režimu celého priestoru"</string>
-</resources>
diff --git a/xr/compose/material3/material3/src/main/res/values-sl/strings.xml b/xr/compose/material3/material3/src/main/res/values-sl/strings.xml
deleted file mode 100644
index c9ba5fb..0000000
--- a/xr/compose/material3/material3/src/main/res/values-sl/strings.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-  Copyright 2025 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.
-   -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="xr_compose_material3_space_mode_switch_collapse" msgid="2304391857258488376">"Strni v način domačega prostora"</string>
-    <string name="xr_compose_material3_space_mode_switch_expand" msgid="2967869985415673240">"Razširi v način celotnega prostora"</string>
-</resources>
diff --git a/xr/compose/material3/material3/src/main/res/values-sq/strings.xml b/xr/compose/material3/material3/src/main/res/values-sq/strings.xml
deleted file mode 100644
index 206727f..0000000
--- a/xr/compose/material3/material3/src/main/res/values-sq/strings.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-  Copyright 2025 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.
-   -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="xr_compose_material3_space_mode_switch_collapse" msgid="2304391857258488376">"Palos në HomeSpaceMode"</string>
-    <string name="xr_compose_material3_space_mode_switch_expand" msgid="2967869985415673240">"Zgjero në FullSpaceMode"</string>
-</resources>
diff --git a/xr/compose/material3/material3/src/main/res/values-sr/strings.xml b/xr/compose/material3/material3/src/main/res/values-sr/strings.xml
deleted file mode 100644
index ce4e112..0000000
--- a/xr/compose/material3/material3/src/main/res/values-sr/strings.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-  Copyright 2025 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.
-   -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="xr_compose_material3_space_mode_switch_collapse" msgid="2304391857258488376">"Скупи на почетни режим простора"</string>
-    <string name="xr_compose_material3_space_mode_switch_expand" msgid="2967869985415673240">"Прошири на пуни режим простора"</string>
-</resources>
diff --git a/xr/compose/material3/material3/src/main/res/values-sv/strings.xml b/xr/compose/material3/material3/src/main/res/values-sv/strings.xml
deleted file mode 100644
index d0703e4..0000000
--- a/xr/compose/material3/material3/src/main/res/values-sv/strings.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-  Copyright 2025 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.
-   -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="xr_compose_material3_space_mode_switch_collapse" msgid="2304391857258488376">"Komprimera till HomeSpace-läge"</string>
-    <string name="xr_compose_material3_space_mode_switch_expand" msgid="2967869985415673240">"Utöka till FullSpace-läge"</string>
-</resources>
diff --git a/xr/compose/material3/material3/src/main/res/values-sw/strings.xml b/xr/compose/material3/material3/src/main/res/values-sw/strings.xml
deleted file mode 100644
index c5c84e1..0000000
--- a/xr/compose/material3/material3/src/main/res/values-sw/strings.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-  Copyright 2025 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.
-   -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="xr_compose_material3_space_mode_switch_collapse" msgid="2304391857258488376">"Kunja utumie hali ya HomeSpaceMode"</string>
-    <string name="xr_compose_material3_space_mode_switch_expand" msgid="2967869985415673240">"Panua utumie hali ya FullSpaceMode"</string>
-</resources>
diff --git a/xr/compose/material3/material3/src/main/res/values-ta/strings.xml b/xr/compose/material3/material3/src/main/res/values-ta/strings.xml
deleted file mode 100644
index 2283c74..0000000
--- a/xr/compose/material3/material3/src/main/res/values-ta/strings.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-  Copyright 2025 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.
-   -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="xr_compose_material3_space_mode_switch_collapse" msgid="2304391857258488376">"HomeSpaceModeக்குச் சுருக்கும்"</string>
-    <string name="xr_compose_material3_space_mode_switch_expand" msgid="2967869985415673240">"FullSpaceModeக்கு விரிக்கும்"</string>
-</resources>
diff --git a/xr/compose/material3/material3/src/main/res/values-te/strings.xml b/xr/compose/material3/material3/src/main/res/values-te/strings.xml
deleted file mode 100644
index e2581ca..0000000
--- a/xr/compose/material3/material3/src/main/res/values-te/strings.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-  Copyright 2025 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.
-   -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="xr_compose_material3_space_mode_switch_collapse" msgid="2304391857258488376">"HomeSpaceModeకు కుదించండి"</string>
-    <string name="xr_compose_material3_space_mode_switch_expand" msgid="2967869985415673240">"FullSpaceModeకు విస్తరించండి"</string>
-</resources>
diff --git a/xr/compose/material3/material3/src/main/res/values-th/strings.xml b/xr/compose/material3/material3/src/main/res/values-th/strings.xml
deleted file mode 100644
index 3451b43..0000000
--- a/xr/compose/material3/material3/src/main/res/values-th/strings.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-  Copyright 2025 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.
-   -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="xr_compose_material3_space_mode_switch_collapse" msgid="2304391857258488376">"ยุบเป็น HomeSpaceMode"</string>
-    <string name="xr_compose_material3_space_mode_switch_expand" msgid="2967869985415673240">"ขยายเป็น FullSpaceMode"</string>
-</resources>
diff --git a/xr/compose/material3/material3/src/main/res/values-tl/strings.xml b/xr/compose/material3/material3/src/main/res/values-tl/strings.xml
deleted file mode 100644
index fbe636e..0000000
--- a/xr/compose/material3/material3/src/main/res/values-tl/strings.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-  Copyright 2025 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.
-   -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="xr_compose_material3_space_mode_switch_collapse" msgid="2304391857258488376">"I-collapse sa HomeSpaceMode"</string>
-    <string name="xr_compose_material3_space_mode_switch_expand" msgid="2967869985415673240">"I-expand sa FullSpaceMode"</string>
-</resources>
diff --git a/xr/compose/material3/material3/src/main/res/values-tr/strings.xml b/xr/compose/material3/material3/src/main/res/values-tr/strings.xml
deleted file mode 100644
index 18c44c7..0000000
--- a/xr/compose/material3/material3/src/main/res/values-tr/strings.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-  Copyright 2025 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.
-   -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="xr_compose_material3_space_mode_switch_collapse" msgid="2304391857258488376">"HomeSpaceMode\'a daralt"</string>
-    <string name="xr_compose_material3_space_mode_switch_expand" msgid="2967869985415673240">"FullSpaceMode\'a genişlet"</string>
-</resources>
diff --git a/xr/compose/material3/material3/src/main/res/values-uk/strings.xml b/xr/compose/material3/material3/src/main/res/values-uk/strings.xml
deleted file mode 100644
index 4dbeb26..0000000
--- a/xr/compose/material3/material3/src/main/res/values-uk/strings.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-  Copyright 2025 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.
-   -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="xr_compose_material3_space_mode_switch_collapse" msgid="2304391857258488376">"Згорнути в режим закритого простору"</string>
-    <string name="xr_compose_material3_space_mode_switch_expand" msgid="2967869985415673240">"Розгорнути в режим відкритого простору"</string>
-</resources>
diff --git a/xr/compose/material3/material3/src/main/res/values-ur/strings.xml b/xr/compose/material3/material3/src/main/res/values-ur/strings.xml
deleted file mode 100644
index bec50ab..0000000
--- a/xr/compose/material3/material3/src/main/res/values-ur/strings.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-  Copyright 2025 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.
-   -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="xr_compose_material3_space_mode_switch_collapse" msgid="2304391857258488376">"‏‫HomeSpaceMode میں سکیڑیں"</string>
-    <string name="xr_compose_material3_space_mode_switch_expand" msgid="2967869985415673240">"‏‫FullSpaceMode میں پھیلائیں"</string>
-</resources>
diff --git a/xr/compose/material3/material3/src/main/res/values-uz/strings.xml b/xr/compose/material3/material3/src/main/res/values-uz/strings.xml
deleted file mode 100644
index 1b94c1d..0000000
--- a/xr/compose/material3/material3/src/main/res/values-uz/strings.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-  Copyright 2025 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.
-   -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="xr_compose_material3_space_mode_switch_collapse" msgid="2304391857258488376">"HomeSpaceMode rejimiga yigʻish"</string>
-    <string name="xr_compose_material3_space_mode_switch_expand" msgid="2967869985415673240">"FullSpaceMode rejimiga yoyish"</string>
-</resources>
diff --git a/xr/compose/material3/material3/src/main/res/values-vi/strings.xml b/xr/compose/material3/material3/src/main/res/values-vi/strings.xml
deleted file mode 100644
index e986198..0000000
--- a/xr/compose/material3/material3/src/main/res/values-vi/strings.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-  Copyright 2025 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.
-   -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="xr_compose_material3_space_mode_switch_collapse" msgid="2304391857258488376">"Thu gọn thành HomeSpaceMode"</string>
-    <string name="xr_compose_material3_space_mode_switch_expand" msgid="2967869985415673240">"Mở rộng thành FullSpaceMode"</string>
-</resources>
diff --git a/xr/compose/material3/material3/src/main/res/values-zh-rCN/strings.xml b/xr/compose/material3/material3/src/main/res/values-zh-rCN/strings.xml
deleted file mode 100644
index ae797d4..0000000
--- a/xr/compose/material3/material3/src/main/res/values-zh-rCN/strings.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-  Copyright 2025 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.
-   -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="xr_compose_material3_space_mode_switch_collapse" msgid="2304391857258488376">"收起为 HomeSpaceMode"</string>
-    <string name="xr_compose_material3_space_mode_switch_expand" msgid="2967869985415673240">"展开为 FullSpaceMode"</string>
-</resources>
diff --git a/xr/compose/material3/material3/src/main/res/values-zh-rHK/strings.xml b/xr/compose/material3/material3/src/main/res/values-zh-rHK/strings.xml
deleted file mode 100644
index 6a52346..0000000
--- a/xr/compose/material3/material3/src/main/res/values-zh-rHK/strings.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-  Copyright 2025 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.
-   -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="xr_compose_material3_space_mode_switch_collapse" msgid="2304391857258488376">"收合至「首頁空間模式」"</string>
-    <string name="xr_compose_material3_space_mode_switch_expand" msgid="2967869985415673240">"展開至「完整空間模式」"</string>
-</resources>
diff --git a/xr/compose/material3/material3/src/main/res/values-zh-rTW/strings.xml b/xr/compose/material3/material3/src/main/res/values-zh-rTW/strings.xml
deleted file mode 100644
index f944fa2..0000000
--- a/xr/compose/material3/material3/src/main/res/values-zh-rTW/strings.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-  Copyright 2025 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.
-   -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="xr_compose_material3_space_mode_switch_collapse" msgid="2304391857258488376">"收合至 HomeSpaceMode"</string>
-    <string name="xr_compose_material3_space_mode_switch_expand" msgid="2967869985415673240">"展開為 FullSpaceMode"</string>
-</resources>
diff --git a/xr/compose/material3/material3/src/main/res/values-zu/strings.xml b/xr/compose/material3/material3/src/main/res/values-zu/strings.xml
deleted file mode 100644
index 0474433..0000000
--- a/xr/compose/material3/material3/src/main/res/values-zu/strings.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-  Copyright 2025 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.
-   -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="xr_compose_material3_space_mode_switch_collapse" msgid="2304391857258488376">"Kugoqe kube i-HomeSpaceMode"</string>
-    <string name="xr_compose_material3_space_mode_switch_expand" msgid="2967869985415673240">"Kunwebe kube i-FullSpaceMode"</string>
-</resources>
diff --git a/xr/projected/integration-tests/testapp/src/main/AndroidManifest.xml b/xr/projected/integration-tests/testapp/src/main/AndroidManifest.xml
index e6ca2ba..c29bdbd 100644
--- a/xr/projected/integration-tests/testapp/src/main/AndroidManifest.xml
+++ b/xr/projected/integration-tests/testapp/src/main/AndroidManifest.xml
@@ -54,10 +54,16 @@
             android:exported="true"
             android:label="AudioManager Activity">
         </activity>
+        <activity
+            android:name="androidx.xr.projected.testapp.audio.AudioActivity"
+            android:exported="true"
+            android:label="Audio Activity">
+        </activity>
     </application>
 
     <uses-feature android:name="android.hardware.camera" />
-    <uses-permission android:name="android.permission.CAMERA" />
     <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
+    <uses-permission android:name="android.permission.CAMERA" />
+    <uses-permission android:name="android.permission.RECORD_AUDIO" />
 
 </manifest>
diff --git a/xr/projected/integration-tests/testapp/src/main/kotlin/androidx/xr/projected/testapp/MainActivity.kt b/xr/projected/integration-tests/testapp/src/main/kotlin/androidx/xr/projected/testapp/MainActivity.kt
index 9bb965b..cbab10ce 100644
--- a/xr/projected/integration-tests/testapp/src/main/kotlin/androidx/xr/projected/testapp/MainActivity.kt
+++ b/xr/projected/integration-tests/testapp/src/main/kotlin/androidx/xr/projected/testapp/MainActivity.kt
@@ -38,6 +38,7 @@
 import androidx.compose.ui.unit.dp
 import androidx.compose.ui.unit.sp
 import androidx.xr.projected.ProjectedContext
+import androidx.xr.projected.testapp.audio.AudioActivity
 import androidx.xr.projected.testapp.audiomanager.AudioManagerActivity
 import androidx.xr.projected.testapp.componentpermissions.PermissionsComponentActivity
 import androidx.xr.projected.testapp.permissions.PermissionsActivity
@@ -131,6 +132,7 @@
             mapOf(
                 "Projected Context" to ProjectedContextActivity::class.java,
                 "Audio Manager" to AudioManagerActivity::class.java,
+                "Audio" to AudioActivity::class.java,
             )
 
         // A list of projected activities that are launchable from the main activity.
diff --git a/xr/projected/integration-tests/testapp/src/main/kotlin/androidx/xr/projected/testapp/audio/AudioActivity.kt b/xr/projected/integration-tests/testapp/src/main/kotlin/androidx/xr/projected/testapp/audio/AudioActivity.kt
new file mode 100644
index 0000000..1e56e44
--- /dev/null
+++ b/xr/projected/integration-tests/testapp/src/main/kotlin/androidx/xr/projected/testapp/audio/AudioActivity.kt
@@ -0,0 +1,282 @@
+/*
+ * Copyright 2025 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 androidx.xr.projected.testapp.audio
+
+import android.Manifest
+import android.content.Context
+import android.content.pm.PackageManager
+import android.media.AudioAttributes
+import android.media.AudioFormat
+import android.media.AudioRecord
+import android.media.AudioTrack
+import android.media.MediaRecorder
+import android.os.Bundle
+import android.util.Log
+import androidx.activity.ComponentActivity
+import androidx.activity.compose.setContent
+import androidx.annotation.RequiresPermission
+import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.material3.Button
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.LaunchedEffect
+import androidx.compose.runtime.MutableState
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.remember
+import androidx.compose.ui.Modifier
+import androidx.core.app.ActivityCompat
+import androidx.lifecycle.Lifecycle
+import androidx.lifecycle.lifecycleScope
+import androidx.lifecycle.repeatOnLifecycle
+import androidx.xr.projected.ProjectedContext
+import java.io.File
+import java.io.FileInputStream
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.launch
+
+/** The AudioActivity records and plays back audio on a projected device. */
+class AudioActivity : ComponentActivity() {
+    lateinit var audioRecord: AudioRecord
+    lateinit var audioTrack: AudioTrack
+    lateinit var audioBuffer: ByteArray
+    lateinit var connectedFlow: Flow<Boolean>
+    var projectedContext: Context? = null
+    var errorMessage: String = ""
+
+    private enum class RecordState {
+        AWAITING_RECORDING,
+        RECORDING,
+        AWAITING_PLAYBACK,
+        PLAYBACK,
+    }
+
+    @RequiresPermission(Manifest.permission.RECORD_AUDIO)
+    override fun onCreate(savedInstanceState: Bundle?) {
+        Log.i(TAG, "Creating AudioActivity")
+        super.onCreate(savedInstanceState)
+        connectedFlow = ProjectedContext.isProjectedDeviceConnected(this, Dispatchers.Default)
+        setContent { CreateAudioUi() }
+    }
+
+    @Composable
+    private fun CreateAudioUi() {
+        val state = remember { mutableStateOf(RecordState.AWAITING_RECORDING) }
+        val connectedState = remember { mutableStateOf(false) }
+        val audioInitialized = remember { mutableStateOf(false) }
+        UpdateConnectedState(connectedState, audioInitialized)
+        Column(modifier = Modifier.fillMaxSize(), verticalArrangement = Arrangement.Center) {
+            if (!connectedState.value || !audioInitialized.value) {
+                Text(errorMessage)
+                return
+            }
+            Text("State: ${state.value.name}")
+            Button(
+                onClick = {
+                    when (state.value) {
+                        RecordState.AWAITING_RECORDING -> startRecording(state)
+                        RecordState.RECORDING -> stopRecording(state)
+                        RecordState.AWAITING_PLAYBACK -> startPlayback(state)
+                        else -> Log.e(TAG, "Button should be disabled during playback.")
+                    }
+                },
+                enabled = (state.value != RecordState.PLAYBACK),
+            ) {
+                Text(getButtonText(state.value))
+            }
+        }
+    }
+
+    @Composable
+    fun UpdateConnectedState(
+        connectedState: MutableState<Boolean>,
+        audioInitialized: MutableState<Boolean>,
+    ) {
+        LaunchedEffect(Unit) {
+            repeatOnLifecycle(Lifecycle.State.STARTED) {
+                connectedFlow.collect { connected ->
+                    connectedState.value = connected
+                    if (connected) {
+                        createProjectedContext()
+                        projectedContext?.let {
+                            if (
+                                ActivityCompat.checkSelfPermission(
+                                    it,
+                                    Manifest.permission.RECORD_AUDIO,
+                                ) != PackageManager.PERMISSION_GRANTED
+                            ) {
+                                errorMessage = "Record Audio permission is required."
+                                audioInitialized.value = false
+                                return@collect
+                            }
+                            audioInitialized.value = initAudio(it)
+                        }
+                        Log.i(TAG, "Projected device is connected")
+                    } else {
+                        errorMessage = "Projected device is not connected."
+                        audioInitialized.value = false
+                        Log.w(TAG, "Projected device is not connected")
+                    }
+                }
+            }
+        }
+    }
+
+    private fun createProjectedContext() {
+        try {
+            projectedContext = ProjectedContext.createProjectedDeviceContext(this)
+        } catch (e: IllegalStateException) {
+            errorMessage = "Failed to create Projected Context."
+            Log.w(TAG, "Error creating projected context: $e")
+        }
+    }
+
+    private fun getButtonText(state: RecordState): String =
+        when (state) {
+            RecordState.AWAITING_RECORDING -> "Record"
+            RecordState.RECORDING -> "Stop Recording"
+            RecordState.AWAITING_PLAYBACK -> "Play"
+            RecordState.PLAYBACK -> "Playback in Progress"
+        }
+
+    // Initialize the AudioRecord and AudioTrack for recording and playing back audio.
+    @RequiresPermission(Manifest.permission.RECORD_AUDIO)
+    private fun initAudio(context: Context): Boolean {
+        Log.i(TAG, "Initializing AudioRecord and AudioTrack")
+        val audioRecordFormat =
+            AudioFormat.Builder()
+                .setEncoding(AudioFormat.ENCODING_PCM_16BIT)
+                .setChannelMask(AudioFormat.CHANNEL_IN_MONO)
+                .setSampleRate(SAMPLE_RATE)
+                .build()
+        val audioRecordingBufferSize =
+            AudioRecord.getMinBufferSize(
+                SAMPLE_RATE,
+                AudioFormat.CHANNEL_IN_MONO,
+                AudioFormat.ENCODING_PCM_16BIT,
+            )
+        audioBuffer = ByteArray(audioRecordingBufferSize)
+        try {
+            audioRecord =
+                AudioRecord.Builder()
+                    .setAudioSource(MediaRecorder.AudioSource.UNPROCESSED)
+                    .setAudioFormat(audioRecordFormat)
+                    .setBufferSizeInBytes(audioRecordingBufferSize)
+                    .setContext(context)
+                    .build()
+        } catch (e: UnsupportedOperationException) {
+            errorMessage = "Failed to create AudioRecord."
+            Log.e(TAG, "Error creating AudioRecord: $e")
+            return false
+        }
+        val attributes =
+            AudioAttributes.Builder()
+                .setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
+                .setUsage(AudioAttributes.USAGE_MEDIA)
+                .build()
+
+        val audioTrackFormat =
+            AudioFormat.Builder()
+                .setEncoding(AudioFormat.ENCODING_PCM_16BIT)
+                .setChannelMask(AudioFormat.CHANNEL_OUT_MONO)
+                .setSampleRate(SAMPLE_RATE)
+                .build()
+
+        val audioTrackBufferSize =
+            AudioTrack.getMinBufferSize(
+                SAMPLE_RATE,
+                AudioFormat.CHANNEL_OUT_MONO,
+                AudioFormat.ENCODING_PCM_16BIT,
+            )
+        try {
+            audioTrack =
+                AudioTrack.Builder()
+                    .setAudioAttributes(attributes)
+                    .setAudioFormat(audioTrackFormat)
+                    .setBufferSizeInBytes(audioTrackBufferSize)
+                    .setContext(context)
+                    .build()
+        } catch (e: UnsupportedOperationException) {
+            errorMessage = "Failed to create AudioTrack."
+            Log.e(TAG, "Error creating AudioTrack: $e")
+            return false
+        }
+        Log.i(TAG, "Successfully initialized AudioRecord and AudioTrack")
+        return true
+    }
+
+    private fun startRecording(state: MutableState<RecordState>) {
+        Log.i(TAG, "Starting Recording")
+        state.value = RecordState.RECORDING
+        audioRecord.startRecording()
+        val fileStream = this.openFileOutput(AUDIO_FILE_NAME, Context.MODE_PRIVATE)
+
+        lifecycleScope.launch(Dispatchers.IO) {
+            while (state.value == RecordState.RECORDING) {
+                audioRecord.read(audioBuffer, /* offsetInBytes= */ 0, audioBuffer.size)
+                fileStream?.write(audioBuffer)
+            }
+            fileStream?.close()
+        }
+    }
+
+    private fun stopRecording(state: MutableState<RecordState>) {
+        Log.i(TAG, "Stopping Recording")
+        state.value = RecordState.AWAITING_PLAYBACK
+        audioRecord.stop()
+    }
+
+    private fun startPlayback(state: MutableState<RecordState>) {
+        Log.i(TAG, "Starting Playback")
+        state.value = RecordState.PLAYBACK
+        val audioFile = File(this.filesDir, AUDIO_FILE_NAME)
+        val fileStream = FileInputStream(audioFile)
+        val audioData = ByteArray(audioFile.length().toInt())
+        fileStream.read(audioData, /* off= */ 0, audioData.size)
+        fileStream.close()
+        // Add a callback to update the state when audio playback is complete.
+        audioTrack.setPlaybackPositionUpdateListener(
+            object : AudioTrack.OnPlaybackPositionUpdateListener {
+                override fun onMarkerReached(audioTrack: AudioTrack?) {
+                    stopPlayback(state)
+                }
+
+                override fun onPeriodicNotification(track: AudioTrack?) {}
+            }
+        )
+        audioTrack.notificationMarkerPosition = audioData.size / 2
+
+        lifecycleScope.launch(Dispatchers.IO) {
+            audioTrack.play()
+            audioTrack.write(audioData, /* offsetInBytes= */ 0, audioData.size)
+        }
+    }
+
+    private fun stopPlayback(state: MutableState<RecordState>) {
+        Log.i(TAG, "Stopping Playback")
+        state.value = RecordState.AWAITING_RECORDING
+        audioTrack.stop()
+    }
+
+    private companion object {
+        const val SAMPLE_RATE = 16000
+        const val AUDIO_FILE_NAME: String = "audioRecording.wav"
+        const val TAG = "AudioActivity"
+    }
+}
diff --git a/xr/projected/integration-tests/testapp/src/main/kotlin/androidx/xr/projected/testapp/componentpermissions/PermissionsComponentActivity.kt b/xr/projected/integration-tests/testapp/src/main/kotlin/androidx/xr/projected/testapp/componentpermissions/PermissionsComponentActivity.kt
index b1c1b65..f316a8b 100644
--- a/xr/projected/integration-tests/testapp/src/main/kotlin/androidx/xr/projected/testapp/componentpermissions/PermissionsComponentActivity.kt
+++ b/xr/projected/integration-tests/testapp/src/main/kotlin/androidx/xr/projected/testapp/componentpermissions/PermissionsComponentActivity.kt
@@ -48,7 +48,11 @@
         requestPermissionLauncher.launch(
             listOf(
                 ProjectedPermissionsRequestParams(
-                    listOf(Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.CAMERA),
+                    listOf(
+                        Manifest.permission.ACCESS_COARSE_LOCATION,
+                        Manifest.permission.CAMERA,
+                        Manifest.permission.RECORD_AUDIO,
+                    ),
                     "Some good rationale.",
                 )
             )
diff --git a/xr/projected/integration-tests/testapp/src/main/kotlin/androidx/xr/projected/testapp/permissions/PermissionsActivity.kt b/xr/projected/integration-tests/testapp/src/main/kotlin/androidx/xr/projected/testapp/permissions/PermissionsActivity.kt
index ddffc18..f085e80 100644
--- a/xr/projected/integration-tests/testapp/src/main/kotlin/androidx/xr/projected/testapp/permissions/PermissionsActivity.kt
+++ b/xr/projected/integration-tests/testapp/src/main/kotlin/androidx/xr/projected/testapp/permissions/PermissionsActivity.kt
@@ -40,7 +40,11 @@
     private fun requestPermissions() {
         val data =
             ProjectedPermissionsRequestParams(
-                listOf(Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.CAMERA),
+                listOf(
+                    Manifest.permission.ACCESS_COARSE_LOCATION,
+                    Manifest.permission.CAMERA,
+                    Manifest.permission.RECORD_AUDIO,
+                ),
                 "Some good rationale.",
             )
         intent = projectedPermissionsResultContract.createIntent(this, listOf(data))