Merge "Bump versions for ProtoLayout and Tiles" into androidx-main
diff --git a/.github/actions/build-single-project/action.yml b/.github/actions/build-single-project/action.yml
index c3dc9a8..feef143 100644
--- a/.github/actions/build-single-project/action.yml
+++ b/.github/actions/build-single-project/action.yml
@@ -11,6 +11,8 @@
     description: "password for gradle cache"
   gradle-enterprise-access-key:
     description: "access key for gradle enterprise"
+  gradle-encryption-key:
+    description: "key for gradle configuration cache encryption"
   gradle-flags:
     description: "flags to pass while invoking gradle"
 runs:
@@ -39,7 +41,7 @@
         echo "DIST_DIR=$HOME/dist" >> $GITHUB_ENV
 
     - name: "Setup Gradle"
-      uses: gradle/gradle-build-action@v2
+      uses: gradle/gradle-build-action@v3-beta
       with:
         # Only save Gradle User Home state for builds on the 'androidx-main' branch.
         # Builds on other branches will only read existing entries from the cache.
@@ -48,6 +50,8 @@
         # Don't reuse cache entries from any other Job.
         gradle-home-cache-strict-match: true
 
+        cache-encryption-key: ${{ inputs.gradle-encryption-key }}
+
         # Limit the size of the cache entry.
         # These directories contain instrumented/transformed dependency jars which can be reconstructed relatively quickly.
         gradle-home-cache-excludes: |
@@ -59,6 +63,7 @@
         JAVA_HOME: ${{ steps.setup-java.outputs.path }}
         GRADLE_BUILD_CACHE_PASSWORD: ${{ inputs.gradle-cache-password }}
         GRADLE_ENTERPRISE_ACCESS_KEY: ${{ inputs.gradle-enterprise-access-key }}
+        GRADLE_ENCRYPTION_KEY: ${{ inputs.gradle-encryption-key }}
       working-directory: ${{ inputs.project-root }}
       shell: bash
       run: ./gradlew buildOnServer zipTestConfigsWithApks ${{ inputs.gradle-flags }}
@@ -67,6 +72,7 @@
         JAVA_HOME: ${{ steps.setup-java.outputs.path }}
         GRADLE_BUILD_CACHE_PASSWORD: ${{ inputs.gradle-cache-password }}
         GRADLE_ENTERPRISE_ACCESS_KEY: ${{ inputs.gradle-enterprise-access-key }}
+        GRADLE_ENCRYPTION_KEY: ${{ inputs.gradle-encryption-key }}
       working-directory: ${{ inputs.project-root }}
       shell: bash
       run: ./gradlew playgroundCIHostTests ${{ inputs.gradle-flags }}
diff --git a/.github/workflows/presubmit.yml b/.github/workflows/presubmit.yml
index e78e03a..3ceb6a8 100644
--- a/.github/workflows/presubmit.yml
+++ b/.github/workflows/presubmit.yml
@@ -16,14 +16,12 @@
     steps:
       - name: "Setup global constants"
         id: global-constants
-        # The configuration-cache cannot be used due to state excluded when caching Gradle User Home
         run: |
           set -x
           GRADLEW_FLAGS="-Dorg.gradle.internal.http.connectionTimeout=60000 \
             -Dorg.gradle.internal.http.socketTimeout=60000                  \
             -Dorg.gradle.internal.repository.max.retries=20                 \
             -Dorg.gradle.internal.repository.initial.backoff=500            \
-            --no-configuration-cache                                        \
             --stacktrace"
           echo "::set-output name=gradlew_flags::$GRADLEW_FLAGS"
       - name: Publish build scans link
@@ -40,6 +38,7 @@
     env:
       GRADLE_BUILD_CACHE_PASSWORD: ${{ secrets.GRADLE_BUILD_CACHE_PASSWORD }}
       GRADLE_ENTERPRISE_ACCESS_KEY: ${{ secrets.GRADLE_ENTERPRISE_ACCESS_KEY }}
+      GRADLE_ENCRYPTION_KEY: ${{ secrets.GRADLE_ENCRYPTION_KEY }}
     steps:
       - name: Pull request format
         uses: 'androidx/check-pr-format-action@main'
@@ -88,7 +87,7 @@
           echo "::set-output name=files::$AFFECTED_FILES"
 
       - name: "Setup Gradle"
-        uses: gradle/gradle-build-action@v2
+        uses: gradle/gradle-build-action@v3-beta
         with:
           # Only save Gradle User Home state for builds on the 'androidx-main' branch.
           # Builds on other branches will only read existing entries from the cache.
@@ -97,6 +96,8 @@
           # Don't reuse cache entries from any other Job.
           gradle-home-cache-strict-match: true
 
+          cache-encryption-key: ${{ secrets.GRADLE_ENCRYPTION_KEY }}
+
           # Limit the size of the cache entry.
           # These directories contain instrumented/transformed dependency jars which can be reconstructed relatively quickly.
           gradle-home-cache-excludes: |
@@ -129,6 +130,7 @@
       project-root: playground-projects/${{matrix.project-root || matrix.project}}-playground
       GRADLE_BUILD_CACHE_PASSWORD: ${{ secrets.GRADLE_BUILD_CACHE_PASSWORD }}
       GRADLE_ENTERPRISE_ACCESS_KEY: ${{ secrets.GRADLE_ENTERPRISE_ACCESS_KEY }}
+      GRADLE_ENCRYPTION_KEY: ${{ secrets.GRADLE_ENCRYPTION_KEY }}
     steps:
       - name: "Checkout androidx repo"
         uses: actions/checkout@v2
@@ -148,6 +150,7 @@
           project-root: ${{ env.project-root }}
           gradle-cache-password: ${{ secrets.GRADLE_BUILD_CACHE_PASSWORD }}
           gradle-enterprise-access-key: ${{ secrets.GRADLE_ENTERPRISE_ACCESS_KEY }}
+          gradle-encryption-key: ${{ secrets.GRADLE_ENCRYPTION_KEY }}
           gradle-flags: ${{ needs.setup.outputs.gradlew_flags }}
       # Upload artifacts task should be in the build-single-project
       # action but they have a tendency to fail and continue-on-error
diff --git a/activity/activity-lint/src/main/java/androidx/activity/lint/ActivityIssueRegistry.kt b/activity/activity-lint/src/main/java/androidx/activity/lint/ActivityIssueRegistry.kt
index 168ec91..e2022c7 100644
--- a/activity/activity-lint/src/main/java/androidx/activity/lint/ActivityIssueRegistry.kt
+++ b/activity/activity-lint/src/main/java/androidx/activity/lint/ActivityIssueRegistry.kt
@@ -29,7 +29,8 @@
     override val api = 14
     override val minApi = CURRENT_API
     override val issues get() = listOf(
-        ActivityResultFragmentVersionDetector.ISSUE
+        ActivityResultFragmentVersionDetector.ISSUE,
+        OnBackPressedDetector.ISSUE
     )
     override val vendor = Vendor(
         feedbackUrl = "https://issuetracker.google.com/issues/new?component=527362",
diff --git a/activity/activity-lint/src/main/java/androidx/activity/lint/OnBackPressedDetector.kt b/activity/activity-lint/src/main/java/androidx/activity/lint/OnBackPressedDetector.kt
new file mode 100644
index 0000000..7e3b21e
--- /dev/null
+++ b/activity/activity-lint/src/main/java/androidx/activity/lint/OnBackPressedDetector.kt
@@ -0,0 +1,76 @@
+/*
+ * 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.activity.lint
+
+import com.android.tools.lint.detector.api.Category
+import com.android.tools.lint.detector.api.Detector
+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.Scope
+import com.android.tools.lint.detector.api.Severity
+import com.intellij.psi.PsiMethod
+import java.util.EnumSet
+import org.jetbrains.uast.UCallExpression
+import org.jetbrains.uast.UMethod
+import org.jetbrains.uast.getParentOfType
+
+class OnBackPressedDetector : Detector(), Detector.UastScanner {
+    companion object {
+        val ISSUE = Issue.create(
+            id = "InvalidUseOfOnBackPressed",
+            briefDescription = "Do not call onBackPressed() within OnBackPressedDisptacher",
+            explanation = """You should not used OnBackPressedCallback for non-UI cases. If you
+                |add a callback, you have to handle back completely in the callback.
+            """,
+            category = Category.CORRECTNESS,
+            severity = Severity.WARNING,
+            implementation = Implementation(
+                OnBackPressedDetector::class.java,
+                EnumSet.of(Scope.JAVA_FILE),
+                Scope.JAVA_FILE_SCOPE
+            )
+        ).addMoreInfo(
+            "https://developer.android.com/guide/navigation/custom-back/" +
+                "predictive-back-gesture#ui-logic"
+        )
+    }
+
+    override fun getApplicableMethodNames(): List<String> = listOf(
+        OnBackPressed
+    )
+
+    override fun visitMethodCall(context: JavaContext, node: UCallExpression, method: PsiMethod) {
+        method.containingClass ?: return
+        if (isCalledInHandledOnBackPressed(node.getParentOfType())) {
+            context.report(
+                ISSUE,
+                context.getLocation(node),
+                "Should not call onBackPressed inside of OnBackPressedCallback.handledOnBackPressed"
+            )
+        }
+    }
+
+    private fun isCalledInHandledOnBackPressed(uMethod: UMethod?): Boolean {
+        if (uMethod == null) return false
+        return HandledOnBackPressed == uMethod.name
+    }
+}
+
+private val OnBackPressed = "onBackPressed"
+
+private val HandledOnBackPressed = "handledOnBackPressed"
diff --git a/activity/activity-lint/src/test/java/androidx/activity/lint/OnBackPressedDispatcherTest.kt b/activity/activity-lint/src/test/java/androidx/activity/lint/OnBackPressedDispatcherTest.kt
new file mode 100644
index 0000000..9c903c2
--- /dev/null
+++ b/activity/activity-lint/src/test/java/androidx/activity/lint/OnBackPressedDispatcherTest.kt
@@ -0,0 +1,95 @@
+/*
+ * 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.activity.lint
+
+import androidx.activity.lint.stubs.STUBS
+import com.android.tools.lint.checks.infrastructure.LintDetectorTest
+import com.android.tools.lint.detector.api.Detector
+import com.android.tools.lint.detector.api.Issue
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+
+@RunWith(JUnit4::class)
+class OnBackPressedDispatcherTest : LintDetectorTest() {
+    override fun getDetector(): Detector = OnBackPressedDetector()
+
+    override fun getIssues(): MutableList<Issue> =
+        mutableListOf(OnBackPressedDetector.ISSUE)
+
+    @Test
+    fun expectPassOnBackPressed() {
+        lint().files(
+            kotlin(
+                """
+                package com.example
+
+                import androidx.activity.ComponentActivity
+                import androidx.activity.OnBackPressedDispatcher
+
+                fun test() {
+                    val activity = ComponentActivity()
+                    activity.onBackPressed()
+                    val dispatcher = OnBackPressedDispatcher()
+                    dispatcher.onBackPressed()
+                }
+            """
+            ),
+            *STUBS
+        )
+            .run().expectClean()
+    }
+
+    @Test
+    fun expectFailOnBackPressed() {
+        lint().files(
+            kotlin(
+                """
+                package com.example
+
+                import androidx.activity.ComponentActivity
+                import androidx.activity.OnBackPressedCallback
+                import androidx.activity.OnBackPressedDispatcher
+
+                fun test() {
+                    object: OnBackPressedCallback {
+                        override fun handledOnBackPressed() {
+                            val activity = ComponentActivity()
+                            activity.onBackPressed()
+                            val dispatcher = OnBackPressedDispatcher()
+                            dispatcher.onBackPressed()
+                        }
+                    }
+                }
+            """
+            ),
+            *STUBS
+        )
+            .run()
+            .expect(
+                """
+                src/com/example/test.kt:12: Warning: Should not call onBackPressed inside of OnBackPressedCallback.handledOnBackPressed [InvalidUseOfOnBackPressed]
+                                            activity.onBackPressed()
+                                            ~~~~~~~~~~~~~~~~~~~~~~~~
+                src/com/example/test.kt:14: Warning: Should not call onBackPressed inside of OnBackPressedCallback.handledOnBackPressed [InvalidUseOfOnBackPressed]
+                                            dispatcher.onBackPressed()
+                                            ~~~~~~~~~~~~~~~~~~~~~~~~~~
+                0 errors, 2 warnings
+                """
+            )
+    }
+}
diff --git a/activity/activity-lint/src/test/java/androidx/activity/lint/stubs/Stubs.kt b/activity/activity-lint/src/test/java/androidx/activity/lint/stubs/Stubs.kt
index 716b288..caf6b3c 100644
--- a/activity/activity-lint/src/test/java/androidx/activity/lint/stubs/Stubs.kt
+++ b/activity/activity-lint/src/test/java/androidx/activity/lint/stubs/Stubs.kt
@@ -17,6 +17,7 @@
 package androidx.activity.lint.stubs
 
 import com.android.tools.lint.checks.infrastructure.LintDetectorTest.java
+import com.android.tools.lint.checks.infrastructure.LintDetectorTest.kotlin
 
 private val ACTIVITY_RESULT_CALLER = java(
     """
@@ -36,8 +37,41 @@
 """
 )
 
+private val COMPONENT_ACTIVITY = kotlin(
+    """
+    package androidx.activity
+
+    class ComponentActivity {
+        open fun onBackPressed() { }
+    }
+"""
+)
+
+private val ON_BACK_PRESSED_CALLBACK = kotlin(
+    """
+    package androidx.activity
+
+    class OnBackPressedCallback {
+        open fun handleOnBackPressed() { }
+    }
+"""
+)
+
+private val ON_BACK_PRESSED_DISPATCHER = kotlin(
+    """
+    package androidx.activity
+
+    class OnBackPressedDispatcher {
+        open fun onBackPressed() { }
+    }
+"""
+)
+
 // stubs for testing calls to registerForActivityResult
 internal val STUBS = arrayOf(
     ACTIVITY_RESULT_CALLER,
-    ACTIVITY_RESULT_CONTRACT
+    ACTIVITY_RESULT_CONTRACT,
+    COMPONENT_ACTIVITY,
+    ON_BACK_PRESSED_CALLBACK,
+    ON_BACK_PRESSED_DISPATCHER
 )
diff --git a/activity/activity/src/androidTest/java/androidx/activity/OnBackPressedDispatcherInvokerTest.kt b/activity/activity/src/androidTest/java/androidx/activity/OnBackPressedDispatcherInvokerTest.kt
index a02a5eb..7c6ae0f 100644
--- a/activity/activity/src/androidTest/java/androidx/activity/OnBackPressedDispatcherInvokerTest.kt
+++ b/activity/activity/src/androidTest/java/androidx/activity/OnBackPressedDispatcherInvokerTest.kt
@@ -485,8 +485,12 @@
 
         dispatcher.dispatchOnBackStarted(BackEventCompat(0.1F, 0.1F, 0.1F, EDGE_LEFT))
 
+        var startedCount2 = 0
+
         val callback2 = object : OnBackPressedCallback(true) {
-            override fun handleOnBackStarted(backEvent: BackEventCompat) { }
+            override fun handleOnBackStarted(backEvent: BackEventCompat) {
+                startedCount2++
+            }
             override fun handleOnBackProgressed(backEvent: BackEventCompat) {}
             override fun handleOnBackPressed() { }
             override fun handleOnBackCancelled() { }
@@ -494,12 +498,12 @@
 
         dispatcher.addCallback(callback2)
 
-        assertThat(registerCount).isEqualTo(2)
-
         dispatcher.dispatchOnBackStarted(BackEventCompat(0.1F, 0.1F, 0.1F, EDGE_LEFT))
 
+        assertThat(registerCount).isEqualTo(1)
+
         assertThat(cancelledCount).isEqualTo(1)
 
-        assertThat(unregisterCount).isEqualTo(1)
+        assertThat(startedCount2).isEqualTo(1)
     }
 }
diff --git a/activity/activity/src/main/java/androidx/activity/result/ActivityResultRegistry.kt b/activity/activity/src/main/java/androidx/activity/result/ActivityResultRegistry.kt
index 7709aa3..4d73896 100644
--- a/activity/activity/src/main/java/androidx/activity/result/ActivityResultRegistry.kt
+++ b/activity/activity/src/main/java/androidx/activity/result/ActivityResultRegistry.kt
@@ -290,9 +290,11 @@
         if (restoredLaunchedKeys != null) {
             launchedKeys.addAll(restoredLaunchedKeys)
         }
-        pendingResults.putAll(
-            savedInstanceState.getBundle(KEY_COMPONENT_ACTIVITY_PENDING_RESULTS)
-        )
+        val restoredPendingResults = savedInstanceState.getBundle(
+            KEY_COMPONENT_ACTIVITY_PENDING_RESULTS)
+        if (restoredPendingResults != null) {
+            pendingResults.putAll(restoredPendingResults)
+        }
         for (i in keys.indices) {
             val key = keys[i]
             // Developers may have already registered with this same key by the time we restore
diff --git a/benchmark/benchmark-common/src/androidTest/java/androidx/benchmark/DeviceInfoTest.kt b/benchmark/benchmark-common/src/androidTest/java/androidx/benchmark/DeviceInfoTest.kt
index ddcc1d0..8e9ccaa 100644
--- a/benchmark/benchmark-common/src/androidTest/java/androidx/benchmark/DeviceInfoTest.kt
+++ b/benchmark/benchmark-common/src/androidTest/java/androidx/benchmark/DeviceInfoTest.kt
@@ -58,14 +58,14 @@
 
         // Wembley available versions don't hit any of the method tracing issues, no art mainline
         assertFalse(DeviceInfo.methodTracingAffectsMeasurements)
-        assertEquals(-1, DeviceInfo.artMainlineVersion)
+        assertEquals(DeviceInfo.ART_MAINLINE_VERSION_UNDETECTED, DeviceInfo.artMainlineVersion)
     }
 
     @Test
     fun artMainlineVersion() {
         // bypass main test if appear to be on go device without art mainline module
         if (Build.VERSION.SDK_INT in 31..33 && DeviceInfo.isLowRamDevice) {
-            if (DeviceInfo.artMainlineVersion == -1L) {
+            if (DeviceInfo.artMainlineVersion == DeviceInfo.ART_MAINLINE_VERSION_UNDETECTED) {
                 return // bypass rest of test, appear to be on go device
             }
         }
@@ -83,15 +83,15 @@
                 "cmd package list packages --show-versioncode --apex-only art"
             ).trim()
 
-            // "google" may or may not be present in package
-            val expectedRegExStr = "package:com(\\.google)?\\.android\\.art" +
+            // "google" and "go" may or may not be present in package
+            val expectedRegExStr = "package:com(\\.google)?\\.android(\\.go)?\\.art" +
                 " versionCode:${DeviceInfo.artMainlineVersion}"
             assertTrue(
                 expectedRegExStr.toRegex().matches(shellVersion),
                 "Expected shell version ($shellVersion) to match $expectedRegExStr"
             )
         } else {
-            assertEquals(-1, DeviceInfo.artMainlineVersion)
+            assertEquals(DeviceInfo.ART_MAINLINE_VERSION_UNDETECTED, DeviceInfo.artMainlineVersion)
         }
     }
 }
diff --git a/benchmark/benchmark-common/src/main/java/androidx/benchmark/BenchmarkState.kt b/benchmark/benchmark-common/src/main/java/androidx/benchmark/BenchmarkState.kt
index 857eb39..910e5e2 100644
--- a/benchmark/benchmark-common/src/main/java/androidx/benchmark/BenchmarkState.kt
+++ b/benchmark/benchmark-common/src/main/java/androidx/benchmark/BenchmarkState.kt
@@ -467,6 +467,12 @@
             )
         }
         check(
+            DeviceInfo.artMainlineVersion != DeviceInfo.ART_MAINLINE_VERSION_UNDETECTED_ERROR
+        ) {
+            "Unable to detect ART mainline module version to check for interference from method" +
+                " tracing, please see logcat for details, and/or file a bug with logcat."
+        }
+        check(
             !enableMethodTracingAffectsMeasurementError ||
             !DeviceInfo.methodTracingAffectsMeasurements ||
                 !MethodTracing.hasBeenUsed) {
diff --git a/benchmark/benchmark-common/src/main/java/androidx/benchmark/DeviceInfo.kt b/benchmark/benchmark-common/src/main/java/androidx/benchmark/DeviceInfo.kt
index 874dc2a..5e60329 100644
--- a/benchmark/benchmark-common/src/main/java/androidx/benchmark/DeviceInfo.kt
+++ b/benchmark/benchmark-common/src/main/java/androidx/benchmark/DeviceInfo.kt
@@ -111,20 +111,21 @@
     private fun queryArtMainlineVersion(): Long {
         val artMainlinePackage = getMainlineAppInfo("com.google.android.art")
             ?: getMainlineAppInfo("com.android.art")
-
+            ?: getMainlineAppInfo("com.google.android.go.art")
+            ?: getMainlineAppInfo("com.android.go.art")
         if (artMainlinePackage == null) {
-            check(Build.VERSION.SDK_INT in 31..33 && isLowRamDevice) {
-                "Unable to find installed ART mainline module," +
-                    " sdk ${Build.VERSION.SDK_INT}, isLowRamDevice $isLowRamDevice"
-            }
-            // accept missing module if it appears we're on a go device
             Log.d(
                 BenchmarkState.TAG,
-                "No ART mainline module found, appears to be go device prior to mainline support"
+                "No ART mainline module found on API ${Build.VERSION.SDK_INT}"
             )
-            return -1
+            return if (Build.VERSION.SDK_INT >= 34) {
+                // defer error to avoid crashing during init
+                ART_MAINLINE_VERSION_UNDETECTED_ERROR
+            } else {
+                // accept missing module if we can't be sure it would have one installed (e.g. go)
+                ART_MAINLINE_VERSION_UNDETECTED
+            }
         }
-
         // This is an EXTREMELY SILLY way to find out ART's versions, but I couldn't find a better
         // one without reflecting into ApplicationInfo.longVersionCode (not allowed in jetpack)
         // or shell commands (slower)
@@ -215,15 +216,6 @@
         )
     }
 
-    val artMainlineVersion = when {
-        Build.VERSION.SDK_INT >= 31 ->
-            queryArtMainlineVersion()
-        Build.VERSION.SDK_INT == 30 ->
-            1
-        else ->
-            -1
-    }
-
     /**
      * Starting with the first Android U release, ART mainline drops optimizations after method
      * tracing occurs, so we disable tracing on those mainline versions.
@@ -234,6 +226,27 @@
      */
     private val ART_MAINLINE_MIN_VERSIONS_AFFECTING_METHOD_TRACING = 340000000L.until(341513000)
 
+    /**
+     * Used when mainline version failed to detect, but this is accepted due to low API level (<34)
+     * where presence isn't guaranteed (e.g. go devices)
+     */
+    const val ART_MAINLINE_VERSION_UNDETECTED = -1L
+
+    /**
+     * Used when mainline version failed to detect, and should throw an error when
+     * running a microbenchmark
+     */
+    const val ART_MAINLINE_VERSION_UNDETECTED_ERROR = -100L
+
+    val artMainlineVersion = when {
+        Build.VERSION.SDK_INT >= 31 ->
+            queryArtMainlineVersion()
+        Build.VERSION.SDK_INT == 30 ->
+            1
+        else ->
+            ART_MAINLINE_VERSION_UNDETECTED
+    }
+
     val methodTracingAffectsMeasurements =
         Build.VERSION.SDK_INT in 26..30 || // b/313868903
             artMainlineVersion in ART_MAINLINE_MIN_VERSIONS_AFFECTING_METHOD_TRACING // b/303660864
diff --git a/benchmark/benchmark-macro/src/androidTest/java/androidx/benchmark/macro/CompilationModeTest.kt b/benchmark/benchmark-macro/src/androidTest/java/androidx/benchmark/macro/CompilationModeTest.kt
index f3b0e7e..51fa028 100644
--- a/benchmark/benchmark-macro/src/androidTest/java/androidx/benchmark/macro/CompilationModeTest.kt
+++ b/benchmark/benchmark-macro/src/androidTest/java/androidx/benchmark/macro/CompilationModeTest.kt
@@ -17,8 +17,10 @@
 package androidx.benchmark.macro
 
 import android.os.Build
+import androidx.benchmark.DeviceInfo
 import androidx.benchmark.Shell
 import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.MediumTest
 import androidx.test.filters.SdkSuppress
 import androidx.test.filters.SmallTest
 import kotlin.test.assertFailsWith
@@ -98,4 +100,27 @@
         }
         assertTrue(CompilationMode.Interpreted.isSupportedWithVmSettings())
     }
+
+    @Test
+    @MediumTest
+    @SdkSuppress(minSdkVersion = 30, maxSdkVersion = 33)
+    fun reinstallTargetPackageTest() {
+        assumeFalse(DeviceInfo.isEmulator) // Don't run these tests on an emulator.
+        val mode = CompilationMode.DEFAULT
+        val copiedApkPaths = mode.copiedApkPaths(Packages.TARGET)
+        try {
+            kotlin.test.assertTrue { copiedApkPaths.isNotEmpty() }
+            mode.uninstallPackage(Packages.TARGET)
+            var path = Shell.pmPath(Packages.TARGET)
+            kotlin.test.assertTrue { path.isEmpty() }
+            mode.installPackageFromPaths(
+                packageName = Packages.TARGET,
+                copiedApkPaths = copiedApkPaths
+            )
+            path = Shell.pmPath(Packages.TARGET)
+            kotlin.test.assertTrue { path.isNotEmpty() }
+        } finally {
+            Shell.executeScriptSilent("rm $copiedApkPaths")
+        }
+    }
 }
diff --git a/benchmark/benchmark-macro/src/androidTest/java/androidx/benchmark/macro/KillSystemProcessTest.kt b/benchmark/benchmark-macro/src/androidTest/java/androidx/benchmark/macro/KillSystemProcessTest.kt
new file mode 100644
index 0000000..50ca4f0
--- /dev/null
+++ b/benchmark/benchmark-macro/src/androidTest/java/androidx/benchmark/macro/KillSystemProcessTest.kt
@@ -0,0 +1,95 @@
+/*
+ * 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.benchmark.macro
+
+import android.annotation.SuppressLint
+import androidx.benchmark.DeviceInfo
+import androidx.benchmark.Shell
+import androidx.test.filters.MediumTest
+import androidx.test.filters.SdkSuppress
+import java.text.SimpleDateFormat
+import kotlin.test.assertTrue
+import org.junit.Assume.assumeTrue
+import org.junit.Test
+
+@MediumTest
+class KillSystemProcessTest {
+
+    @Test
+    @SdkSuppress(minSdkVersion = 30) // getHistoricalExitReasons was introduced in API 30.
+    fun killSystemUiTest() {
+        // Don't run these tests on an emulator
+        assumeTrue(DeviceInfo.isRooted && !DeviceInfo.isEmulator)
+        val scope = MacrobenchmarkScope(
+            packageName = SYSTEM_UI,
+            launchWithClearTask = true
+        )
+        assertTrue { Shell.isPackageAlive(scope.packageName) }
+        // Look at the last kill exit record and keep track of that.
+        val start = applicationExitTimestamps(packageName = scope.packageName).maxOrNull() ?: 0L
+        scope.killProcess()
+        // Wait for some time for the book-keeping to be complete
+        @Suppress("BanThreadSleep")
+        Thread.sleep(DELAY)
+        assertTrue(
+            // Here we want to make sure that there is at least one new timestamp
+            // more recent than the last ones we looked at.
+            applicationExitTimestamps(packageName = scope.packageName)
+                .any { it >= start }
+        )
+    }
+
+    companion object {
+        private const val SYSTEM_UI = "com.android.systemui"
+
+        private const val DELAY = 1_000L
+
+        private const val TIMESTAMP_START_MARKER = "timestamp="
+
+        private const val TIMESTAMP_END_MARKER = "pid="
+
+        @SuppressLint("SimpleDateFormat")
+        private val TIMESTAMP_FORMAT = SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS")
+
+        fun applicationExitTimestamps(packageName: String): List<Long> {
+
+            // Last Timestamp of Persistence Into Persistent Storage: 2024-01-22 22:23:41.974
+            //  package: com.android.systemui
+            //    Historical Process Exit for uid=10085
+            //        ApplicationExitInfo #0:
+            //          timestamp=2024-01-23 00:54:34.671 pid=1967 realUid=10085 packageUid=10085
+
+            val output = Shell.executeScriptCaptureStdoutStderr(
+                "dumpsys activity exit-info $packageName"
+            )
+            require(output.stderr.isBlank())
+            return output.stdout.lines().mapNotNull { line ->
+                val start = line.indexOf(TIMESTAMP_START_MARKER)
+                val end = line.indexOf(TIMESTAMP_END_MARKER, startIndex = start)
+                if (start >= 0 && end >= 0) {
+                    val timestamp = line.substringAfter(TIMESTAMP_START_MARKER)
+                        .substringBefore(TIMESTAMP_END_MARKER)
+                        .trim()
+
+                    TIMESTAMP_FORMAT.parse(timestamp)?.time
+                } else {
+                    null
+                }
+            }
+        }
+    }
+}
diff --git a/benchmark/benchmark-macro/src/main/java/androidx/benchmark/macro/CompilationMode.kt b/benchmark/benchmark-macro/src/main/java/androidx/benchmark/macro/CompilationMode.kt
index 7751daec..21be9ce 100644
--- a/benchmark/benchmark-macro/src/main/java/androidx/benchmark/macro/CompilationMode.kt
+++ b/benchmark/benchmark-macro/src/main/java/androidx/benchmark/macro/CompilationMode.kt
@@ -30,6 +30,7 @@
 import androidx.benchmark.macro.CompilationMode.None
 import androidx.benchmark.macro.CompilationMode.Partial
 import androidx.profileinstaller.ProfileInstallReceiver
+import java.lang.StringBuilder
 import org.junit.AssumptionViolatedException
 
 /**
@@ -138,51 +139,86 @@
 
     /**
      * A more expensive alternative to `compile --reset` which doesn't preserve app data, but
-     * does work on older APIs without root
+     * does work on older APIs without root.
      */
-    private fun reinstallPackage(packageName: String) {
+    @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+    fun reinstallPackage(packageName: String) {
         inMemoryTrace("reinstallPackage") {
-
-            // Copy APKs to /data/local/temp
-            val apkPaths = Shell.pmPath(packageName)
-
-            val tempApkPaths: List<String> = apkPaths.mapIndexed { index, apkPath ->
-                val tempApkPath =
-                    "/data/local/tmp/$packageName-$index-${System.currentTimeMillis()}.apk"
-                Log.d(TAG, "Copying APK $apkPath to $tempApkPath")
-                Shell.executeScriptSilent(
-                    "cp $apkPath $tempApkPath"
-                )
-                tempApkPath
-            }
-            val tempApkPathsString = tempApkPaths.joinToString(" ")
-
+            val copiedApkPaths = copiedApkPaths(packageName)
             try {
                 // Uninstall package
                 // This is what effectively clears the ART profiles
-                Log.d(TAG, "Uninstalling $packageName")
-                var output = Shell.executeScriptCaptureStdout("pm uninstall $packageName")
-                check(output.trim() == "Success") {
-                    "Unable to uninstall $packageName ($output)"
-                }
+                uninstallPackage(packageName)
                 // Install the APK from /data/local/tmp
-                Log.d(TAG, "Installing $packageName")
-                // Provide a `-t` argument to `pm install` to ensure test packages are
-                // correctly installed. (b/231294733)
-                output = Shell.executeScriptCaptureStdout("pm install -t $tempApkPathsString")
-
-                check(output.trim() == "Success" || output.contains("PERFORMED")) {
-                    "Unable to install $packageName (out=$output)"
-                }
+                installPackageFromPaths(packageName = packageName, copiedApkPaths = copiedApkPaths)
             } finally {
                 // Cleanup the temporary APK
-                Log.d(TAG, "Deleting $tempApkPathsString")
-                Shell.executeScriptSilent("rm $tempApkPathsString")
+                Log.d(TAG, "Deleting $copiedApkPaths")
+                Shell.executeScriptSilent("rm $copiedApkPaths")
             }
         }
     }
 
     /**
+     * Copies the APKs obtained from the current install location, into `/data/local/tmp` and
+     * returns a `<space>` delimited list of paths that can be used to reinstall the app package
+     * after uninstall.
+     */
+    @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+    fun copiedApkPaths(packageName: String): String {
+        // Copy APKs to /data/local/temp
+        val apkPaths = Shell.pmPath(packageName)
+
+        val tempApkPaths: List<String> = apkPaths.mapIndexed { index, apkPath ->
+            val tempApkPath =
+                "/data/local/tmp/$packageName-$index-${System.currentTimeMillis()}.apk"
+            Log.d(TAG, "Copying APK $apkPath to $tempApkPath")
+            Shell.executeScriptSilent(
+                "cp $apkPath $tempApkPath"
+            )
+            tempApkPath
+        }
+        return tempApkPaths.joinToString(" ")
+    }
+
+    /**
+     * Uninstalls an app package by using `pm uninstall` under the hood.
+     */
+    @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+    fun uninstallPackage(packageName: String) {
+        Log.d(TAG, "Uninstalling $packageName")
+        val output = Shell.executeScriptCaptureStdout("pm uninstall $packageName")
+        check(output.trim() == "Success") {
+            "Unable to uninstall $packageName ($output)"
+        }
+    }
+
+    /**
+     * Installs the app using a set of APKs that were previously copied and staged into
+     * `/data/local/tmp` from a pre-existing install session.
+     */
+    @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+    fun installPackageFromPaths(packageName: String, copiedApkPaths: String) {
+        Log.d(TAG, "Installing $packageName")
+        val builder = StringBuilder("pm install")
+        // Provide a `-t` argument to `pm install` to ensure test packages are
+        // correctly installed. (b/231294733)
+        builder.append(" -t")
+        if (Build.VERSION.SDK_INT >= 30) {
+            // Use --skip-verification to disable Play protect.
+            // This option was introduced in Android R (30)
+            // b/308100444 has additional context.
+            builder.append(" --skip-verification")
+        }
+        builder.append(" $copiedApkPaths")
+        val output = Shell.executeScriptCaptureStdout(builder.toString())
+
+        check(output.trim() == "Success" || output.contains("PERFORMED")) {
+            "Unable to install $packageName (out=$output)"
+        }
+    }
+
+    /**
      * Writes a skip file via a [ProfileInstallReceiver] broadcast, so profile installation
      * does not interfere with benchmarks.
      */
@@ -481,12 +517,14 @@
                         you must disable jit on your device with the following command:
                         `adb shell setprop dalvik.vm.extra-opts -Xusejit:false; adb shell stop; adb shell start`                         
                     """.trimIndent()
+
                 DeviceInfo.isRooted && this != CompilationMode.Interpreted ->
                     """
                         To run benchmarks with CompilationMode $this,
                         you must enable jit on your device with the following command:
                         `adb shell setprop dalvik.vm.extra-opts \"\"; adb shell stop; adb shell start` 
                     """.trimIndent()
+
                 else ->
                     "You must toggle usejit on the VM to use CompilationMode $this, this requires" +
                         "rooting your device."
diff --git a/benchmark/benchmark-macro/src/main/java/androidx/benchmark/macro/Macrobenchmark.kt b/benchmark/benchmark-macro/src/main/java/androidx/benchmark/macro/Macrobenchmark.kt
index 40284fc..6d83128 100644
--- a/benchmark/benchmark-macro/src/main/java/androidx/benchmark/macro/Macrobenchmark.kt
+++ b/benchmark/benchmark-macro/src/main/java/androidx/benchmark/macro/Macrobenchmark.kt
@@ -18,6 +18,8 @@
 
 import android.content.pm.ApplicationInfo
 import android.content.pm.ApplicationInfo.FLAG_DEBUGGABLE
+import android.content.pm.ApplicationInfo.FLAG_SYSTEM
+import android.content.pm.ApplicationInfo.FLAG_UPDATED_SYSTEM_APP
 import android.content.pm.PackageManager
 import android.os.Build
 import android.util.Log
@@ -46,10 +48,11 @@
 import java.io.File
 
 /**
- * Get package ApplicationInfo, throw if not found
+ * Get package ApplicationInfo, throw if not found.
  */
+@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
 @Suppress("DEPRECATION")
-internal fun getInstalledPackageInfo(packageName: String): ApplicationInfo {
+fun getInstalledPackageInfo(packageName: String): ApplicationInfo {
     val pm = InstrumentationRegistry.getInstrumentation().context.packageManager
     try {
         return pm.getApplicationInfo(packageName, 0)
@@ -61,6 +64,14 @@
     }
 }
 
+/**
+ * @return `true` if the [ApplicationInfo] instance is referring to a system app.
+ */
+@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+fun ApplicationInfo.isSystemApp(): Boolean {
+    return flags and (FLAG_SYSTEM or FLAG_UPDATED_SYSTEM_APP) > 0
+}
+
 internal fun checkErrors(packageName: String): ConfigurationError.SuppressionState? {
     Arguments.throwIfError()
 
@@ -208,10 +219,13 @@
     val startTime = System.nanoTime()
     // Ensure method tracing is explicitly enabled and that we are not running in dry run mode.
     val launchWithMethodTracing = Arguments.macrobenchMethodTracingEnabled()
+    val applicationInfo = getInstalledPackageInfo(packageName)
     val scope = MacrobenchmarkScope(
         packageName,
         launchWithClearTask = launchWithClearTask
     )
+    // Capture if the app being benchmarked is a system app.
+    scope.isSystemApp = applicationInfo.isSystemApp()
     scope.launchWithMethodTracing = launchWithMethodTracing
     // Ensure the device is awake
     scope.device.wakeUp()
diff --git a/benchmark/benchmark-macro/src/main/java/androidx/benchmark/macro/MacrobenchmarkScope.kt b/benchmark/benchmark-macro/src/main/java/androidx/benchmark/macro/MacrobenchmarkScope.kt
index 992c951..a3af2b9 100644
--- a/benchmark/benchmark-macro/src/main/java/androidx/benchmark/macro/MacrobenchmarkScope.kt
+++ b/benchmark/benchmark-macro/src/main/java/androidx/benchmark/macro/MacrobenchmarkScope.kt
@@ -85,6 +85,11 @@
     internal var flushArtProfiles: Boolean = false
 
     /**
+     * `true` if the app is a system app.
+     */
+    internal var isSystemApp: Boolean = false
+
+    /**
      * Current Macrobenchmark measurement iteration, or null if measurement is not yet enabled.
      *
      * Non-measurement iterations can occur due to warmup a [CompilationMode], or prior to the first
@@ -430,11 +435,13 @@
      * Force-stop the process being measured.
      */
     private fun killProcessImpl() {
-        val useKillAll = Shell.isSessionRooted()
+        val isRooted = Shell.isSessionRooted()
         Log.d(TAG, "Killing process $packageName")
-        if (useKillAll) {
+        if (isRooted && isSystemApp) {
             device.executeShellCommand("killall $packageName")
         } else {
+            // We want to use `am force-stop` for apps that are not system apps
+            // to make sure app components are not automatically restarted by system_server.
             device.executeShellCommand("am force-stop $packageName")
         }
         // System Apps need an additional Thread.sleep() to ensure that the process is killed.
diff --git a/benchmark/integration-tests/macrobenchmark/src/main/java/androidx/benchmark/integration/macrobenchmark/SystemAppTest.kt b/benchmark/integration-tests/macrobenchmark/src/main/java/androidx/benchmark/integration/macrobenchmark/SystemAppTest.kt
new file mode 100644
index 0000000..c88674b
--- /dev/null
+++ b/benchmark/integration-tests/macrobenchmark/src/main/java/androidx/benchmark/integration/macrobenchmark/SystemAppTest.kt
@@ -0,0 +1,48 @@
+/*
+ * 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.benchmark.integration.macrobenchmark
+
+import androidx.benchmark.macro.getInstalledPackageInfo
+import androidx.benchmark.macro.isSystemApp
+import androidx.test.filters.MediumTest
+import kotlin.test.assertFalse
+import kotlin.test.assertTrue
+import org.junit.Test
+
+@MediumTest
+class SystemAppTest {
+
+    @Test
+    fun targetIsNotASystemApp() {
+        val applicationInfo = getInstalledPackageInfo(BENCHMARK_TARGET)
+        assertFalse(applicationInfo.isSystemApp())
+    }
+
+    @Test
+    fun sysUiIsASystemApp() {
+        val applicationInfo = getInstalledPackageInfo(SYSTEM_UI)
+        assertTrue(applicationInfo.isSystemApp())
+    }
+
+    companion object {
+        // Macrobenchmark target package
+        private const val BENCHMARK_TARGET = "androidx.benchmark.integration.macrobenchmark.target"
+
+        // System UI
+        private const val SYSTEM_UI = "com.android.systemui"
+    }
+}
diff --git a/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/compat/CaptureSessionFactory.kt b/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/compat/CaptureSessionFactory.kt
index 903a52f..3cb3f7b 100644
--- a/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/compat/CaptureSessionFactory.kt
+++ b/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/compat/CaptureSessionFactory.kt
@@ -409,7 +409,7 @@
             checkNotNull(postviewStream) {
                 "Postview Stream in StreamGraph cannot be null for reprocessing request"
             }
-            if (postviewOutput == null && outputConfig.streams == postviewStream.outputs) {
+            if (postviewOutput == null && outputConfig.streams.contains(postviewStream)) {
                 postviewOutput = output
             } else {
                 allOutputs.add(output)
diff --git a/compose/foundation/foundation-lint/src/main/java/androidx/compose/foundation/lint/NonLambdaOffsetModifierDetector.kt b/compose/foundation/foundation-lint/src/main/java/androidx/compose/foundation/lint/NonLambdaOffsetModifierDetector.kt
index 3d98da8..9380897 100644
--- a/compose/foundation/foundation-lint/src/main/java/androidx/compose/foundation/lint/NonLambdaOffsetModifierDetector.kt
+++ b/compose/foundation/foundation-lint/src/main/java/androidx/compose/foundation/lint/NonLambdaOffsetModifierDetector.kt
@@ -21,6 +21,7 @@
 import androidx.compose.lint.Names
 import androidx.compose.lint.inheritsFrom
 import androidx.compose.lint.isInPackageName
+import androidx.compose.lint.toKmFunction
 import com.android.tools.lint.detector.api.Category
 import com.android.tools.lint.detector.api.Detector
 import com.android.tools.lint.detector.api.Implementation
@@ -31,8 +32,8 @@
 import com.android.tools.lint.detector.api.SourceCodeScanner
 import com.android.tools.lint.detector.api.UastLintUtils.Companion.tryResolveUDeclaration
 import com.intellij.psi.PsiMethod
-import com.intellij.psi.util.ClassUtil
 import java.util.EnumSet
+import kotlinx.metadata.KmClassifier
 import org.jetbrains.kotlin.psi.KtProperty
 import org.jetbrains.uast.UCallExpression
 import org.jetbrains.uast.UDeclaration
@@ -72,11 +73,29 @@
     }
 
     /**
-     * Has two parameters of type DP
+     * For the form of `Modifier.<method-name>(Dp, Dp): Modifier`.
+     *
+     * Note that method-name is already handled by [getApplicableMethodNames].
      */
     private fun PsiMethod.isDesiredOffsetOverload(): Boolean {
-        // use signature
-        return ClassUtil.getAsmMethodSignature(this) == OffsetSignature
+        val kmFunction = this.toKmFunction() ?: return false
+        val receiverClassifier = kmFunction.receiverParameterType?.classifier ?: return false
+        val returnTypeClassifier = kmFunction.returnType.classifier
+
+        if (receiverClassifier != ModifierClassifier) {
+            return false
+        }
+        if (returnTypeClassifier != ModifierClassifier) {
+            return false
+        }
+
+        val valueParameters = kmFunction.valueParameters
+        if (valueParameters.size != 2) {
+            return false
+        }
+        return valueParameters.all {
+            it.type.classifier == DpClassifier
+        }
     }
 
     private fun hasStateBackedArguments(node: UCallExpression): Boolean {
@@ -152,6 +171,6 @@
     return cleanCallExpression.returnType?.inheritsFrom(Names.Runtime.State) ?: false
 }
 
-private const val OffsetSignature =
-    "(Landroidx/compose/ui/Modifier;Landroidx/compose/ui/unit/Dp;Landroidx/compose/ui/unit/Dp;)" +
-        "Landroidx/compose/ui/Modifier;"
+private val ModifierClassifier = KmClassifier.Class(Names.Ui.Modifier.kmClassName)
+
+private val DpClassifier = KmClassifier.Class(Names.Ui.Unit.Dp.kmClassName)
diff --git a/compose/foundation/foundation-lint/src/test/java/androidx/compose/foundation/lint/NonLambdaOffsetModifierDetectorTest.kt b/compose/foundation/foundation-lint/src/test/java/androidx/compose/foundation/lint/NonLambdaOffsetModifierDetectorTest.kt
index 0eb8d9a..0b7007e 100644
--- a/compose/foundation/foundation-lint/src/test/java/androidx/compose/foundation/lint/NonLambdaOffsetModifierDetectorTest.kt
+++ b/compose/foundation/foundation-lint/src/test/java/androidx/compose/foundation/lint/NonLambdaOffsetModifierDetectorTest.kt
@@ -23,7 +23,6 @@
 import com.android.tools.lint.checks.infrastructure.TestFile
 import com.android.tools.lint.detector.api.Detector
 import com.android.tools.lint.detector.api.Issue
-import org.junit.Ignore
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.junit.runners.JUnit4
@@ -38,7 +37,7 @@
     private val OffsetStub: TestFile = bytecodeStub(
         filename = "Offset.kt",
         filepath = "androidx/compose/foundation/layout",
-        checksum = 0xd449361a,
+        checksum = 0xdde1b690,
         source = """
         package androidx.compose.foundation.layout
 
@@ -56,39 +55,42 @@
         """,
         """
                 META-INF/main.kotlin_module:
-                H4sIAAAAAAAAAGNgYGBmYGBgBGJ2KM3ApcellJiXUpSfmVKhl5yfW5BfnKqX
-                ll+al5JYkpmfp5eTWJlfWiLE4Z+WVpxa4l3CpcAlgaG+NFOvNC+zRIjFpcC7
-                RIlBiwEAXUlt+WoAAAA=
+                H4sIAAAAAAAA/2NgYGBmYGBgBGJOBijg0uNSSsxLKcrPTKnQS87PLcgvTtVL
+                yy/NS0ksyczP08tJrMwvLRHi8E9LK04t8S7hUuCSwFBfmqlXmpdZIsTiUgBU
+                wcfFUpJaXCLEFgIkvUuUGLQYAPzR4e16AAAA
                 """,
         """
                 androidx/compose/foundation/layout/OffsetKt.class:
-                H4sIAAAAAAAAALVW3U8jVRT/3en3tOyW8rXAwtZtdaGwTAcXVimiyIdWWkC7
-                ITFEk2k7LQPtTNOZIfBi9skX/wDjqy++GhPjuiaG+Ogftdlzpx+UD9sVtMnc
-                e+6555z7O79z53T+fvXyTwBP8DnDjKIX64ZWPJEKRrVmmKpUMmy9qFiaoUsV
-                5dSwLWmnVDJVa8vygTGED5VjhXb0srSTP1QLpHUxeA3HhuFkKnMloq1JWaOo
-                lTS1nrp219Y1S1qvdd+c7h6YIZYx6mXpULXydUXTTUnRdcNyEjGlbcPatisV
-                svIuWweaueKHn2HyyLAqmi4dHlclTbfUuq5UpLRu1cldK5g+iAxDhQO1cNT0
-                31XqSlUlQ4ZHU5nLTKQ6NDkepJya3gshhD4RQdxhYCd+hGk69SPCcL9bPj4M
-                MgTWaEPRKQOG7rzG25apEIYxEsAQ7jG4rQOVfFd6FKUHtSGMYTxIEe8zhOKc
-                vnir3JO9ijLRtaYMdxqR4kW1pNgVivjd/3aB0lcL1vNOjXcJ6EOMXyeNVitE
-                9dQmL/bbeEdEHI9C8MArQsA0gxjX4qV4WbXWa1T8NEOwQWKxFteOiQIlbxoV
-                21J3mqQONrYvq4cvKlqUhTDXOElm+LoXeR0XvmTrhcbLsdmU5N58/HS7A5Yf
-                d6mQSi+dddqlhvRmNlJPrfRC6oeHIdorXYb+lklWtRTqegrphOqxi9oj44OP
-                CnbEBYH0JxqXkiQVietfz55HxbPnonBPaE2dT3tnLBamQUiyBD3zI2FhbCDi
-                jghJtzN6kq6/fvQKfu/YZKeZ3y+EfbTyO1KASxRHeKMwQrcoHPw8Q6SVdycZ
-                D3sXhyH+JvXhjaF5wMaJxX0NvXXSs9OaSgaBhuncEd1s95pRVBnuZjRd3bar
-                ebX+TMlXVA7TKCiVPaWu8XVTOf6FrVtaVU3rx5qpkWr1vNETvsu77Z59wawv
-                ZymFo6xSawYN5LSyrlh2nWQxZ9j1grqp8Y3BxmJdzdvldi4Mo81j9q5AgEzv
-                ohv858UobwNw4RNafUV6foEeJCKBF7g7E+mncTYyQGPiF4yeYeh3TAj4md82
-                fOq4EwMQkSY52nDFJD1wpDDpmCNFSBLwWdPDR/MWPQOu5qJjDAfwFh6SzPF8
-                TyH5zsKE+5sfMOha9LgWvX8g/uWQ59vf6P9mwnOdOpuYmX2BBEfpQoZGN4SR
-                YQfvMCULwhsibCM0x2iea+JPkF2I5BnMEsoA+vCYJA/ZtHTRtm6Ud7TbkRa8
-                QJp0W9KS/wlp8/9MWpDI6SfSgkRIP6UfvAFpHrxL9hxkljITaB5tkbbQlS7+
-                iZJ2oDhO7TvGQy7SftaxfnKFrD7hAlm8bDdG0HcBgXQzBC5sO4ab2CEVy2VX
-                d8V2mxG3nIYkJnLRlrQpzkTl6LnFv/gWJs/56HrtWq/zTwSyS2REOSbPygtL
-                srgQm1+SFxvT03MgTm+5HRp+SjIm8+iyzGcKvyFil+hIEzlPicf39uFK4/00
-                lmhEKo1lfJDGCj7cBzPxEVb3IZqYM/HAhMfExybWTKyb2DARNhE1EXkN1SFU
-                dTgMAAA=
+                H4sIAAAAAAAA/+1WSVMbRxT+erSPhC2EN7GZWAoGYTwS2DhGDrEDKFEswEaE
+                xCFLDdIID0gzqlkoyCFF5ZBrzjkml1xTOZEcUpRzy2/Ib0nl9YwECGRE8DVS
+                9fTr7u9t3+vpnr/++f0PAPfwBcOYrJUNXS3vSCW9VtdNRarotlaWLVXXpKq8
+                q9uWtFSpmIr11AqAMUQ35W2ZVrQNaWl9UynRrIfhku5gxlfrLya/XrzH8Hik
+                cMqyrUoLelmtqIqRzeVGzwYwJAq6sSFtKta6IauaKcmapltOYKa0qFuLdrVK
+                qEjSeqmaSdd/EEGGwS3dqqqatLldk1TNUgxNrkp5zTLIiFoyAxAZrpZeKqWt
+                hpVnsiHXFAIy3B4pnMwve2ymyI1sZEdXI4igS0QYlxj6z8ojgChDaJYWZI0i
+                Zzibl+QhMhtBDD0hdOMKg9d6qZDuTAdSO1AawTVcD5PFGwzXj9P2lT1RPqzc
+                YKe6sB1qOWq7DNda654sKxXZrloMxY71z59muuOW6Gu3bmuqJc3VA3iLdmeJ
+                dodl2CVLN8bVWr1K3I3kRnMRJJAUcQtvR+CDX4SA2wxiUk1WkhuKNVendPIM
+                YZeVcj2pblNy8rqpV21LWTqxua+4sNblIMYZbrZbaaW3vdEmcxHcccPLMPhd
+                chm+7EBm4diOr9hayX1Hcg0p05nXn9/MwaPxtupuYRR666zd7OsR9Gq6XGRn
+                Okfqf8QJngliKohJhqFOqdPR1Eo4Q3dTZ0GxZDrpZAIJtW0PHYmMP0L8AdoQ
+                W1wQaHFH5VKapDKV5e+DvVviwZ4o3BCa3fHWnAp6exPRg71eIc1S1CauR4Xe
+                npg3JqS9ztOX9rz6yS8E/b0jx2HBoBAN0CjoSCEu/bnPDvYI6w2K0TAZFc5l
+                UzifyUg0/OpbISD6gq9+HEwznuMEQ6zJ0XEmb3WuMkPyPIXmp0zDwfyOxXV1
+                relpZbeuEGDgDGd1Wh8+3zEaQIHOX9ft3S2qfqrQ7noo6rZRUuaUdXvjMCBy
+                4tuWq7bCGCsuPHkmHloRnzomxFRxqCnlxLGhzNAR4j9cq6Q5MTRXb6t1lDLh
+                UgUxk8jcydyfzogPExPTmSm3e3AUiJPBm0XDvaQTGW49k+E9mZ+nK9M7q5cV
+                hssFVVMW7dq6YqzI61WF7xW9JFdXZUPl48Zk37KtWWpNyWvbqqnS1JOj25s2
+                ycnVwyu4BdZVtOTS1oJcbxgNFdUNTbZsg+RIXtMUY7Yqm6ZCUNGtYE7luCvt
+                yskQb3hdPRURMnTievlrDz/i/IaAB8s0ek7z/N3vScVC+7ic+hVXD9D9G+IC
+                fuGHA4qOCp1LELFC8pALRy/6HHM96McArXNpkCQBHzc0AtSvUgt7GgP6RUO4
+                SSaY4/t7MsXnxwe83/yAqGfK55nyX/V9t4/huQHfyan5VCK5jxEelQef0NML
+                oSfmxHeNEgLFF0GUohDJRRTDjXhThItQPKMk+RGi/xhJPsI05/oP5+L8bjpN
+                zN0OxIRbiJEuSkz6jYiZeD0xYSKgm6IIU9LdREz4AsRM0te01wlugTIRqI+n
+                Yg+ImLHYO2fSwz8kV5xQHCUEG/Rwkw9p/VMHff8UOV1CY+A+45i+eARdLRGM
+                XywCH144m4yR/276dI3jM0dxEWsE+f8AxedExzLRkyWqHq3Bk8e7eczk8R4e
+                5/EE7+cxi7k1MBPzyK2hy8S0iT4TkyY+MPGhibyJj0z0m3hqYtDEHRN+k2zx
+                ulwiu0vUnjn6z/8FFIb9PeENAAA=
                 """
     )
 
@@ -96,7 +98,7 @@
     private val AnotherOffsetDefinitionStub = kotlinAndBytecodeStub(
         filename = "InitialTestPackage.kt",
         filepath = "initial/test/pack",
-        checksum = 0xd4dfae47,
+        checksum = 0xceabfb36,
         source = """
             package initial.test.pack
 
@@ -123,66 +125,66 @@
         """,
         """
                 META-INF/main.kotlin_module:
-                H4sIAAAAAAAAAGNgYGBmYGBgBGJ2KM3AJc0lmJiXX5KRWqRXklpcoleQmJwt
-                xBYCZHqXcGlyCWbmZZZkJuYgSYp4QoRAagKAAonpqd4lSgxaDACYtrgJYAAA
+                H4sIAAAAAAAA/2NgYGBmYGBgBGJOBijgkuYSTMzLL8lILdIrSS0u0StITM4W
+                YgsBMr1LuDS5BDPzMksyE3OQJEU8IUIgNQFAgcT0VO8SJQYtBgDlWnMBYAAA
                 AA==
                 """,
         """
                 initial/test/pack/AnotherClass.class:
-                H4sIAAAAAAAAAIVU308cVRT+7sz+mB0WmIVCKay0yorL0nYAW62FooBWBgFJ
-                aYgVXy674zIwzKwzd4m+GJ76JzTRFxNjfOKhJgrGJg1t3/ybjPHcnemCC4Fk
-                5txzz5zzne+ce+78/e9fzwHcwjLDoOM5wuGuKexQmDVe3jZnPF9s2sGcy8Mw
-                DcZgbPFdbrrcq5qfb2zZZZGGypCakqHTDImiNbLGoBZH1rJIIq0jAY1BqwV+
-                zQ7EdwzMykJHWwYKsuQvNp2Q4dri+aknGdqqtlhpolACi0Ev+zs137M9MU5Q
-                Zb9GX4aIwcVoQ4t+UDW3bLERcMcLTe7Rdy4cn/RlXyzXXXdSFpDSiWcvQ1aC
-                Fyr217zuCoa14kUpLGuxtVOTF/LKohuXZMZ+apnwV0XgeFWGS8WRE2CRlWq4
-                3GqbrTtuxQ7SGNRxVba99yR68fUZ3NPwJh0Zr9Vsr8Jwo3ga/HS+GJsoDqEg
-                4d9myMtWn+f4jnQsSse58x1L0nE0izzekNoNKn+Th5tzfsVmyB1HWp6wq7LC
-                sWjUaJZMTOgYx7tUkf1Nnbs0TT3FM3r/JUPhvEOnE+cbrk19TTZ6xtB1GoXI
-                LG77wnU8c8kWvMIFJ5uys6vSHWJSpGnCt8n0rSN3RFOp0Gz+crQ3qCt9iq4Y
-                R3s6PYqh6YqWorWNVpXWDu3lY63vaG9CGWOz7V0pQ+lXxtSXP6cUI7GQMdJy
-                N//qsbrQbWikk6OmKZETmRmZM6TrE5rR1p/oY2Ns/tUTlQKzkccTRno76R1S
-                f5BrwmtEpz+hJY2U5DrBqA70WNGcPqQxXaEp5VX75jaNfSI6kE6aY3u5vrNh
-                Bw9lz2Sr/DJ313jgyH1sHHhQ94SzY1verhM6ZJo57jdD+6og5CVei70Lrd4r
-                POA7trCD/4Xpq349KNv3HRlzJY5ZO4VPE6HQr0cW0yV/N6RppNOFJnmfdtP0
-                XaFVLx0iUxr4A+2/0U7BpySlD9CBeZK9kRftOoGGJtFoDmDQG2GZtMqIZOl3
-                tO+fCZONHGKYHJF6HTzUGszODKAfA8HKgHGoDU6ZZ1AeDRzi8tNmUEQ20ySb
-                iclaMZsewMigD1fi3MNxk3L5xPc/QJMMpkoDBxiIIBdIqmASgS5mnP4urZJa
-                /hmuPjrEta63DjAsIw8wYowc4PoBbj5tKSMfMzrBg6TZ7MFw3IMGgz9xq7UN
-                WhzPcBvvxTy+olVesUJp9FckE/ujL6D8iKS6P3oEZUkCXaf3J2lJRGey0Dg+
-                Na39g1ya9scdKzQ7VsAdfEB5PouvMt5vhC425CdYovULst6lk5lch2physI9
-                kpiW4kMLH2FmHSzELObW0RnK5+MQekOmQhghciG6QnSHuN0w3glhhsiT/h8X
-                5RN2iwcAAA==
+                H4sIAAAAAAAA/4VU30/cRhD+1r4fPnOADwIhcCVpudLjSGKgSZsGkhZoU0yA
+                oBChpvRluXMPg7Gv9h5qXyqe8idEal8qVVWfeEilFqpGikjy1r+pqjp7dg56
+                IJDsmdnxzLffzsz673//egHgBh4wDDqeIxzumsIOhVnj5S1z2vPFhh3MujwM
+                02AMxibf4abLvar5YH3TLos0VIbUlEy9y5AoWiOrDGpxZDWLJNI6EtAYtFrg
+                1+xAfMfArCx0tGWgIEvxYsMJGa4snL31JENb1RbLTRTawGLQy/52zfdsT4wT
+                VNmv0ZchYnA+2tCCH1TNTVusB9zxQpN79J0Lxyd7yRdLddedlAdI6cSzlyEr
+                wQsV+2tedwXDavG8LSxrobVSk+fyyqIbF+SO/VQy4a+IwPGqDBeKI8fAIi+d
+                4WKrb6buuBU7SGNQx2VZ9t7j6MU3Pbij4W1qGa/VbK/CcK14EvzkfjE2URxC
+                QcK/y5CXpT4r8D0ZWJSBs2cHlmTgaBZ5vCWta3T8DR5uzPoVmyF3lGl5wq7K
+                E45Fo0azZGJCxzjepxPZ39S5S9PUUzyl9l8yFM5qOnWcr7s21TXZqBlD10kU
+                IrOw5QvX8cxFW/AKF5x8yvaOSneISZGRAjTmW+T/1pEr4qpUaEB/Odwd1JU+
+                RVeMw12dHsXQdEVLkW4jrZLu0F490foOdyeUMTbT3pUylH5lTH31c0oxEvMZ
+                Iy1Xc6+fqPPdhkY2BWqaEgWRm5E7Q7Y+oRlt/Yk+NsbmXj9VKTEbRTxlZLeT
+                3SHth7kmvEZ0+hNa0khJrhNMnqDHiob1Ec3qMo0qr9rXt2j2E1FXOmmY7aX6
+                9rodPJKFk/Xyy9xd5YEj17Fz4GHdE862bXk7TuiQa/qo6AztK4KQF3ktji60
+                Ri/zgG/bwg7+l6av+PWgbN9zZM6lOGf1BD6NhUL/H3mYLvnPIUsjm241yc9p
+                dZe+K6T10gEypYE/0P4brRTMkZQxQAcskr1RFK06ZXfJkmg0DDDojbBM2XTS
+                ydLvaN87FSYbBcQwOSL1JnmoNZmdmkB/B4KVCeNQG5wyz6E8HjjAxWfNpIhs
+                pkk2E5Odj9n0AEYGfbgU7z0cFymXT3z/AzTJYKo0sI+BCPI+SRVMItDtjLe/
+                TVpSyz/H5ccHuNL1zj6GZeY+RoyRfVzdx/VnLcfIx4yO8SBpNmswHNegweBP
+                3GgtgxbnM9zEBzGPr0jLK1Yojf6KZGJv9CWUH5FU90YPoSxKoKv0/iQ9iagn
+                9xvtU9PaP8ilaX1UsUKzYgXcwke0zwLZaUnqw0bqYkPewxLpL8h7mzozuQbV
+                wpSFOxZN08dk4hML05hZAwsxi0/X0BnK57MQekOmQhghciG6QnSHuNlw3gph
+                hsiT/R+xoJVLkAcAAA==
                 """,
         """
                 initial/test/pack/InitialTestPackageKt.class:
-                H4sIAAAAAAAAAJVRXU8TQRQ9M4W2LghtbZUWRJQCbR9cIL5VTQiJcUMFIqQv
-                fXG6Hdppt7tmZ9rgGz/IH2B8MDz7o4x3aFWEGHWSuffcc7/mzv367fMXAM9Q
-                Y9hUoTJKBK6R2rjvhT9wvQlzSsQx2aIrD0wKjCHTF2PhBiLsukftvvSJTTAk
-                o7MzLQ3DRqVxu9heGJmejPcDoXXd86oew3ojirtuX5p2LFSoXRFSjDAqInwY
-                mcNRENSp7HPTU/plGmmG1UFkAhW6/fHQVaGRcUg9vNDElK58nYLDUPB70h9M
-                849FLIaSAhm2Ko2bz65fY05skW692pzHPO46mMMCw3zZ9i7/GGztb3MxsHO6
-                NBv7wLAg2joKRkYeTfPzk3I36WxjOtYbaURHGEF1+HCcoNUwK1JUbmABJ/5c
-                WbRNqLPDcHB5seBcXjg8k3b4End4OlEqZS4vSnyb1fg2301mEhaTnrGanLN/
-                8tmSu4x6onB7808H9NCZ/agjGRbpG+ThaNiW8aloB8TkGpEvgqaIlbWnZPnt
-                KDRqKL1wrLQi6ucy9n4tmsE5iUaxL18pm1Oc5jQnGdcCsQOOGdjDUcQskqTL
-                ZL0mbb/EqeXufMLi8sq7j1cxGySTNEwSWWwSXptEIUM2rlAO98hvUZ4Qxxbh
-                uQRRKUxOEYX/aFP4rc39f2/DUbmS66iSfkGeBzTfUgsJD0UPJZJY9rCChx5W
-                8agFpqnN4xaSGgWNJxpZjZxGXmP2O5cbQQjTAwAA
+                H4sIAAAAAAAA/5VR328SQRD+9qCUXmtLEbTQWtHSFjDxaOMbatI0MV6KbWMb
+                XnhxObawcNyZ24XUN/4g/wDjg+mzf5RxFlBrG6NecjPffPNrZ+brt89fADzD
+                E4YdGUgtue9oobTznnt9x50y50Scks074kjPgzGkenzEHZ8HHeek1RMesTGG
+                RHhxoYRm2C7Vbxc7CELdFdGhz5WquW7ZZdiqh1HH6QndirgMlMMDiuFahoSP
+                Q3089P0alX2uu1K9TCLJsNkPtS8DpzcaODLQIgqohxvoiNKlp+ZhM2S9rvD6
+                s/xTHvGBoECG3VL95rNr15gzU6RTKzeWsIQ7NhaxzLBUNL2LPwYr/G0uBnZJ
+                P83GPjAs85YK/aEWJ7P8zLTcTXq1PhvrjdC8zTWnOtZgFKPTMCMWjADV7Btg
+                kfNSGlQl1N5jOLoaL9tXY9tKJW1rzbKtZCyfT12N81aVVayqtZ9IxQwmHTea
+                nHN/8pmS+8x0y94+/9M+vTZ+GLYFwwrtQhwPBy0RnfOWT0y6Hnrcb/BIGntG
+                Ft8OAy0Hwg1GUkmifl7k4Ne1GeyzcBh54pU0OblZTmOacS0Qe7AQN9sgncMc
+                EqS3yXpN2qzErqQXPmFlfePdx0nMDskEDZPAKnYJF6ZRSJGNCUrjLvkNyhCy
+                UCK8GCNqHtMvh+x/tMn+1ubev7exUJ7IIiqkX5DnPs231kTMRc5F3sU6Nlw8
+                wKaLhyg0wRQe4XETCYWswpbCqkJaIaMw9x0Y3G4V2AMAAA==
                 """,
         """
                 initial/test/pack/OffsetClass.class:
-                H4sIAAAAAAAAAI1QPW8TQRB9u/dhc/nwOYTgfBGgSig4x6IDRSKWIl1kMILI
-                FG5Y25uw8fkOeddR6PxbqGlSRaKILEp+FGL2fFUUoZx082bezLzZmT9/f90A
-                eIXnDNsqVUaJJDJSm+ib6A+j9umplqaZCK1LYAzhubgQUSLSs6jdO5d9U4LD
-                4L+xnQcMzu5eZxEe/AAuSgyu+ao0w07rv8qvSSHLQwZvN473YgZ2Sb/F7wzL
-                oqezZGJkuyiqtoaZSVQavZNGDIQRpMBHFw4twqyhyWxI1KWyUZ28wT7D59l0
-                NeA1HvBwNg142TplQqc2mzZ4nR16v3/4POTHa6Gzwetuww+9An2LxJfu4q18
-                g9FoPIrna57Qlh9oSXEmXw7pvW4zG0iGCp1Bvp+MenJ8InoJMSutrC+Sjhgr
-                Gxdk8CmbjPvySNlg/eMkNWokO0oryr5N08wIo7JUYx+crmw/h2bT0cluUxQR
-                0nPgvbhG+Yocjidk/Zx0sUN2cV6ABwgIq1jIGdt8SNX2aO7m1peft3r9vPfp
-                PF/0Wm8Jy4V2hTxOeuG99IJ76nGqsZ1beEbYpFyV3r7ShRPjYYxVsnR6Mmsx
-                HqPWBdNYx0YXZY1AY1PD1whzZ0mjorHwDymQrhH2AgAA
+                H4sIAAAAAAAA/41QPW8TQRB9u/dh5/Lhc0iC80UCNAkF51jpQEjEEtIhgxFE
+                pnDD2t6Ejc93yLuOQuffQp2GKlIKZFHyoxCz56sQQjnpZt682fd2Z379vv0B
+                4BiPGXZVqowSSWSkNtEX0R9G7bMzLU0zEVqXwBjCC3EpokSk51G7dyH7pgSH
+                wX9ulS8YnIPDzhI8+AFclBhc81lphr3Wf52fkUOWlwzeQRwfxgzsin6bvzKs
+                iJ7OkomR7eJQtTXMTKLS6I00YiCMIAc+unRoEGbDgg0g8ZD4K2WrOqHBEcPH
+                2XQt4DUe8HA2DXjZgjJlpzabNnidnXg/v/k85K83QmeL192GH3pF9m0mvvQv
+                3to3mL10PZ7PekqjvqNJxbl8OqRHu81sIBkqtAv5djLqyfGp6CXErLayvkg6
+                YqxsXZDBh2wy7stXyhab7yepUSPZUVpR92WaZkYYlaUaR+C0avs5dDdtnuID
+                qiI7PmXvyQ3K3wlw7FH0c9LFPsWl+QEsIKBcxWLOWPEJnbZLc7d3Pl3/pfVz
+                7f68X2gtWsZK4V0hxMkvvJNfcEc/joe5chePKDepV6W3r3bhxLgXYy3GOjYI
+                4n6MGja7YBpb2O6irBFo7Gj4GmEOljUqGot/AARrj8f7AgAA
                 """
     )
     // common_typos_enabled
@@ -190,26 +192,32 @@
     private val DensityStub: TestFile = bytecodeStub(
         filename = "Density.kt",
         filepath = "androidx/compose/ui/unit",
-        checksum = 0xaa534a7a,
+        checksum = 0xeb800aa8,
         """
             package androidx.compose.ui.unit
 
-            interface Density
+            interface Density {
+                val density: Float
+                val fontScale: Float
+            }
         """,
         """
-        META-INF/main.kotlin_module:
-        H4sIAAAAAAAAAGNgYGBmYGBgBGJWKM3ApcIlnpiXUpSfmVKhl5yfW5BfnKpX
-        mqmXlp8vxOmWn++SWJLoXaLEoMUAAALEmjo+AAAA
-        """,
+                META-INF/main.kotlin_module:
+                H4sIAAAAAAAA/2NgYGBmYGBgBGJOBijg0uNSSsxLKcrPTKnQS87PLcgvTtVL
+                yy/NS0ksyczP08tJrMwvLRHi8E9LK04t8S7hUuCSwFBfmqlXmpdZIsTiUgBU
+                wcfFUpJaXCLEFgIkvUuUGLQYAPzR4e16AAAA
+                """,
         """
-        androidx/compose/ui/unit/Density.class:
-        H4sIAAAAAAAAAIVOTUvDQBB9s7FNjV+pH1Bv4g9w2+LNkyBCoCIoeMlpm6yy
-        Tbor3U2pt/4uD9KzP0qcqHdn4M17M/DefH69fwC4xDHhTNly4Uy5koWbvzqv
-        ZWNkY02QN9p6E95iECGdqaWStbIv8n4600WIERH6k8qF2lh5p4MqVVBXBDFf
-        RuxNLXQIVPFqZVo1ZFaOCCebdS8RA5GIlNnzYLMeiyG1xzHhfPLfP5wBQvKn
-        LqrA4tE1i0LfmloTTh8aG8xcPxlvprW+ttYFFYyzvssZ2MJvCRz+YB9HPEds
-        2eHu5ogyxBl6jNhuIcmwg90c5LGH/RzC48Aj/QaMxaG1RAEAAA==
-        """
+                androidx/compose/ui/unit/Density.class:
+                H4sIAAAAAAAA/4VPTUtCQRQ9M+/Tl9XTvtRVtKpNz6RdqyiEB0agEIGr0TfK
+                pM4LZ57Yzt/Soh/RIsRlPyqaJ0bQJhjOvffcw5x7Pr/ePwBcokZwzGQyTUUy
+                j/rp5DlVPMpElEmho1suldAvHghB+MRmLBozOYzue0+8rz1YBMGQ642KwDo9
+                axIUDdVMpe702ZgTlFqjVI+FjO64ZgnT7IqATmaWcSc5FHIAARkZfi7yqW66
+                5IKgtVyUA1qhAQ2Xi8A8GnoB9W1/UFkuGrRO2uWQ1mjdely92atX163Zvh06
+                hnX/sF7o5H82CE5a/6U195lzvOQnVWHwGybYaM5H2gydNJv2eVPkm2o7k1pM
+                +INQojfm11KmmmmRSuUaZ9h5SFCbwIELmOrl1WwqazxC1dQbY+wbRaELK0YQ
+                YytGEdumxU6MXYRdEIUSyl34CnsK+woHa3QUXIVDBe8bGvQ5CNoBAAA=
+                """
     )
 
     override fun getDetector(): Detector = NonLambdaOffsetModifierDetector()
@@ -217,7 +225,6 @@
     override fun getIssues(): MutableList<Issue> =
         mutableListOf(NonLambdaOffsetModifierDetector.UseOfNonLambdaOverload)
 
-    @Ignore("b/309832115")
     @Test
     fun lambdaOffset_simpleUsage_shouldNotWarn() {
         lint().files(
@@ -253,7 +260,6 @@
             .expectClean()
     }
 
-    @Ignore("b/309832115")
     @Test
     fun lambdaOffset_withStateUsages_shouldNotWarn() {
         lint().files(
@@ -303,7 +309,6 @@
             .expectClean()
     }
 
-    @Ignore("b/309832115")
     @Test
     fun lambdaOffset_withAnimatableUsage_shouldNotWarn() {
         lint().files(
@@ -358,7 +363,6 @@
             .expectClean()
     }
 
-    @Ignore("b/309832115")
     @Test
     fun nonLambdaOffset_usingVariableDp_shouldNotWarn() {
         lint().files(
@@ -402,7 +406,6 @@
             .expectClean()
     }
 
-    @Ignore("b/309832115")
     @Test
     fun nonLambdaOffset_usingPassedStaticArguments_shouldNotWarn() {
         lint().files(
@@ -439,7 +442,6 @@
 
     // State tests
 
-    @Ignore("b/309832115")
     @Test
     fun nonLambdaOffset_usingStateLocalVariable_shouldWarn() {
         lint().files(
@@ -486,7 +488,6 @@
             )
     }
 
-    @Ignore("b/309832115")
     @Test
     fun nonLambdaOffset_usingDelegatedStateVariable_shouldWarn() {
         lint().files(
@@ -534,7 +535,6 @@
             )
     }
 
-    @Ignore("b/309832115")
     @Test
     fun nonLambdaOffset_usingStateReceiver_shouldWarn() {
         lint().files(
@@ -593,7 +593,6 @@
             )
     }
 
-    @Ignore("b/309832115")
     @Test
     fun nonLambdaOffset_usingTopLevelStateVariables_shouldWarn() {
         lint().files(
@@ -640,7 +639,6 @@
             )
     }
 
-    @Ignore("b/309832115")
     @Test
     fun nonLambdaOffset_usingClassPropertiesState_shouldWarn() {
         lint().files(
@@ -689,7 +687,6 @@
             )
     }
 
-    @Ignore("b/309832115")
     @Test
     fun nonLambdaOffset_usingLambdaMethodWithState_shouldWarn() {
         lint().files(
@@ -736,7 +733,6 @@
             )
     }
 
-    @Ignore("b/309832115")
     @Test
     fun nonLambdaOffset_usingStateArgumentsHoisted_shouldWarn() {
         lint().files(
@@ -782,7 +778,6 @@
             )
     }
 
-    @Ignore("b/309832115")
     @Test
     fun nonLambdaOffset_usingStateVariableWithSecondaryMethodCallNoStateInSignature_shouldWarn() {
         lint().files(
@@ -835,7 +830,6 @@
             )
     }
 
-    @Ignore("b/309832115")
     @Test
     fun nonLambdaOffset_usingStateVariableWithSecondaryMethodCallStateInSignature_shouldWarn() {
         lint().files(
@@ -889,7 +883,6 @@
             )
     }
 
-    @Ignore("b/309832115")
     @Test
     fun nonLambdaOffset_usingDelegatedStateVariableWithComplexExpression_shouldWarn() {
         lint().files(
@@ -939,7 +932,6 @@
 
     // Animatable tests
 
-    @Ignore("b/309832115")
     @Test
     fun nonLambdaOffset_usingAnimatableArgumentsLocalVariable_shouldWarn() {
         lint().files(
@@ -985,7 +977,6 @@
             )
     }
 
-    @Ignore("b/309832115")
     @Test
     fun nonLambdaOffset_usingAnimatableArgumentsHoisted_shouldWarn() {
         lint().files(
@@ -1030,7 +1021,6 @@
             )
     }
 
-    @Ignore("b/309832115")
     @Test
     fun nonLambdaOffset_usingAnimatableReceiver_shouldWarn() {
         lint().files(
@@ -1090,7 +1080,6 @@
             )
     }
 
-    @Ignore("b/309832115")
     @Test
     fun nonLambdaOffset_usingLambdaMethodWithAnimatable_shouldWarn() {
         lint().files(
@@ -1138,7 +1127,6 @@
             )
     }
 
-    @Ignore("b/309832115")
     @Test
     fun nonLambdaOffset_usingTopLevelAnimatableVariables_shouldWarn() {
         lint().files(
@@ -1186,7 +1174,6 @@
             )
     }
 
-    @Ignore("b/309832115")
     @Test
     fun nonLambdaOffset_usingClassPropertiesAnimatable_shouldWarn() {
         lint().files(
@@ -1236,7 +1223,6 @@
             )
     }
 
-    @Ignore("b/309832115")
     @Test
     fun nonLambdaOffset_usingAnimatableVariableWithComplexExpression_shouldWarn() {
         lint().files(
@@ -1282,7 +1268,6 @@
             )
     }
 
-    @Ignore("b/309832115")
     @Test
     fun nonLambdaOffset_animatableVariableWithSecondaryMethodCallNoStateInSignature_shouldWarn() {
         lint().files(
@@ -1335,7 +1320,6 @@
             )
     }
 
-    @Ignore("b/309832115")
     @Test
     fun nonLambdaOffset_usingAnimatableArgumentsWithMethodCallStateInSignature_shouldWarn() {
         lint().files(
@@ -1390,7 +1374,6 @@
 
     // Non modifier related tests
 
-    @Ignore("b/309832115")
     @Test
     fun nonModifierOffset_bytecode_shouldNotWarn() {
         lint().files(
@@ -1415,7 +1398,6 @@
             .expectClean()
     }
 
-    @Ignore("b/309832115")
     @Test
     fun nonModifierOffsetKotlin_shouldNotWarn() {
         lint().files(
diff --git a/compose/foundation/foundation/api/current.ignore b/compose/foundation/foundation/api/current.ignore
index b3ba5ff8..022ce06 100644
--- a/compose/foundation/foundation/api/current.ignore
+++ b/compose/foundation/foundation/api/current.ignore
@@ -3,6 +3,14 @@
     Added method androidx.compose.foundation.pager.PageInfo.getKey()
 
 
+ChangedType: androidx.compose.foundation.gestures.snapping.SnapFlingBehaviorKt#rememberSnapFlingBehavior(androidx.compose.foundation.gestures.snapping.SnapLayoutInfoProvider):
+    Method androidx.compose.foundation.gestures.snapping.SnapFlingBehaviorKt.rememberSnapFlingBehavior has changed return type from androidx.compose.foundation.gestures.snapping.SnapFlingBehavior to androidx.compose.foundation.gestures.TargetedFlingBehavior
+
+
+ParameterNameChange: androidx.compose.foundation.gestures.snapping.SnapFlingBehavior#performFling(androidx.compose.foundation.gestures.ScrollScope, float, kotlin.jvm.functions.Function1<? super java.lang.Float,kotlin.Unit>, kotlin.coroutines.Continuation<? super java.lang.Float>) parameter #2:
+    Attempted to change parameter name from onSettlingDistanceUpdated to onRemainingDistanceUpdated in method androidx.compose.foundation.gestures.snapping.SnapFlingBehavior.performFling
+
+
 RemovedClass: androidx.compose.foundation.lazy.layout.LazyLayoutItemProviderKt:
     Removed class androidx.compose.foundation.lazy.layout.LazyLayoutItemProviderKt
 RemovedClass: androidx.compose.foundation.text2.input.AllCapsTransformationKt:
diff --git a/compose/foundation/foundation/api/current.txt b/compose/foundation/foundation/api/current.txt
index 202b7fa..921ab43 100644
--- a/compose/foundation/foundation/api/current.txt
+++ b/compose/foundation/foundation/api/current.txt
@@ -324,7 +324,16 @@
   }
 
   public final class ReceiveContentKt {
-    method @SuppressCompatibility @androidx.compose.foundation.ExperimentalFoundationApi public static androidx.compose.ui.Modifier receiveContent(androidx.compose.ui.Modifier, androidx.compose.foundation.content.MediaType[] acceptedMediaTypes, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.content.TransferableContent,androidx.compose.foundation.content.TransferableContent?> onReceive);
+    method @SuppressCompatibility @androidx.compose.foundation.ExperimentalFoundationApi public static androidx.compose.ui.Modifier receiveContent(androidx.compose.ui.Modifier, java.util.Set<androidx.compose.foundation.content.MediaType> hintMediaTypes, androidx.compose.foundation.content.ReceiveContentListener receiveContentListener);
+    method @SuppressCompatibility @androidx.compose.foundation.ExperimentalFoundationApi public static androidx.compose.ui.Modifier receiveContent(androidx.compose.ui.Modifier, java.util.Set<androidx.compose.foundation.content.MediaType> hintMediaTypes, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.content.TransferableContent,androidx.compose.foundation.content.TransferableContent?> onReceive);
+  }
+
+  @SuppressCompatibility @androidx.compose.foundation.ExperimentalFoundationApi public interface ReceiveContentListener {
+    method public default void onDragEnd();
+    method public default void onDragEnter();
+    method public default void onDragExit();
+    method public default void onDragStart();
+    method public androidx.compose.foundation.content.TransferableContent? onReceive(androidx.compose.foundation.content.TransferableContent transferableContent);
   }
 
   @SuppressCompatibility @androidx.compose.foundation.ExperimentalFoundationApi public final class TransferableContent {
@@ -619,25 +628,24 @@
 package androidx.compose.foundation.gestures.snapping {
 
   public final class LazyGridSnapLayoutInfoProviderKt {
-    method @SuppressCompatibility @androidx.compose.foundation.ExperimentalFoundationApi public static androidx.compose.foundation.gestures.snapping.SnapLayoutInfoProvider SnapLayoutInfoProvider(androidx.compose.foundation.lazy.grid.LazyGridState lazyGridState, optional androidx.compose.foundation.gestures.snapping.SnapPosition snapPosition);
+    method public static androidx.compose.foundation.gestures.snapping.SnapLayoutInfoProvider SnapLayoutInfoProvider(androidx.compose.foundation.lazy.grid.LazyGridState lazyGridState, optional androidx.compose.foundation.gestures.snapping.SnapPosition snapPosition);
   }
 
   public final class LazyListSnapLayoutInfoProviderKt {
-    method @SuppressCompatibility @androidx.compose.foundation.ExperimentalFoundationApi public static androidx.compose.foundation.gestures.snapping.SnapLayoutInfoProvider SnapLayoutInfoProvider(androidx.compose.foundation.lazy.LazyListState lazyListState, optional androidx.compose.foundation.gestures.snapping.SnapPosition snapPosition);
-    method @SuppressCompatibility @androidx.compose.foundation.ExperimentalFoundationApi @androidx.compose.runtime.Composable public static androidx.compose.foundation.gestures.FlingBehavior rememberSnapFlingBehavior(androidx.compose.foundation.lazy.LazyListState lazyListState);
+    method public static androidx.compose.foundation.gestures.snapping.SnapLayoutInfoProvider SnapLayoutInfoProvider(androidx.compose.foundation.lazy.LazyListState lazyListState, optional androidx.compose.foundation.gestures.snapping.SnapPosition snapPosition);
+    method @androidx.compose.runtime.Composable public static androidx.compose.foundation.gestures.FlingBehavior rememberSnapFlingBehavior(androidx.compose.foundation.lazy.LazyListState lazyListState);
   }
 
-  @SuppressCompatibility @androidx.compose.foundation.ExperimentalFoundationApi public final class SnapFlingBehavior implements androidx.compose.foundation.gestures.TargetedFlingBehavior {
-    ctor @Deprecated public SnapFlingBehavior(androidx.compose.foundation.gestures.snapping.SnapLayoutInfoProvider snapLayoutInfoProvider, androidx.compose.animation.core.AnimationSpec<java.lang.Float> lowVelocityAnimationSpec, androidx.compose.animation.core.DecayAnimationSpec<java.lang.Float> highVelocityAnimationSpec, androidx.compose.animation.core.AnimationSpec<java.lang.Float> snapAnimationSpec);
+  public final class SnapFlingBehavior implements androidx.compose.foundation.gestures.TargetedFlingBehavior {
     ctor public SnapFlingBehavior(androidx.compose.foundation.gestures.snapping.SnapLayoutInfoProvider snapLayoutInfoProvider, androidx.compose.animation.core.DecayAnimationSpec<java.lang.Float> decayAnimationSpec, androidx.compose.animation.core.AnimationSpec<java.lang.Float> snapAnimationSpec);
     method public suspend Object? performFling(androidx.compose.foundation.gestures.ScrollScope, float initialVelocity, kotlin.jvm.functions.Function1<? super java.lang.Float,kotlin.Unit> onRemainingDistanceUpdated, kotlin.coroutines.Continuation<? super java.lang.Float>);
   }
 
   public final class SnapFlingBehaviorKt {
-    method @SuppressCompatibility @androidx.compose.foundation.ExperimentalFoundationApi @androidx.compose.runtime.Composable public static androidx.compose.foundation.gestures.TargetedFlingBehavior rememberSnapFlingBehavior(androidx.compose.foundation.gestures.snapping.SnapLayoutInfoProvider snapLayoutInfoProvider);
+    method @androidx.compose.runtime.Composable public static androidx.compose.foundation.gestures.TargetedFlingBehavior rememberSnapFlingBehavior(androidx.compose.foundation.gestures.snapping.SnapLayoutInfoProvider snapLayoutInfoProvider);
   }
 
-  @SuppressCompatibility @androidx.compose.foundation.ExperimentalFoundationApi public interface SnapLayoutInfoProvider {
+  public interface SnapLayoutInfoProvider {
     method public default float calculateApproachOffset(float initialVelocity);
     method public float calculateSnappingOffset(float currentVelocity);
   }
@@ -1254,16 +1262,16 @@
   }
 
   @SuppressCompatibility @androidx.compose.foundation.ExperimentalFoundationApi public final class PagerDefaults {
-    method @Deprecated @androidx.compose.runtime.Composable public androidx.compose.foundation.gestures.snapping.SnapFlingBehavior flingBehavior(androidx.compose.foundation.pager.PagerState state, optional androidx.compose.foundation.pager.PagerSnapDistance pagerSnapDistance, optional androidx.compose.animation.core.AnimationSpec<java.lang.Float> lowVelocityAnimationSpec, optional androidx.compose.animation.core.DecayAnimationSpec<java.lang.Float> highVelocityAnimationSpec, optional androidx.compose.animation.core.AnimationSpec<java.lang.Float> snapAnimationSpec, optional float snapPositionalThreshold);
-    method @androidx.compose.runtime.Composable public androidx.compose.foundation.gestures.snapping.SnapFlingBehavior flingBehavior(androidx.compose.foundation.pager.PagerState state, optional androidx.compose.foundation.pager.PagerSnapDistance pagerSnapDistance, optional androidx.compose.animation.core.DecayAnimationSpec<java.lang.Float> decayAnimationSpec, optional androidx.compose.animation.core.AnimationSpec<java.lang.Float> snapAnimationSpec, optional @FloatRange(from=0.0, to=1.0) float snapPositionalThreshold);
+    method @Deprecated @androidx.compose.runtime.Composable public androidx.compose.foundation.gestures.TargetedFlingBehavior flingBehavior(androidx.compose.foundation.pager.PagerState state, optional androidx.compose.foundation.pager.PagerSnapDistance pagerSnapDistance, optional androidx.compose.animation.core.AnimationSpec<java.lang.Float> lowVelocityAnimationSpec, optional androidx.compose.animation.core.DecayAnimationSpec<java.lang.Float> highVelocityAnimationSpec, optional androidx.compose.animation.core.AnimationSpec<java.lang.Float> snapAnimationSpec, optional float snapPositionalThreshold);
+    method @androidx.compose.runtime.Composable public androidx.compose.foundation.gestures.TargetedFlingBehavior flingBehavior(androidx.compose.foundation.pager.PagerState state, optional androidx.compose.foundation.pager.PagerSnapDistance pagerSnapDistance, optional androidx.compose.animation.core.DecayAnimationSpec<java.lang.Float> decayAnimationSpec, optional androidx.compose.animation.core.AnimationSpec<java.lang.Float> snapAnimationSpec, optional @FloatRange(from=0.0, to=1.0) float snapPositionalThreshold);
     method public androidx.compose.ui.input.nestedscroll.NestedScrollConnection pageNestedScrollConnection(androidx.compose.foundation.pager.PagerState state, androidx.compose.foundation.gestures.Orientation orientation);
     field public static final androidx.compose.foundation.pager.PagerDefaults INSTANCE;
     field public static final int OutOfBoundsPageCount = 0; // 0x0
   }
 
   public final class PagerKt {
-    method @SuppressCompatibility @androidx.compose.foundation.ExperimentalFoundationApi @androidx.compose.runtime.Composable public static void HorizontalPager(androidx.compose.foundation.pager.PagerState state, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.pager.PageSize pageSize, optional int outOfBoundsPageCount, optional float pageSpacing, optional androidx.compose.ui.Alignment.Vertical verticalAlignment, optional androidx.compose.foundation.gestures.snapping.SnapFlingBehavior flingBehavior, optional boolean userScrollEnabled, optional boolean reverseLayout, optional kotlin.jvm.functions.Function1<? super java.lang.Integer,?>? key, optional androidx.compose.ui.input.nestedscroll.NestedScrollConnection pageNestedScrollConnection, optional androidx.compose.foundation.gestures.snapping.SnapPosition snapPosition, kotlin.jvm.functions.Function2<? super androidx.compose.foundation.pager.PagerScope,? super java.lang.Integer,kotlin.Unit> pageContent);
-    method @SuppressCompatibility @androidx.compose.foundation.ExperimentalFoundationApi @androidx.compose.runtime.Composable public static void VerticalPager(androidx.compose.foundation.pager.PagerState state, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.pager.PageSize pageSize, optional int outOfBoundsPageCount, optional float pageSpacing, optional androidx.compose.ui.Alignment.Horizontal horizontalAlignment, optional androidx.compose.foundation.gestures.snapping.SnapFlingBehavior flingBehavior, optional boolean userScrollEnabled, optional boolean reverseLayout, optional kotlin.jvm.functions.Function1<? super java.lang.Integer,?>? key, optional androidx.compose.ui.input.nestedscroll.NestedScrollConnection pageNestedScrollConnection, optional androidx.compose.foundation.gestures.snapping.SnapPosition snapPosition, kotlin.jvm.functions.Function2<? super androidx.compose.foundation.pager.PagerScope,? super java.lang.Integer,kotlin.Unit> pageContent);
+    method @SuppressCompatibility @androidx.compose.foundation.ExperimentalFoundationApi @androidx.compose.runtime.Composable public static void HorizontalPager(androidx.compose.foundation.pager.PagerState state, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.pager.PageSize pageSize, optional int outOfBoundsPageCount, optional float pageSpacing, optional androidx.compose.ui.Alignment.Vertical verticalAlignment, optional androidx.compose.foundation.gestures.TargetedFlingBehavior flingBehavior, optional boolean userScrollEnabled, optional boolean reverseLayout, optional kotlin.jvm.functions.Function1<? super java.lang.Integer,?>? key, optional androidx.compose.ui.input.nestedscroll.NestedScrollConnection pageNestedScrollConnection, optional androidx.compose.foundation.gestures.snapping.SnapPosition snapPosition, kotlin.jvm.functions.Function2<? super androidx.compose.foundation.pager.PagerScope,? super java.lang.Integer,kotlin.Unit> pageContent);
+    method @SuppressCompatibility @androidx.compose.foundation.ExperimentalFoundationApi @androidx.compose.runtime.Composable public static void VerticalPager(androidx.compose.foundation.pager.PagerState state, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.pager.PageSize pageSize, optional int outOfBoundsPageCount, optional float pageSpacing, optional androidx.compose.ui.Alignment.Horizontal horizontalAlignment, optional androidx.compose.foundation.gestures.TargetedFlingBehavior flingBehavior, optional boolean userScrollEnabled, optional boolean reverseLayout, optional kotlin.jvm.functions.Function1<? super java.lang.Integer,?>? key, optional androidx.compose.ui.input.nestedscroll.NestedScrollConnection pageNestedScrollConnection, optional androidx.compose.foundation.gestures.snapping.SnapPosition snapPosition, kotlin.jvm.functions.Function2<? super androidx.compose.foundation.pager.PagerScope,? super java.lang.Integer,kotlin.Unit> pageContent);
   }
 
   @SuppressCompatibility @androidx.compose.foundation.ExperimentalFoundationApi public sealed interface PagerLayoutInfo {
diff --git a/compose/foundation/foundation/api/restricted_current.ignore b/compose/foundation/foundation/api/restricted_current.ignore
index b3ba5ff8..022ce06 100644
--- a/compose/foundation/foundation/api/restricted_current.ignore
+++ b/compose/foundation/foundation/api/restricted_current.ignore
@@ -3,6 +3,14 @@
     Added method androidx.compose.foundation.pager.PageInfo.getKey()
 
 
+ChangedType: androidx.compose.foundation.gestures.snapping.SnapFlingBehaviorKt#rememberSnapFlingBehavior(androidx.compose.foundation.gestures.snapping.SnapLayoutInfoProvider):
+    Method androidx.compose.foundation.gestures.snapping.SnapFlingBehaviorKt.rememberSnapFlingBehavior has changed return type from androidx.compose.foundation.gestures.snapping.SnapFlingBehavior to androidx.compose.foundation.gestures.TargetedFlingBehavior
+
+
+ParameterNameChange: androidx.compose.foundation.gestures.snapping.SnapFlingBehavior#performFling(androidx.compose.foundation.gestures.ScrollScope, float, kotlin.jvm.functions.Function1<? super java.lang.Float,kotlin.Unit>, kotlin.coroutines.Continuation<? super java.lang.Float>) parameter #2:
+    Attempted to change parameter name from onSettlingDistanceUpdated to onRemainingDistanceUpdated in method androidx.compose.foundation.gestures.snapping.SnapFlingBehavior.performFling
+
+
 RemovedClass: androidx.compose.foundation.lazy.layout.LazyLayoutItemProviderKt:
     Removed class androidx.compose.foundation.lazy.layout.LazyLayoutItemProviderKt
 RemovedClass: androidx.compose.foundation.text2.input.AllCapsTransformationKt:
diff --git a/compose/foundation/foundation/api/restricted_current.txt b/compose/foundation/foundation/api/restricted_current.txt
index 719edf3..51d1012 100644
--- a/compose/foundation/foundation/api/restricted_current.txt
+++ b/compose/foundation/foundation/api/restricted_current.txt
@@ -326,7 +326,16 @@
   }
 
   public final class ReceiveContentKt {
-    method @SuppressCompatibility @androidx.compose.foundation.ExperimentalFoundationApi public static androidx.compose.ui.Modifier receiveContent(androidx.compose.ui.Modifier, androidx.compose.foundation.content.MediaType[] acceptedMediaTypes, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.content.TransferableContent,androidx.compose.foundation.content.TransferableContent?> onReceive);
+    method @SuppressCompatibility @androidx.compose.foundation.ExperimentalFoundationApi public static androidx.compose.ui.Modifier receiveContent(androidx.compose.ui.Modifier, java.util.Set<androidx.compose.foundation.content.MediaType> hintMediaTypes, androidx.compose.foundation.content.ReceiveContentListener receiveContentListener);
+    method @SuppressCompatibility @androidx.compose.foundation.ExperimentalFoundationApi public static androidx.compose.ui.Modifier receiveContent(androidx.compose.ui.Modifier, java.util.Set<androidx.compose.foundation.content.MediaType> hintMediaTypes, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.content.TransferableContent,androidx.compose.foundation.content.TransferableContent?> onReceive);
+  }
+
+  @SuppressCompatibility @androidx.compose.foundation.ExperimentalFoundationApi public interface ReceiveContentListener {
+    method public default void onDragEnd();
+    method public default void onDragEnter();
+    method public default void onDragExit();
+    method public default void onDragStart();
+    method public androidx.compose.foundation.content.TransferableContent? onReceive(androidx.compose.foundation.content.TransferableContent transferableContent);
   }
 
   @SuppressCompatibility @androidx.compose.foundation.ExperimentalFoundationApi public final class TransferableContent {
@@ -621,25 +630,24 @@
 package androidx.compose.foundation.gestures.snapping {
 
   public final class LazyGridSnapLayoutInfoProviderKt {
-    method @SuppressCompatibility @androidx.compose.foundation.ExperimentalFoundationApi public static androidx.compose.foundation.gestures.snapping.SnapLayoutInfoProvider SnapLayoutInfoProvider(androidx.compose.foundation.lazy.grid.LazyGridState lazyGridState, optional androidx.compose.foundation.gestures.snapping.SnapPosition snapPosition);
+    method public static androidx.compose.foundation.gestures.snapping.SnapLayoutInfoProvider SnapLayoutInfoProvider(androidx.compose.foundation.lazy.grid.LazyGridState lazyGridState, optional androidx.compose.foundation.gestures.snapping.SnapPosition snapPosition);
   }
 
   public final class LazyListSnapLayoutInfoProviderKt {
-    method @SuppressCompatibility @androidx.compose.foundation.ExperimentalFoundationApi public static androidx.compose.foundation.gestures.snapping.SnapLayoutInfoProvider SnapLayoutInfoProvider(androidx.compose.foundation.lazy.LazyListState lazyListState, optional androidx.compose.foundation.gestures.snapping.SnapPosition snapPosition);
-    method @SuppressCompatibility @androidx.compose.foundation.ExperimentalFoundationApi @androidx.compose.runtime.Composable public static androidx.compose.foundation.gestures.FlingBehavior rememberSnapFlingBehavior(androidx.compose.foundation.lazy.LazyListState lazyListState);
+    method public static androidx.compose.foundation.gestures.snapping.SnapLayoutInfoProvider SnapLayoutInfoProvider(androidx.compose.foundation.lazy.LazyListState lazyListState, optional androidx.compose.foundation.gestures.snapping.SnapPosition snapPosition);
+    method @androidx.compose.runtime.Composable public static androidx.compose.foundation.gestures.FlingBehavior rememberSnapFlingBehavior(androidx.compose.foundation.lazy.LazyListState lazyListState);
   }
 
-  @SuppressCompatibility @androidx.compose.foundation.ExperimentalFoundationApi public final class SnapFlingBehavior implements androidx.compose.foundation.gestures.TargetedFlingBehavior {
-    ctor @Deprecated public SnapFlingBehavior(androidx.compose.foundation.gestures.snapping.SnapLayoutInfoProvider snapLayoutInfoProvider, androidx.compose.animation.core.AnimationSpec<java.lang.Float> lowVelocityAnimationSpec, androidx.compose.animation.core.DecayAnimationSpec<java.lang.Float> highVelocityAnimationSpec, androidx.compose.animation.core.AnimationSpec<java.lang.Float> snapAnimationSpec);
+  public final class SnapFlingBehavior implements androidx.compose.foundation.gestures.TargetedFlingBehavior {
     ctor public SnapFlingBehavior(androidx.compose.foundation.gestures.snapping.SnapLayoutInfoProvider snapLayoutInfoProvider, androidx.compose.animation.core.DecayAnimationSpec<java.lang.Float> decayAnimationSpec, androidx.compose.animation.core.AnimationSpec<java.lang.Float> snapAnimationSpec);
     method public suspend Object? performFling(androidx.compose.foundation.gestures.ScrollScope, float initialVelocity, kotlin.jvm.functions.Function1<? super java.lang.Float,kotlin.Unit> onRemainingDistanceUpdated, kotlin.coroutines.Continuation<? super java.lang.Float>);
   }
 
   public final class SnapFlingBehaviorKt {
-    method @SuppressCompatibility @androidx.compose.foundation.ExperimentalFoundationApi @androidx.compose.runtime.Composable public static androidx.compose.foundation.gestures.TargetedFlingBehavior rememberSnapFlingBehavior(androidx.compose.foundation.gestures.snapping.SnapLayoutInfoProvider snapLayoutInfoProvider);
+    method @androidx.compose.runtime.Composable public static androidx.compose.foundation.gestures.TargetedFlingBehavior rememberSnapFlingBehavior(androidx.compose.foundation.gestures.snapping.SnapLayoutInfoProvider snapLayoutInfoProvider);
   }
 
-  @SuppressCompatibility @androidx.compose.foundation.ExperimentalFoundationApi public interface SnapLayoutInfoProvider {
+  public interface SnapLayoutInfoProvider {
     method public default float calculateApproachOffset(float initialVelocity);
     method public float calculateSnappingOffset(float currentVelocity);
   }
@@ -1256,16 +1264,16 @@
   }
 
   @SuppressCompatibility @androidx.compose.foundation.ExperimentalFoundationApi public final class PagerDefaults {
-    method @Deprecated @androidx.compose.runtime.Composable public androidx.compose.foundation.gestures.snapping.SnapFlingBehavior flingBehavior(androidx.compose.foundation.pager.PagerState state, optional androidx.compose.foundation.pager.PagerSnapDistance pagerSnapDistance, optional androidx.compose.animation.core.AnimationSpec<java.lang.Float> lowVelocityAnimationSpec, optional androidx.compose.animation.core.DecayAnimationSpec<java.lang.Float> highVelocityAnimationSpec, optional androidx.compose.animation.core.AnimationSpec<java.lang.Float> snapAnimationSpec, optional float snapPositionalThreshold);
-    method @androidx.compose.runtime.Composable public androidx.compose.foundation.gestures.snapping.SnapFlingBehavior flingBehavior(androidx.compose.foundation.pager.PagerState state, optional androidx.compose.foundation.pager.PagerSnapDistance pagerSnapDistance, optional androidx.compose.animation.core.DecayAnimationSpec<java.lang.Float> decayAnimationSpec, optional androidx.compose.animation.core.AnimationSpec<java.lang.Float> snapAnimationSpec, optional @FloatRange(from=0.0, to=1.0) float snapPositionalThreshold);
+    method @Deprecated @androidx.compose.runtime.Composable public androidx.compose.foundation.gestures.TargetedFlingBehavior flingBehavior(androidx.compose.foundation.pager.PagerState state, optional androidx.compose.foundation.pager.PagerSnapDistance pagerSnapDistance, optional androidx.compose.animation.core.AnimationSpec<java.lang.Float> lowVelocityAnimationSpec, optional androidx.compose.animation.core.DecayAnimationSpec<java.lang.Float> highVelocityAnimationSpec, optional androidx.compose.animation.core.AnimationSpec<java.lang.Float> snapAnimationSpec, optional float snapPositionalThreshold);
+    method @androidx.compose.runtime.Composable public androidx.compose.foundation.gestures.TargetedFlingBehavior flingBehavior(androidx.compose.foundation.pager.PagerState state, optional androidx.compose.foundation.pager.PagerSnapDistance pagerSnapDistance, optional androidx.compose.animation.core.DecayAnimationSpec<java.lang.Float> decayAnimationSpec, optional androidx.compose.animation.core.AnimationSpec<java.lang.Float> snapAnimationSpec, optional @FloatRange(from=0.0, to=1.0) float snapPositionalThreshold);
     method public androidx.compose.ui.input.nestedscroll.NestedScrollConnection pageNestedScrollConnection(androidx.compose.foundation.pager.PagerState state, androidx.compose.foundation.gestures.Orientation orientation);
     field public static final androidx.compose.foundation.pager.PagerDefaults INSTANCE;
     field public static final int OutOfBoundsPageCount = 0; // 0x0
   }
 
   public final class PagerKt {
-    method @SuppressCompatibility @androidx.compose.foundation.ExperimentalFoundationApi @androidx.compose.runtime.Composable public static void HorizontalPager(androidx.compose.foundation.pager.PagerState state, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.pager.PageSize pageSize, optional int outOfBoundsPageCount, optional float pageSpacing, optional androidx.compose.ui.Alignment.Vertical verticalAlignment, optional androidx.compose.foundation.gestures.snapping.SnapFlingBehavior flingBehavior, optional boolean userScrollEnabled, optional boolean reverseLayout, optional kotlin.jvm.functions.Function1<? super java.lang.Integer,?>? key, optional androidx.compose.ui.input.nestedscroll.NestedScrollConnection pageNestedScrollConnection, optional androidx.compose.foundation.gestures.snapping.SnapPosition snapPosition, kotlin.jvm.functions.Function2<? super androidx.compose.foundation.pager.PagerScope,? super java.lang.Integer,kotlin.Unit> pageContent);
-    method @SuppressCompatibility @androidx.compose.foundation.ExperimentalFoundationApi @androidx.compose.runtime.Composable public static void VerticalPager(androidx.compose.foundation.pager.PagerState state, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.pager.PageSize pageSize, optional int outOfBoundsPageCount, optional float pageSpacing, optional androidx.compose.ui.Alignment.Horizontal horizontalAlignment, optional androidx.compose.foundation.gestures.snapping.SnapFlingBehavior flingBehavior, optional boolean userScrollEnabled, optional boolean reverseLayout, optional kotlin.jvm.functions.Function1<? super java.lang.Integer,?>? key, optional androidx.compose.ui.input.nestedscroll.NestedScrollConnection pageNestedScrollConnection, optional androidx.compose.foundation.gestures.snapping.SnapPosition snapPosition, kotlin.jvm.functions.Function2<? super androidx.compose.foundation.pager.PagerScope,? super java.lang.Integer,kotlin.Unit> pageContent);
+    method @SuppressCompatibility @androidx.compose.foundation.ExperimentalFoundationApi @androidx.compose.runtime.Composable public static void HorizontalPager(androidx.compose.foundation.pager.PagerState state, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.pager.PageSize pageSize, optional int outOfBoundsPageCount, optional float pageSpacing, optional androidx.compose.ui.Alignment.Vertical verticalAlignment, optional androidx.compose.foundation.gestures.TargetedFlingBehavior flingBehavior, optional boolean userScrollEnabled, optional boolean reverseLayout, optional kotlin.jvm.functions.Function1<? super java.lang.Integer,?>? key, optional androidx.compose.ui.input.nestedscroll.NestedScrollConnection pageNestedScrollConnection, optional androidx.compose.foundation.gestures.snapping.SnapPosition snapPosition, kotlin.jvm.functions.Function2<? super androidx.compose.foundation.pager.PagerScope,? super java.lang.Integer,kotlin.Unit> pageContent);
+    method @SuppressCompatibility @androidx.compose.foundation.ExperimentalFoundationApi @androidx.compose.runtime.Composable public static void VerticalPager(androidx.compose.foundation.pager.PagerState state, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.pager.PageSize pageSize, optional int outOfBoundsPageCount, optional float pageSpacing, optional androidx.compose.ui.Alignment.Horizontal horizontalAlignment, optional androidx.compose.foundation.gestures.TargetedFlingBehavior flingBehavior, optional boolean userScrollEnabled, optional boolean reverseLayout, optional kotlin.jvm.functions.Function1<? super java.lang.Integer,?>? key, optional androidx.compose.ui.input.nestedscroll.NestedScrollConnection pageNestedScrollConnection, optional androidx.compose.foundation.gestures.snapping.SnapPosition snapPosition, kotlin.jvm.functions.Function2<? super androidx.compose.foundation.pager.PagerScope,? super java.lang.Integer,kotlin.Unit> pageContent);
   }
 
   @SuppressCompatibility @androidx.compose.foundation.ExperimentalFoundationApi public sealed interface PagerLayoutInfo {
diff --git a/compose/foundation/foundation/benchmark/src/androidTest/java/androidx/compose/foundation/benchmark/pager/PagerScrollingBenchmark.kt b/compose/foundation/foundation/benchmark/src/androidTest/java/androidx/compose/foundation/benchmark/pager/PagerScrollingBenchmark.kt
index 5930853..445bada 100644
--- a/compose/foundation/foundation/benchmark/src/androidTest/java/androidx/compose/foundation/benchmark/pager/PagerScrollingBenchmark.kt
+++ b/compose/foundation/foundation/benchmark/src/androidTest/java/androidx/compose/foundation/benchmark/pager/PagerScrollingBenchmark.kt
@@ -23,7 +23,6 @@
 import androidx.compose.foundation.benchmark.lazy.toggleStateBenchmark
 import androidx.compose.foundation.benchmark.lazy.toggleStateBenchmarkDraw
 import androidx.compose.foundation.gestures.scrollBy
-import androidx.compose.foundation.gestures.snapping.SnapFlingBehavior
 import androidx.compose.foundation.gestures.snapping.SnapLayoutInfoProvider
 import androidx.compose.foundation.gestures.snapping.rememberSnapFlingBehavior
 import androidx.compose.foundation.layout.Box
@@ -305,7 +304,7 @@
     { state, useKeys, beyondBoundsPageCount ->
         val flingBehavior = rememberSnapFlingBehavior(
             snapLayoutInfoProvider = NoOpInfoProvider
-        ) as SnapFlingBehavior
+        )
         VerticalPager(
             state = state, modifier = Modifier
                 .requiredHeight(400.dp)
@@ -332,7 +331,7 @@
     { state, useKeys, beyondBoundsPageCount ->
         val flingBehavior = rememberSnapFlingBehavior(
             snapLayoutInfoProvider = NoOpInfoProvider
-        ) as SnapFlingBehavior
+        )
         HorizontalPager(
             state = state, modifier = Modifier
                 .requiredWidth(400.dp)
diff --git a/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/SuspendingGesturesDemo.kt b/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/SuspendingGesturesDemo.kt
index 4a3744e..b7f7366 100644
--- a/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/SuspendingGesturesDemo.kt
+++ b/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/SuspendingGesturesDemo.kt
@@ -223,7 +223,7 @@
         ) {
             var offset by remember { mutableStateOf(0.dp) }
             Box(
-                Modifier.offset(offset, 0.dp)
+                Modifier.offset { IntOffset(x = offset.roundToPx(), y = 0) }
                     .requiredSize(50.dp)
                     .background(Color.Blue)
                     .pointerInput(Unit) {
@@ -250,7 +250,7 @@
             ) {
                 var offset by remember { mutableStateOf(0.dp) }
                 Box(
-                    Modifier.offset(0.dp, offset)
+                    Modifier.offset { IntOffset(x = 0, y = offset.roundToPx()) }
                         .requiredSize(50.dp)
                         .background(Color.Red)
                         .pointerInput(Unit) {
@@ -301,7 +301,7 @@
 
     ) {
         Box(
-            Modifier.offset(offsetX, 0.dp)
+            Modifier.offset { IntOffset(x = offsetX.roundToPx(), y = 0) }
                 .background(Color.Blue.copy(alpha = 0.5f))
                 .requiredWidth(50.dp)
                 .fillMaxHeight()
@@ -313,7 +313,7 @@
                 }
         )
         Box(
-            Modifier.offset(0.dp, offsetY)
+            Modifier.offset { IntOffset(x = 0, y = offsetY.roundToPx()) }
                 .background(Color.Red.copy(alpha = 0.5f))
                 .requiredHeight(50.dp)
                 .fillMaxWidth()
diff --git a/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/text2/ReceiveContentDemos.kt b/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/text2/ReceiveContentDemos.kt
index 7a3a941..d21d93d 100644
--- a/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/text2/ReceiveContentDemos.kt
+++ b/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/text2/ReceiveContentDemos.kt
@@ -16,14 +16,17 @@
 
 package androidx.compose.foundation.demos.text2
 
-import android.content.ClipData
 import android.content.Context
 import android.graphics.ImageDecoder
+import android.net.Uri
 import android.os.Build
 import android.provider.MediaStore
 import androidx.compose.foundation.ExperimentalFoundationApi
 import androidx.compose.foundation.Image
+import androidx.compose.foundation.background
+import androidx.compose.foundation.clickable
 import androidx.compose.foundation.content.MediaType
+import androidx.compose.foundation.content.ReceiveContentListener
 import androidx.compose.foundation.content.TransferableContent
 import androidx.compose.foundation.content.consumeEach
 import androidx.compose.foundation.content.hasMediaType
@@ -33,14 +36,17 @@
 import androidx.compose.foundation.layout.Row
 import androidx.compose.foundation.layout.Spacer
 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.foundation.rememberScrollState
+import androidx.compose.foundation.shape.RoundedCornerShape
 import androidx.compose.foundation.text2.BasicTextField2
 import androidx.compose.foundation.text2.input.TextFieldState
 import androidx.compose.foundation.verticalScroll
 import androidx.compose.material.Card
+import androidx.compose.material.Divider
 import androidx.compose.material.LocalTextStyle
 import androidx.compose.material.MaterialTheme
 import androidx.compose.material.Text
@@ -48,13 +54,17 @@
 import androidx.compose.runtime.getValue
 import androidx.compose.runtime.mutableStateOf
 import androidx.compose.runtime.remember
+import androidx.compose.runtime.rememberCoroutineScope
 import androidx.compose.runtime.setValue
 import androidx.compose.ui.Modifier
+import androidx.compose.ui.composed
 import androidx.compose.ui.graphics.ImageBitmap
 import androidx.compose.ui.graphics.asImageBitmap
 import androidx.compose.ui.platform.LocalContext
 import androidx.compose.ui.text.font.FontWeight
 import androidx.compose.ui.unit.dp
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.launch
 
 @OptIn(ExperimentalFoundationApi::class)
 @Composable
@@ -62,51 +72,71 @@
     val state = remember { TextFieldState() }
     val context = LocalContext.current
 
-    ReceiveContentShowcase(
-        "Everything Consumer",
-        MediaType.All, {
-            // consume everything here
-            null
-        },
-        modifier = Modifier.verticalScroll(rememberScrollState())
-    ) {
-        var images by remember { mutableStateOf<List<ImageBitmap>>(emptyList()) }
+    Column {
+        var descriptionToggle by remember { mutableStateOf(false) }
+        Text(
+            if (descriptionToggle) Description else "Click to see the description...",
+            Modifier
+                .padding(8.dp)
+                .clickable { descriptionToggle = !descriptionToggle }
+        )
+        Spacer(Modifier.height(8.dp))
         ReceiveContentShowcase(
-            "Image Consumer",
-            MediaType.Image, { transferableContent ->
-                if (!transferableContent.hasMediaType(MediaType.Image)) {
-                    transferableContent
-                } else {
-                    val newImages = mutableListOf<ImageBitmap>()
-                    transferableContent.consumeEach { item ->
-                        // only consume this item if we can read
-                        item.readImageBitmap(context)?.let { newImages += it; true } ?: false
-                    }.also {
-                        images = newImages
-                    }
-                }
-            }
+            "Everything Consumer",
+            MediaType.All, {
+                // consume everything here
+                null
+            },
+            modifier = Modifier.verticalScroll(rememberScrollState())
         ) {
-            Row(horizontalArrangement = Arrangement.spacedBy(8.dp)) {
-                images.forEach {
-                    Image(it, contentDescription = null, Modifier.size(100.dp))
-                }
-            }
+            val coroutineScope = rememberCoroutineScope()
+            var images by remember { mutableStateOf<List<ImageBitmap>>(emptyList()) }
             ReceiveContentShowcase(
-                "Text Consumer",
-                MediaType.Text, {
-                    it.consumeEach { item ->
-                        val text = item.coerceToText(context)
-                        // only consume if it has text in it.
-                        !text.isNullOrBlank() && item.uri == null
+                title = "Image Consumer",
+                hintMediaType = MediaType.Image,
+                onReceive = { transferableContent ->
+                    if (!transferableContent.hasMediaType(MediaType.Image)) {
+                        transferableContent
+                    } else {
+                        var uri: Uri? = null
+                        transferableContent.consumeEach { item ->
+                            // only consume this item if we can read
+                            if (item.uri != null && uri == null) {
+                                uri = item.uri
+                                true
+                            } else {
+                                false
+                            }
+                        }.also {
+                            coroutineScope.launch(Dispatchers.IO) {
+                                uri?.readImageBitmap(context)?.let { images = listOf(it) }
+                            }
+                        }
+                    }
+                },
+                onClear = { images = emptyList() }
+            ) {
+                Row(horizontalArrangement = Arrangement.spacedBy(8.dp)) {
+                    images.forEach {
+                        Image(it, contentDescription = null, Modifier.size(100.dp))
                     }
                 }
-            ) {
-                BasicTextField2(
-                    state = state,
-                    modifier = demoTextFieldModifiers,
-                    textStyle = LocalTextStyle.current
-                )
+                ReceiveContentShowcase(
+                    "Text Consumer",
+                    MediaType.Text, {
+                        it.consumeEach { item ->
+                            val text = item.coerceToText(context)
+                            // only consume if it has text in it.
+                            !text.isNullOrBlank() && item.uri == null
+                        }
+                    }
+                ) {
+                    BasicTextField2(
+                        state = state,
+                        modifier = demoTextFieldModifiers,
+                        textStyle = LocalTextStyle.current
+                    )
+                }
             }
         }
     }
@@ -119,20 +149,38 @@
 @Composable
 private fun ReceiveContentShowcase(
     title: String,
-    acceptedMediaType: MediaType,
+    hintMediaType: MediaType,
     onReceive: (TransferableContent) -> TransferableContent?,
     modifier: Modifier = Modifier,
+    onClear: () -> Unit = {},
     content: @Composable () -> Unit
 ) {
     val transferableContentState = remember { mutableStateOf<TransferableContent?>(null) }
+    val receiveContentState = remember {
+        ReceiveContentState(setOf(hintMediaType)) {
+            transferableContentState.value = it
+            onReceive(it)
+        }
+    }
     Column(
         modifier
-            .receiveContent(acceptedMediaType) {
-                transferableContentState.value = it
-                onReceive(it)
+            .dropReceiveContent(receiveContentState)
+            .padding(8.dp)
+    ) {
+        Card(
+            Modifier
+                .fillMaxWidth()
+                .clickable {
+                    transferableContentState.value = null
+                    onClear()
+                },
+            elevation = 4.dp,
+            backgroundColor = if (receiveContentState.hovering) {
+                MaterialTheme.colors.secondary
+            } else {
+                MaterialTheme.colors.surface
             }
-            .padding(8.dp)) {
-        Card(Modifier.fillMaxWidth()) {
+        ) {
             Column(
                 modifier = Modifier.padding(8.dp),
                 verticalArrangement = Arrangement.spacedBy(4.dp)
@@ -140,7 +188,7 @@
                 val transferableContent = transferableContentState.value
                 if (transferableContent == null) {
                     Text(
-                        "$title - Haven't received anything yet!",
+                        "$title - Hasn't received anything yet!",
                         style = MaterialTheme.typography.h6
                     )
                 } else {
@@ -159,13 +207,15 @@
 
                     for (i in 0 until transferableContent.clipEntry.clipData.itemCount) {
                         val item = transferableContent.clipEntry.clipData.getItemAt(i)
-                        KeyValueEntry("Uri", "${item.uri}")
-                        KeyValueEntry("Text", "${item.text}")
-                        KeyValueEntry("Intent", "${item.intent}")
+                        if (item.uri != null) KeyValueEntry("Uri", "${item.uri}")
+                        if (item.text != null) KeyValueEntry("Text", "${item.text}")
+                        if (item.intent != null) KeyValueEntry("Intent", "${item.intent}")
+                        Divider(Modifier.fillMaxWidth())
                     }
                 }
             }
         }
+        Spacer(Modifier.height(8.dp))
         content()
     }
 }
@@ -183,11 +233,73 @@
 }
 
 @Suppress("ClassVerificationFailure", "DEPRECATION")
-private fun ClipData.Item.readImageBitmap(context: Context): ImageBitmap? {
-    val imageUri = uri ?: return null
+private fun Uri.readImageBitmap(context: Context): ImageBitmap? {
     return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
-        ImageDecoder.decodeBitmap(ImageDecoder.createSource(context.contentResolver, imageUri))
+        ImageDecoder.decodeBitmap(ImageDecoder.createSource(context.contentResolver, this))
     } else {
-        MediaStore.Images.Media.getBitmap(context.contentResolver, imageUri)
+        MediaStore.Images.Media.getBitmap(context.contentResolver, this)
     }.asImageBitmap()
 }
+
+@OptIn(ExperimentalFoundationApi::class)
+class ReceiveContentState(
+    var hintMediaTypes: Set<MediaType>,
+    private val onReceive: (TransferableContent) -> TransferableContent?
+) {
+    internal var hovering by mutableStateOf(false)
+    internal var dragging by mutableStateOf(false)
+
+    internal val listener = object : ReceiveContentListener {
+        override fun onDragEnter() {
+            hovering = true
+        }
+
+        override fun onDragEnd() {
+            hovering = false
+            dragging = false
+        }
+
+        override fun onDragStart() {
+            dragging = true
+        }
+
+        override fun onDragExit() {
+            hovering = false
+        }
+
+        override fun onReceive(transferableContent: TransferableContent): TransferableContent? {
+            dragging = false
+            hovering = false
+            return this@ReceiveContentState.onReceive(transferableContent)
+        }
+    }
+}
+
+@OptIn(ExperimentalFoundationApi::class)
+fun Modifier.dropReceiveContent(
+    state: ReceiveContentState
+) = composed {
+    receiveContent(state.hintMediaTypes, state.listener)
+        .background(
+            color = if (state.hovering) {
+                MaterialTheme.colors.secondary
+            } else if (state.dragging) {
+                MaterialTheme.colors.primary
+            } else {
+                MaterialTheme.colors.surface
+            },
+            shape = RoundedCornerShape(8.dp)
+        )
+}
+
+private const val Description = "Below setup works as follows;\n" +
+    "  - There are 3 nested receiveContent nodes.\n" +
+    "  - The outermost one consumes everything that's passed to it.\n" +
+    "  - The middle one only consumes image content.\n" +
+    "  - The innermost one only consumes text content.\n" +
+    "  - BasicTextField2 that's nested the deepest would delegate whatever it receives " +
+    "to all 3 parents in order of proximity.\n" +
+    "  - Each node shows all the items it receives, not just what it consumes.\n\n" +
+    "ReceiveContent works with keyboard, paste, and drag/drop.\n" +
+    "Click on any card to clear its internal state.\n" +
+    "Click on this description to hide it."
diff --git a/compose/foundation/foundation/samples/src/main/java/androidx/compose/foundation/samples/ReceiveContentSamples.kt b/compose/foundation/foundation/samples/src/main/java/androidx/compose/foundation/samples/ReceiveContentSamples.kt
index 03766d2..3aeff3c 100644
--- a/compose/foundation/foundation/samples/src/main/java/androidx/compose/foundation/samples/ReceiveContentSamples.kt
+++ b/compose/foundation/foundation/samples/src/main/java/androidx/compose/foundation/samples/ReceiveContentSamples.kt
@@ -20,7 +20,10 @@
 import androidx.annotation.Sampled
 import androidx.compose.foundation.ExperimentalFoundationApi
 import androidx.compose.foundation.Image
+import androidx.compose.foundation.background
 import androidx.compose.foundation.content.MediaType
+import androidx.compose.foundation.content.ReceiveContentListener
+import androidx.compose.foundation.content.TransferableContent
 import androidx.compose.foundation.content.consumeEach
 import androidx.compose.foundation.content.hasMediaType
 import androidx.compose.foundation.content.receiveContent
@@ -28,12 +31,14 @@
 import androidx.compose.foundation.layout.Row
 import androidx.compose.foundation.text2.BasicTextField2
 import androidx.compose.foundation.text2.input.rememberTextFieldState
+import androidx.compose.material.MaterialTheme
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.getValue
 import androidx.compose.runtime.mutableStateOf
 import androidx.compose.runtime.remember
 import androidx.compose.runtime.setValue
 import androidx.compose.ui.Modifier
+import androidx.compose.ui.graphics.Color
 import androidx.compose.ui.graphics.ImageBitmap
 
 @OptIn(ExperimentalFoundationApi::class)
@@ -50,7 +55,7 @@
         }
         BasicTextField2(
             state = state,
-            modifier = Modifier.receiveContent(MediaType.Image) { transferableContent ->
+            modifier = Modifier.receiveContent(setOf(MediaType.Image)) { transferableContent ->
                 if (!transferableContent.hasMediaType(MediaType.Image)) {
                     return@receiveContent transferableContent
                 }
@@ -66,5 +71,73 @@
     }
 }
 
+@OptIn(ExperimentalFoundationApi::class)
+@Sampled
+@Composable
+fun ReceiveContentFullSample() {
+    val state = rememberTextFieldState()
+    var images by remember { mutableStateOf<List<ImageBitmap>>(emptyList()) }
+    var dragging by remember { mutableStateOf(false) }
+    var hovering by remember { mutableStateOf(false) }
+    Column {
+        Row {
+            images.forEach {
+                Image(bitmap = it, contentDescription = null)
+            }
+        }
+        BasicTextField2(
+            state = state,
+            modifier = Modifier
+                .background(
+                    when {
+                        dragging -> Color.Red
+                        hovering -> Color.Green
+                        else -> MaterialTheme.colors.background
+                    }
+                )
+                .receiveContent(
+                    hintMediaTypes = setOf(MediaType.Image),
+                    receiveContentListener = object : ReceiveContentListener {
+                        override fun onDragStart() {
+                            dragging = true
+                        }
+
+                        override fun onDragEnd() {
+                            hovering = false
+                            dragging = false
+                        }
+
+                        override fun onDragEnter() {
+                            hovering = true
+                        }
+
+                        override fun onDragExit() {
+                            hovering = false
+                        }
+
+                        override fun onReceive(
+                            transferableContent: TransferableContent
+                        ): TransferableContent? {
+                            if (!transferableContent.hasMediaType(MediaType.Image)) {
+                                return transferableContent
+                            }
+                            val newImages = mutableListOf<ImageBitmap>()
+                            return transferableContent
+                                .consumeEach { item ->
+                                    // only consume this item if we can read an imageBitmap
+                                    item
+                                        .readImageBitmap()
+                                        ?.let { newImages += it; true } ?: false
+                                }
+                                .also {
+                                    images = newImages
+                                }
+                        }
+                    }
+                )
+        )
+    }
+}
+
 private fun ClipData.Item.readImageBitmap(): ImageBitmap? =
     TODO("Reads an ImageBitmap from ClipData.Item#uri")
diff --git a/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/TestActivity.kt b/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/TestActivity.kt
index b7b84f5c..31442e7 100644
--- a/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/TestActivity.kt
+++ b/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/TestActivity.kt
@@ -22,7 +22,7 @@
 
 class TestActivity : ComponentActivity() {
     var hasFocusLatch = CountDownLatch(1)
-    var requestedDragAndDropPermission: DragEvent? = null
+    val requestedDragAndDropPermissions: MutableList<DragEvent> = mutableListOf()
 
     override fun onWindowFocusChanged(hasFocus: Boolean) {
         super.onWindowFocusChanged(hasFocus)
@@ -32,7 +32,7 @@
     }
 
     override fun requestDragAndDropPermissions(event: DragEvent?): DragAndDropPermissions {
-        requestedDragAndDropPermission = event
+        event?.let { requestedDragAndDropPermissions += it }
         return super.requestDragAndDropPermissions(event)
     }
 }
diff --git a/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/content/ReceiveContentConfigurationTest.kt b/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/content/ReceiveContentConfigurationTest.kt
deleted file mode 100644
index e1b64c3..0000000
--- a/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/content/ReceiveContentConfigurationTest.kt
+++ /dev/null
@@ -1,310 +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.compose.foundation.content
-
-import android.net.Uri
-import androidx.compose.foundation.ExperimentalFoundationApi
-import androidx.compose.foundation.content.internal.ReceiveContentConfiguration
-import androidx.compose.foundation.content.internal.mergeReceiveContentConfiguration
-import androidx.compose.foundation.layout.Box
-import androidx.compose.runtime.getValue
-import androidx.compose.runtime.mutableStateOf
-import androidx.compose.runtime.setValue
-import androidx.compose.ui.Modifier
-import androidx.compose.ui.node.ModifierNodeElement
-import androidx.compose.ui.platform.PlatformTextInputModifierNode
-import androidx.compose.ui.test.junit4.createComposeRule
-import androidx.test.filters.MediumTest
-import com.google.common.truth.Truth.assertThat
-import org.junit.Rule
-import org.junit.Test
-
-@OptIn(ExperimentalFoundationApi::class)
-@MediumTest
-class ReceiveContentConfigurationTest {
-
-    @get:Rule
-    val rule = createComposeRule()
-
-    @Test
-    fun receiveContentConfiguration_isMergedBottomToTop() {
-        var calculatedReceiveContent: ReceiveContentConfiguration? = null
-        val listenerCalls = mutableListOf<Int>()
-        rule.setContent {
-            Box(modifier = Modifier
-                .receiveContent(MediaType.Video) { listenerCalls += 3; it }
-                .receiveContent(MediaType.Audio) { listenerCalls += 2; it }
-                .receiveContent(MediaType.Text) { listenerCalls += 1; it }
-                .then(TestElement {
-                    calculatedReceiveContent = it.mergeReceiveContentConfiguration()
-                    calculatedReceiveContent
-                        ?.onReceive
-                        ?.invoke(TransferableContent(createClipData()))
-                })
-            )
-        }
-
-        rule.runOnIdle {
-            assertThat(calculatedReceiveContent?.acceptedMimeTypes).isNotNull()
-            assertThat(calculatedReceiveContent?.acceptedMimeTypes).containsExactlyElementsIn(
-                listOf(
-                    MediaType.Video.representation,
-                    MediaType.Audio.representation,
-                    MediaType.Text.representation
-                )
-            )
-            assertThat(listenerCalls).isEqualTo(listOf(1, 2, 3))
-        }
-    }
-
-    @Test
-    fun onReceiveCallbacks_passTheReturnedValue_toParentNode() {
-        var videoReceived: TransferableContent? = null
-        var audioReceived: TransferableContent? = null
-        var textReceived: TransferableContent? = null
-        rule.setContent {
-            Box(modifier = Modifier
-                .receiveContent(MediaType.Video) {
-                    videoReceived = it
-                    val t = it.consumeEach { it.uri?.toString()?.contains("video") ?: false }
-                    t
-                }
-                .receiveContent(MediaType.Audio) {
-                    audioReceived = it
-                    val t = it.consumeEach { it.uri?.toString()?.contains("audio") ?: false }
-                    t
-                }
-                .receiveContent(MediaType.Text) {
-                    textReceived = it
-                    val t = it.consumeEach { it.text != null }
-                    t
-                }
-                .then(TestElement {
-                    it.mergeReceiveContentConfiguration()
-                        ?.onReceive
-                        ?.invoke(TransferableContent(createClipData {
-                            addText()
-                            addUri(Uri.parse("content://video"), "video/mp4")
-                            addUri(Uri.parse("content://audio"), "audio/ogg")
-                        }))
-                })
-            )
-        }
-
-        rule.runOnIdle {
-            assertClipData(videoReceived!!.clipEntry.clipData).isEqualToClipData(createClipData {
-                addUri(Uri.parse("content://video"), "video/mp4")
-            }, ignoreClipDescription = true)
-            assertClipData(audioReceived!!.clipEntry.clipData).isEqualToClipData(createClipData {
-                addUri(Uri.parse("content://video"), "video/mp4")
-                addUri(Uri.parse("content://audio"), "audio/ogg")
-            }, ignoreClipDescription = true)
-            assertClipData(textReceived!!.clipEntry.clipData).isEqualToClipData(createClipData {
-                addText()
-                addUri(Uri.parse("content://video"), "video/mp4")
-                addUri(Uri.parse("content://audio"), "audio/ogg")
-            }, ignoreClipDescription = true)
-        }
-    }
-
-    @Test
-    fun receiveContentConfiguration_returnsNullIfNotDefined() {
-        var calculatedReceiveContent: ReceiveContentConfiguration? = ReceiveContentConfiguration(
-            emptySet()
-        ) { null }
-        rule.setContent {
-            Box(
-                modifier = Modifier.then(TestElement {
-                    calculatedReceiveContent = it.mergeReceiveContentConfiguration()
-                })
-            )
-        }
-
-        rule.runOnIdle {
-            assertThat(calculatedReceiveContent).isNull()
-        }
-    }
-
-    @Test
-    fun receiveContentConfiguration_returnsNullIfDefined_atSiblingNode() {
-        var calculatedReceiveContent: ReceiveContentConfiguration? = ReceiveContentConfiguration(
-            emptySet()
-        ) { null }
-        rule.setContent {
-            Box {
-                Box(modifier = Modifier.then(TestElement {
-                    calculatedReceiveContent = it.mergeReceiveContentConfiguration()
-                }))
-                Box(modifier = Modifier.receiveContent(MediaType.Text) { it })
-            }
-        }
-
-        rule.runOnIdle {
-            assertThat(calculatedReceiveContent).isNull()
-        }
-    }
-
-    @Test
-    fun receiveContentConfiguration_returnsNullIfDefined_atChildNode() {
-        var calculatedReceiveContent: ReceiveContentConfiguration? = ReceiveContentConfiguration(
-            emptySet()
-        ) { null }
-        rule.setContent {
-            Box(
-                modifier = Modifier.then(TestElement {
-                    calculatedReceiveContent = it.mergeReceiveContentConfiguration()
-                })
-            ) {
-                Box(modifier = Modifier.receiveContent(MediaType.Text) { it })
-            }
-        }
-
-        rule.runOnIdle {
-            assertThat(calculatedReceiveContent).isNull()
-        }
-    }
-
-    @Test
-    fun receiveContentConfiguration_noMimeType_returnsNull() {
-        var calculatedReceiveContent: ReceiveContentConfiguration? = ReceiveContentConfiguration(
-            emptySet()
-        ) { null }
-        rule.setContent {
-            Box(modifier = Modifier.receiveContent { it }) {
-                Box(modifier = Modifier.then(TestElement {
-                    calculatedReceiveContent = it.mergeReceiveContentConfiguration()
-                }))
-            }
-        }
-
-        rule.runOnIdle {
-            assertThat(calculatedReceiveContent).isNull()
-        }
-    }
-
-    @Test
-    fun detachedReceiveContent_disappearsFromMergedConfiguration() {
-        var getReceiveContentConfiguration: (() -> ReceiveContentConfiguration?)? = null
-        var attached by mutableStateOf(true)
-        rule.setContent {
-            Box(modifier = Modifier
-                .receiveContent(MediaType.Video) { it }
-                .then(if (attached) Modifier.receiveContent(MediaType.Audio) { it } else Modifier)
-                .receiveContent(MediaType.Text) { it }
-                .then(TestElement {
-                    getReceiveContentConfiguration = {
-                        it.mergeReceiveContentConfiguration()
-                    }
-                })
-            )
-        }
-
-        rule.runOnIdle {
-            val receiveContentConfiguration = getReceiveContentConfiguration?.invoke()
-            assertThat(receiveContentConfiguration).isNotNull()
-            assertThat(receiveContentConfiguration?.acceptedMimeTypes).containsExactlyElementsIn(
-                listOf(
-                    MediaType.Video.representation,
-                    MediaType.Audio.representation,
-                    MediaType.Text.representation
-                )
-            )
-        }
-
-        attached = false
-
-        rule.runOnIdle {
-            val receiveContentConfiguration = getReceiveContentConfiguration?.invoke()
-            assertThat(receiveContentConfiguration).isNotNull()
-            assertThat(receiveContentConfiguration?.acceptedMimeTypes).containsExactlyElementsIn(
-                listOf(
-                    MediaType.Video.representation,
-                    MediaType.Text.representation
-                )
-            )
-        }
-    }
-
-    @Test
-    fun laterAttachedReceiveContent_appearsInMergedConfiguration() {
-        var getReceiveContentConfiguration: (() -> ReceiveContentConfiguration?)? = null
-        var attached by mutableStateOf(false)
-        rule.setContent {
-            Box(modifier = Modifier
-                .receiveContent(MediaType.Video) { it }
-                .then(if (attached) Modifier.receiveContent(MediaType.Audio) { it } else Modifier)
-                .receiveContent(MediaType.Text) { it }
-                .then(TestElement {
-                    getReceiveContentConfiguration = {
-                        it.mergeReceiveContentConfiguration()
-                    }
-                })
-            )
-        }
-
-        rule.runOnIdle {
-            val receiveContentConfiguration = getReceiveContentConfiguration?.invoke()
-            assertThat(receiveContentConfiguration).isNotNull()
-            assertThat(receiveContentConfiguration?.acceptedMimeTypes).containsExactlyElementsIn(
-                listOf(
-                    MediaType.Video.representation,
-                    MediaType.Text.representation
-                )
-            )
-        }
-
-        attached = true
-
-        rule.runOnIdle {
-            val receiveContentConfiguration = getReceiveContentConfiguration?.invoke()
-            assertThat(receiveContentConfiguration).isNotNull()
-            assertThat(receiveContentConfiguration?.acceptedMimeTypes).containsExactlyElementsIn(
-                listOf(
-                    MediaType.Video.representation,
-                    MediaType.Audio.representation,
-                    MediaType.Text.representation
-                )
-            )
-        }
-    }
-
-    private data class TestElement(
-        val onNode: (TestNode) -> Unit
-    ) : ModifierNodeElement<TestNode>() {
-        override fun create(): TestNode = TestNode(onNode)
-        override fun update(node: TestNode) {
-            node.onNode = onNode
-        }
-    }
-
-    private class TestNode(
-        var onNode: (TestNode) -> Unit
-    ) : Modifier.Node(), PlatformTextInputModifierNode {
-
-        override fun onAttach() {
-            onNode(this)
-        }
-    }
-}
-
-@OptIn(ExperimentalFoundationApi::class)
-private val MediaType.Companion.Video: MediaType
-    get() = MediaType("video/*")
-
-@OptIn(ExperimentalFoundationApi::class)
-private val MediaType.Companion.Audio: MediaType
-    get() = MediaType("audio/*")
diff --git a/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/content/ReceiveContentTest.kt b/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/content/ReceiveContentTest.kt
index b6f0f0d..91d6be5 100644
--- a/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/content/ReceiveContentTest.kt
+++ b/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/content/ReceiveContentTest.kt
@@ -20,109 +20,829 @@
 import android.content.ClipDescription
 import android.content.Intent
 import android.net.Uri
+import android.view.View
 import androidx.compose.foundation.ExperimentalFoundationApi
-import androidx.compose.ui.platform.toClipEntry
-import androidx.compose.ui.platform.toClipMetadata
+import androidx.compose.foundation.TestActivity
+import androidx.compose.foundation.content.internal.ReceiveContentConfiguration
+import androidx.compose.foundation.content.internal.getReceiveContentConfiguration
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.size
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.setValue
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.ExperimentalComposeUiApi
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.geometry.Offset
+import androidx.compose.ui.modifier.ModifierLocalModifierNode
+import androidx.compose.ui.node.ModifierNodeElement
+import androidx.compose.ui.platform.LocalView
+import androidx.compose.ui.platform.firstUriOrNull
+import androidx.compose.ui.test.junit4.createAndroidComposeRule
+import androidx.compose.ui.unit.dp
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.MediumTest
+import androidx.test.filters.SdkSuppress
 import com.google.common.truth.Truth.assertThat
+import org.junit.Rule
 import org.junit.Test
 import org.junit.runner.RunWith
 
 @MediumTest
 @RunWith(AndroidJUnit4::class)
-@OptIn(ExperimentalFoundationApi::class)
+@OptIn(ExperimentalFoundationApi::class, ExperimentalComposeUiApi::class)
 class ReceiveContentTest {
 
-    @Test
-    fun consumeEach_separatesTransferableContent() {
-        val clipData = createClipData {
-            addText()
-            addHtmlText()
-            addUri()
-        }
-        val transferableContent = TransferableContent(
-            clipEntry = clipData.toClipEntry(),
-            source = TransferableContent.Source.Keyboard,
-            clipMetadata = clipData.description.toClipMetadata()
-        )
+    @get:Rule
+    val rule = createAndroidComposeRule<TestActivity>()
 
-        // only consume plain text
-        val remaining = transferableContent.consumeEach {
-            it.text != null && it.htmlText == null
+    @Test
+    fun receiveContentConfiguration_isMergedBottomToTop() {
+        var calculatedReceiveContent: ReceiveContentConfiguration? = null
+        val listenerCalls = mutableListOf<Int>()
+        rule.setContent {
+            Box(modifier = Modifier
+                .receiveContent(setOf(MediaType.Video)) { listenerCalls += 3; it }
+                .receiveContent(setOf(MediaType.Audio)) { listenerCalls += 2; it }
+                .receiveContent(setOf(MediaType.Text)) { listenerCalls += 1; it }
+                .then(TestElement {
+                    calculatedReceiveContent = it.getReceiveContentConfiguration()
+                    calculatedReceiveContent
+                        ?.receiveContentListener
+                        ?.onReceive(TransferableContent(createClipData()))
+                })
+            )
         }
 
-        assertThat(remaining).isNotNull()
-        assertThat(remaining?.source).isEqualTo(TransferableContent.Source.Keyboard)
-        assertClipDescription(remaining?.clipMetadata?.clipDescription)
-            .isEqualToClipDescription(clipData.description)
-
-        val remainingClipData = remaining?.clipEntry?.clipData
-        assertThat(remainingClipData).isNotNull()
-        assertThat(remainingClipData?.itemCount).isEqualTo(2)
-        // the first item from original ClipData will be consumed
-        assertThat(remainingClipData?.getItemAt(0)).isEqualTo(clipData.getItemAt(1))
-        assertThat(remainingClipData?.getItemAt(1)).isEqualTo(clipData.getItemAt(2))
+        rule.runOnIdle {
+            assertThat(calculatedReceiveContent?.hintMediaTypes).isNotNull()
+            assertThat(calculatedReceiveContent?.hintMediaTypes).containsExactlyElementsIn(
+                setOf(MediaType.Video, MediaType.Audio, MediaType.Text)
+            )
+            assertThat(listenerCalls).isEqualTo(listOf(1, 2, 3))
+        }
     }
 
     @Test
-    fun consumingEverything_returnsNull() {
-        val clipData = createClipData()
-        val transferableContent = TransferableContent(
-            clipEntry = clipData.toClipEntry(),
-            source = TransferableContent.Source.Keyboard,
-            clipMetadata = clipData.description.toClipMetadata()
-        )
+    fun onReceiveCallbacks_passTheReturnedValue_toParentNode() {
+        var videoReceived: TransferableContent? = null
+        var audioReceived: TransferableContent? = null
+        var textReceived: TransferableContent? = null
+        rule.setContent {
+            Box(modifier = Modifier
+                .receiveContent(setOf(MediaType.Video)) {
+                    videoReceived = it
+                    val t = it.consumeEach {
+                        it.uri
+                            ?.toString()
+                            ?.contains("video") ?: false
+                    }
+                    t
+                }
+                .receiveContent(setOf(MediaType.Audio)) {
+                    audioReceived = it
+                    val t = it.consumeEach {
+                        it.uri
+                            ?.toString()
+                            ?.contains("audio") ?: false
+                    }
+                    t
+                }
+                .receiveContent(setOf(MediaType.Text)) {
+                    textReceived = it
+                    val t = it.consumeEach { it.text != null }
+                    t
+                }
+                .then(TestElement {
+                    it.getReceiveContentConfiguration()
+                        ?.receiveContentListener
+                        ?.onReceive(TransferableContent(createClipData {
+                            addText()
+                            addUri(Uri.parse("content://video"), "video/mp4")
+                            addUri(Uri.parse("content://audio"), "audio/ogg")
+                        }))
+                })
+            )
+        }
 
-        // only consume plain text
-        val remaining = transferableContent.consumeEach { true }
-
-        assertThat(remaining).isNull()
+        rule.runOnIdle {
+            assertClipData(videoReceived!!.clipEntry.clipData).isEqualToClipData(createClipData {
+                addUri(Uri.parse("content://video"), "video/mp4")
+            }, ignoreClipDescription = true)
+            assertClipData(audioReceived!!.clipEntry.clipData).isEqualToClipData(createClipData {
+                addUri(Uri.parse("content://video"), "video/mp4")
+                addUri(Uri.parse("content://audio"), "audio/ogg")
+            }, ignoreClipDescription = true)
+            assertClipData(textReceived!!.clipEntry.clipData).isEqualToClipData(createClipData {
+                addText()
+                addUri(Uri.parse("content://video"), "video/mp4")
+                addUri(Uri.parse("content://audio"), "audio/ogg")
+            }, ignoreClipDescription = true)
+        }
     }
 
     @Test
-    fun consumingOnlyItem_returnsNull() {
-        val clipData = createClipData { addText() }
-        val transferableContent = TransferableContent(
-            clipEntry = clipData.toClipEntry(),
-            source = TransferableContent.Source.Keyboard,
-            clipMetadata = clipData.description.toClipMetadata()
+    fun receiveContentConfiguration_returnsNullIfNotDefined() {
+        var calculatedReceiveContent: ReceiveContentConfiguration? = ReceiveContentConfiguration(
+            emptySet(),
+            ReceiveContentListener { null }
         )
+        rule.setContent {
+            Box(
+                modifier = Modifier.then(TestElement {
+                    calculatedReceiveContent = it.getReceiveContentConfiguration()
+                })
+            )
+        }
 
-        // only consume plain text
-        val remaining = transferableContent.consumeEach { true }
-
-        assertThat(remaining).isNull()
+        rule.runOnIdle {
+            assertThat(calculatedReceiveContent).isNull()
+        }
     }
 
     @Test
-    fun notConsumingAnything_returnsTheSameInstance() {
-        val clipData = createClipData()
-        val transferableContent = TransferableContent(
-            clipEntry = clipData.toClipEntry(),
-            source = TransferableContent.Source.Keyboard,
-            clipMetadata = clipData.description.toClipMetadata()
+    fun receiveContentConfiguration_returnsNullIfDefined_atSiblingNode() {
+        var calculatedReceiveContent: ReceiveContentConfiguration? = ReceiveContentConfiguration(
+            emptySet(),
+            ReceiveContentListener { null }
         )
+        rule.setContent {
+            Box {
+                Box(modifier = Modifier.then(TestElement {
+                    calculatedReceiveContent = it.getReceiveContentConfiguration()
+                }))
+                Box(modifier = Modifier.receiveContent(setOf(MediaType.Text)) { it })
+            }
+        }
 
-        // only consume plain text
-        val remaining = transferableContent.consumeEach { false }
-
-        assertThat(remaining).isSameInstanceAs(transferableContent)
+        rule.runOnIdle {
+            assertThat(calculatedReceiveContent).isNull()
+        }
     }
 
     @Test
-    fun notConsumingOnlyItem_returnsTheSameInstance() {
-        val clipData = createClipData { addText() }
-        val transferableContent = TransferableContent(
-            clipEntry = clipData.toClipEntry(),
-            source = TransferableContent.Source.Keyboard,
-            clipMetadata = clipData.description.toClipMetadata()
+    fun receiveContentConfiguration_returnsNullIfDefined_atChildNode() {
+        var calculatedReceiveContent: ReceiveContentConfiguration? = ReceiveContentConfiguration(
+            emptySet(),
+            ReceiveContentListener { null }
         )
+        rule.setContent {
+            Box(
+                modifier = Modifier.then(TestElement {
+                    calculatedReceiveContent = it.getReceiveContentConfiguration()
+                })
+            ) {
+                Box(modifier = Modifier.receiveContent(setOf(MediaType.Text)) { it })
+            }
+        }
 
-        // only consume plain text
-        val remaining = transferableContent.consumeEach { false }
+        rule.runOnIdle {
+            assertThat(calculatedReceiveContent).isNull()
+        }
+    }
 
-        assertThat(remaining).isSameInstanceAs(transferableContent)
+    @Test
+    fun receiveContentConfiguration_emptyMediaTypeSet_returnsMediaTypeAll() {
+        var calculatedReceiveContent: ReceiveContentConfiguration? = ReceiveContentConfiguration(
+            emptySet(),
+            ReceiveContentListener { null }
+        )
+        rule.setContent {
+            Box(modifier = Modifier.receiveContent(emptySet()) { it }) {
+                Box(modifier = Modifier.then(TestElement {
+                    calculatedReceiveContent = it.getReceiveContentConfiguration()
+                }))
+            }
+        }
+
+        rule.runOnIdle {
+            assertThat(calculatedReceiveContent).isNotNull()
+            assertThat(calculatedReceiveContent?.hintMediaTypes).isEqualTo(setOf(MediaType.All))
+        }
+    }
+
+    @Test
+    fun detachedReceiveContent_disappearsFromMergedConfiguration() {
+        var getReceiveContentConfiguration: (() -> ReceiveContentConfiguration?)? = null
+        var attached by mutableStateOf(true)
+        rule.setContent {
+            Box(modifier = Modifier
+                .receiveContent(setOf(MediaType.Video)) { it }
+                .then(if (attached) {
+                    Modifier.receiveContent(setOf(MediaType.Audio)) { it }
+                } else {
+                    Modifier
+                })
+                .receiveContent(setOf(MediaType.Text)) { it }
+                .then(TestElement {
+                    getReceiveContentConfiguration = {
+                        it.getReceiveContentConfiguration()
+                    }
+                })
+            )
+        }
+
+        rule.runOnIdle {
+            val receiveContentConfiguration = getReceiveContentConfiguration?.invoke()
+            assertThat(receiveContentConfiguration).isNotNull()
+            assertThat(receiveContentConfiguration?.hintMediaTypes).containsExactlyElementsIn(
+                setOf(MediaType.Video, MediaType.Audio, MediaType.Text)
+            )
+        }
+
+        attached = false
+
+        rule.runOnIdle {
+            val receiveContentConfiguration = getReceiveContentConfiguration?.invoke()
+            assertThat(receiveContentConfiguration).isNotNull()
+            assertThat(receiveContentConfiguration?.hintMediaTypes).containsExactlyElementsIn(
+                setOf(MediaType.Video, MediaType.Text)
+            )
+        }
+    }
+
+    @Test
+    fun laterAttachedReceiveContent_appearsInMergedConfiguration() {
+        var getReceiveContentConfiguration: (() -> ReceiveContentConfiguration?)? = null
+        var attached by mutableStateOf(false)
+        rule.setContent {
+            Box(modifier = Modifier
+                .receiveContent(setOf(MediaType.Video)) { it }
+                .then(if (attached) {
+                    Modifier.receiveContent(setOf(MediaType.Audio)) { it }
+                } else {
+                    Modifier
+                })
+                .receiveContent(setOf(MediaType.Text)) { it }
+                .then(TestElement {
+                    getReceiveContentConfiguration = {
+                        it.getReceiveContentConfiguration()
+                    }
+                })
+            )
+        }
+
+        rule.runOnIdle {
+            val receiveContentConfiguration = getReceiveContentConfiguration?.invoke()
+            assertThat(receiveContentConfiguration).isNotNull()
+            assertThat(receiveContentConfiguration?.hintMediaTypes).containsExactlyElementsIn(
+                setOf(MediaType.Video, MediaType.Text)
+            )
+        }
+
+        attached = true
+
+        rule.runOnIdle {
+            val receiveContentConfiguration = getReceiveContentConfiguration?.invoke()
+            assertThat(receiveContentConfiguration).isNotNull()
+            assertThat(receiveContentConfiguration?.hintMediaTypes).containsExactlyElementsIn(
+                setOf(MediaType.Video, MediaType.Audio, MediaType.Text)
+            )
+        }
+    }
+
+    @Test
+    fun changingParentReceiveContent_appearsInMergedConfiguration() {
+        var getReceiveContentConfiguration: (() -> ReceiveContentConfiguration?)? = null
+        var topMediaTypes by mutableStateOf(setOf(MediaType.Video))
+        rule.setContent {
+            Box(modifier = Modifier
+                .receiveContent(topMediaTypes) { it }
+                .receiveContent(setOf(MediaType.Text)) { it }
+                .then(TestElement {
+                    getReceiveContentConfiguration = {
+                        it.getReceiveContentConfiguration()
+                    }
+                })
+            )
+        }
+
+        rule.runOnIdle {
+            val receiveContentConfiguration = getReceiveContentConfiguration?.invoke()
+            assertThat(receiveContentConfiguration).isNotNull()
+            assertThat(receiveContentConfiguration?.hintMediaTypes).containsExactlyElementsIn(
+                setOf(MediaType.Video, MediaType.Text)
+            )
+        }
+
+        topMediaTypes = setOf(MediaType.Audio, MediaType.Video)
+
+        rule.runOnIdle {
+            val receiveContentConfiguration = getReceiveContentConfiguration?.invoke()
+            assertThat(receiveContentConfiguration).isNotNull()
+            assertThat(receiveContentConfiguration?.hintMediaTypes).containsExactlyElementsIn(
+                setOf(MediaType.Video, MediaType.Audio, MediaType.Text)
+            )
+        }
+    }
+
+    @Test
+    fun changingCurrentReceiveContent_appearsInMergedConfiguration() {
+        var getReceiveContentConfiguration: (() -> ReceiveContentConfiguration?)? = null
+        var currentMediaTypes by mutableStateOf(setOf(MediaType.Video))
+        rule.setContent {
+            Box(modifier = Modifier
+                .receiveContent(setOf(MediaType.Image)) { it }
+                .receiveContent(currentMediaTypes) { it }
+                .then(TestElement {
+                    getReceiveContentConfiguration = {
+                        it.getReceiveContentConfiguration()
+                    }
+                })
+            )
+        }
+
+        rule.runOnIdle {
+            val receiveContentConfiguration = getReceiveContentConfiguration?.invoke()
+            assertThat(receiveContentConfiguration).isNotNull()
+            assertThat(receiveContentConfiguration?.hintMediaTypes).containsExactlyElementsIn(
+                setOf(MediaType.Video, MediaType.Image)
+            )
+        }
+
+        currentMediaTypes = setOf(MediaType.Text, MediaType.Video)
+
+        rule.runOnIdle {
+            val receiveContentConfiguration = getReceiveContentConfiguration?.invoke()
+            assertThat(receiveContentConfiguration).isNotNull()
+            assertThat(receiveContentConfiguration?.hintMediaTypes).containsExactlyElementsIn(
+                setOf(MediaType.Video, MediaType.Image, MediaType.Text)
+            )
+        }
+    }
+
+    @SdkSuppress(minSdkVersion = 24)
+    @Test
+    fun dragAndDrop_dropImplicitlyRequestsPermissions_once() {
+        lateinit var view: View
+        rule.setContent {
+            view = LocalView.current
+            Box(modifier = Modifier
+                .size(200.dp)
+                .receiveContent(setOf(MediaType.Video)) { it }
+                .size(100.dp)
+                .receiveContent(setOf(MediaType.Audio)) { it }
+                .size(50.dp)
+                .receiveContent(setOf(MediaType.Text)) { it }
+            )
+        }
+
+        val draggingUri = Uri.parse("content://com.example/content.jpg")
+        testDragAndDrop(view, rule.density) {
+            drag(
+                Offset(25.dp.toPx(), 25.dp.toPx()),
+                draggingUri
+            )
+            drop()
+        }
+
+        rule.runOnIdle {
+            val requests = rule.activity.requestedDragAndDropPermissions
+            assertThat(requests.size).isEqualTo(1)
+            assertThat(requests.first().clipData.getItemAt(0).uri).isEqualTo(draggingUri)
+        }
+    }
+
+    @Test
+    fun dragAndDropOnSingleNodeTriggersOnReceive() {
+        lateinit var view: View
+        var transferableContent: TransferableContent? = null
+        rule.setContent {
+            view = LocalView.current
+            Box(modifier = Modifier
+                .size(100.dp)
+                .receiveContent(setOf(MediaType.Image)) {
+                    transferableContent = it
+                    null // consume all
+                })
+        }
+
+        val draggingUri = Uri.parse("content://com.example/content.jpg")
+        testDragAndDrop(view, rule.density) {
+            drag(
+                Offset(50.dp.toPx(), 50.dp.toPx()),
+                draggingUri
+            )
+            drop()
+        }
+
+        rule.runOnIdle {
+            assertThat(transferableContent).isNotNull()
+            assertThat(transferableContent?.clipEntry?.firstUriOrNull())
+                .isEqualTo(draggingUri)
+            assertThat(transferableContent?.source)
+                .isEqualTo(TransferableContent.Source.DragAndDrop)
+        }
+    }
+
+    @Test
+    fun dragAndDropOnSingleNode_withNotIncludedHintMediaType_triggersOnReceive() {
+        lateinit var view: View
+        var transferableContent: TransferableContent? = null
+        rule.setContent {
+            view = LocalView.current
+            Box(modifier = Modifier
+                .size(100.dp)
+                .receiveContent(setOf(MediaType.Audio)) {
+                    transferableContent = it
+                    null // consume all
+                })
+        }
+
+        val draggingUri = Uri.parse("content://com.example/content.jpg")
+        testDragAndDrop(view, rule.density) {
+            drag(
+                Offset(50.dp.toPx(), 50.dp.toPx()),
+                draggingUri
+            )
+            drop()
+        }
+
+        rule.runOnIdle {
+            assertThat(transferableContent).isNotNull()
+            assertThat(transferableContent?.clipEntry?.firstUriOrNull())
+                .isEqualTo(draggingUri)
+            assertThat(transferableContent?.source)
+                .isEqualTo(TransferableContent.Source.DragAndDrop)
+        }
+    }
+
+    @Test
+    fun dragAndDropOnNestedNode_triggersOnReceive_onAllNodes() {
+        lateinit var view: View
+        var childTransferableContent: TransferableContent? = null
+        var parentTransferableContent: TransferableContent? = null
+        rule.setContent {
+            view = LocalView.current
+            Box(modifier = Modifier
+                .size(200.dp)
+                .receiveContent(setOf(MediaType.All)) {
+                    parentTransferableContent = it
+                    null
+                }) {
+                Box(modifier = Modifier
+                    .align(Alignment.Center)
+                    .size(100.dp)
+                    .receiveContent(setOf(MediaType.Image)) {
+                        childTransferableContent = it
+                        it // don't consume anything
+                    })
+            }
+        }
+
+        val draggingUri = Uri.parse("content://com.example/content.jpg")
+        testDragAndDrop(view, rule.density) {
+            drag(
+                Offset(100.dp.toPx(), 100.dp.toPx()),
+                draggingUri
+            )
+            drop()
+        }
+
+        rule.runOnIdle {
+            assertThat(parentTransferableContent).isNotNull()
+            assertThat(parentTransferableContent?.clipEntry?.firstUriOrNull())
+                .isEqualTo(draggingUri)
+            assertThat(parentTransferableContent?.source)
+                .isEqualTo(TransferableContent.Source.DragAndDrop)
+
+            assertThat(childTransferableContent).isNotNull()
+            assertThat(childTransferableContent?.clipEntry?.firstUriOrNull())
+                .isEqualTo(draggingUri)
+            assertThat(childTransferableContent?.source)
+                .isEqualTo(TransferableContent.Source.DragAndDrop)
+        }
+    }
+
+    @Test
+    fun dragAndDropOnNestedNode_triggersOnReceive_onHoveringNodes() {
+        lateinit var view: View
+        var childTransferableContent: TransferableContent? = null
+        var parentTransferableContent: TransferableContent? = null
+        var grandParentTransferableContent: TransferableContent? = null
+        rule.setContent {
+            view = LocalView.current
+            Box(modifier = Modifier
+                .size(200.dp)
+                .receiveContent(setOf(MediaType.All)) {
+                    grandParentTransferableContent = it
+                    null
+                }) {
+                Box(modifier = Modifier
+                    .align(Alignment.Center)
+                    .size(100.dp)
+                    .receiveContent(setOf(MediaType.Image)) {
+                        parentTransferableContent = it
+                        it // don't consume anything
+                    }) {
+                    Box(modifier = Modifier
+                        .align(Alignment.Center)
+                        .size(50.dp)
+                        .receiveContent(setOf(MediaType.Text)) {
+                            childTransferableContent = it
+                            it // don't consume anything
+                        })
+                }
+            }
+        }
+
+        val draggingUri = Uri.parse("content://com.example/content.jpg")
+        testDragAndDrop(view, rule.density) {
+            drag(
+                Offset(60.dp.toPx(), 60.dp.toPx()),
+                draggingUri
+            )
+            drop()
+        }
+
+        rule.runOnIdle {
+            assertThat(grandParentTransferableContent).isNotNull()
+            assertThat(parentTransferableContent).isNotNull()
+            assertThat(childTransferableContent).isNull() // child was not in hover region
+        }
+    }
+
+    @Test
+    fun dragAndDrop_enterExitCallbacks_singleNode() {
+        lateinit var view: View
+        val calls = mutableListOf<String>()
+        rule.setContent {
+            view = LocalView.current
+            Box(
+                modifier = Modifier
+                    .size(100.dp)
+                    .receiveContent(setOf(MediaType.All), object : ReceiveContentListener {
+                        override fun onDragEnter() {
+                            calls += "enter"
+                        }
+
+                        override fun onDragExit() {
+                            calls += "exit"
+                        }
+
+                        override fun onReceive(
+                            transferableContent: TransferableContent
+                        ): TransferableContent? {
+                            calls += "receive"
+                            return null
+                        }
+                    })
+            )
+        }
+
+        val draggingUri = Uri.parse("content://com.example/content.jpg")
+        testDragAndDrop(view, rule.density) {
+            drag(Offset(125.dp.toPx(), 125.dp.toPx()), draggingUri)
+            // enter
+            drag(Offset(90.dp.toPx(), 90.dp.toPx()), draggingUri)
+            // moves
+            drag(Offset(50.dp.toPx(), 50.dp.toPx()), draggingUri)
+            // exits
+            drag(Offset(101.dp.toPx(), 50.dp.toPx()), draggingUri)
+            // enters again
+            drag(Offset(99.dp.toPx(), 50.dp.toPx()), draggingUri)
+            drop()
+        }
+
+        rule.runOnIdle {
+            assertThat(calls).isEqualTo(listOf("enter", "exit", "enter", "receive"))
+        }
+    }
+
+    @Test
+    fun dragAndDrop_enterExitCallbacks_nestedNodes() {
+        lateinit var view: View
+        val calls = mutableListOf<String>()
+        rule.setContent {
+            view = LocalView.current
+            Box(
+                modifier = Modifier
+                    .size(200.dp)
+                    .receiveContent(setOf(MediaType.All), object : ReceiveContentListener {
+                        override fun onDragEnter() {
+                            calls += "enter-1"
+                        }
+
+                        override fun onDragExit() {
+                            calls += "exit-1"
+                        }
+
+                        override fun onReceive(
+                            transferableContent: TransferableContent
+                        ): TransferableContent = transferableContent
+                    })
+            ) {
+                Box(
+                    modifier = Modifier
+                        .align(Alignment.Center)
+                        .size(100.dp)
+                        .receiveContent(setOf(MediaType.All), object : ReceiveContentListener {
+                            override fun onDragEnter() {
+                                calls += "enter-2"
+                            }
+
+                            override fun onDragExit() {
+                                calls += "exit-2"
+                            }
+
+                            override fun onReceive(
+                                transferableContent: TransferableContent
+                            ): TransferableContent = transferableContent
+                        })
+                ) {
+                    Box(
+                        modifier = Modifier
+                            .align(Alignment.Center)
+                            .size(50.dp)
+                            .receiveContent(setOf(MediaType.All), object : ReceiveContentListener {
+                                override fun onDragEnter() {
+                                    calls += "enter-3"
+                                }
+
+                                override fun onDragExit() {
+                                    calls += "exit-3"
+                                }
+
+                                override fun onReceive(
+                                    transferableContent: TransferableContent
+                                ): TransferableContent = transferableContent
+                            })
+                    )
+                }
+            }
+        }
+
+        val draggingUri = Uri.parse("content://com.example/content.jpg")
+        testDragAndDrop(view, rule.density) {
+            drag(Offset(225.dp.toPx(), 225.dp.toPx()), draggingUri)
+            // enter 1 and 2, skip 3
+            drag(Offset(60.dp.toPx(), 60.dp.toPx()), draggingUri)
+            // exits 2, stays in 1
+            drag(Offset(40.dp.toPx(), 40.dp.toPx()), draggingUri)
+            // enters 2 and 3
+            drag(Offset(100.dp.toPx(), 100.dp.toPx()), draggingUri)
+            // exits all of them at once
+            drag(Offset(201.dp.toPx(), 201.dp.toPx()), draggingUri)
+        }
+
+        rule.runOnIdle {
+            assertThat(calls).isEqualTo(
+                listOf(
+                    "enter-1",
+                    "enter-2",
+                    "exit-2",
+                    "enter-2",
+                    "enter-3",
+                    "exit-1",
+                    "exit-2",
+                    "exit-3"
+                )
+            )
+        }
+    }
+
+    @Test
+    fun dragAndDrop_startEndCallbacks_singleNode() {
+        lateinit var view: View
+        val calls = mutableListOf<String>()
+        rule.setContent {
+            view = LocalView.current
+            Box(
+                modifier = Modifier
+                    .size(100.dp)
+                    .receiveContent(setOf(MediaType.All), object : ReceiveContentListener {
+                        override fun onDragStart() {
+                            calls += "start"
+                        }
+
+                        override fun onDragEnd() {
+                            calls += "end"
+                        }
+
+                        override fun onReceive(
+                            transferableContent: TransferableContent
+                        ): TransferableContent? = null
+                    })
+            )
+        }
+
+        val draggingUri = Uri.parse("content://com.example/content.jpg")
+        testDragAndDrop(view, rule.density) {
+            drag(Offset(125.dp.toPx(), 125.dp.toPx()), draggingUri)
+            cancelDrag()
+        }
+
+        rule.runOnIdle {
+            assertThat(calls).isEqualTo(listOf("start", "end"))
+        }
+
+        calls.clear()
+
+        testDragAndDrop(view, rule.density) {
+            drag(Offset(50.dp.toPx(), 50.dp.toPx()), draggingUri)
+            cancelDrag()
+        }
+
+        rule.runOnIdle {
+            assertThat(calls).isEqualTo(listOf("start", "end"))
+        }
+    }
+
+    @Test
+    fun dragAndDrop_startEndCallbacks_nestedNodes() {
+        lateinit var view: View
+        val calls = mutableListOf<String>()
+        rule.setContent {
+            view = LocalView.current
+            Box(
+                modifier = Modifier
+                    .size(200.dp)
+                    .receiveContent(setOf(MediaType.All), object : ReceiveContentListener {
+                        override fun onDragStart() {
+                            calls += "start-1"
+                        }
+
+                        override fun onDragEnd() {
+                            calls += "end-1"
+                        }
+
+                        override fun onReceive(
+                            transferableContent: TransferableContent
+                        ): TransferableContent = transferableContent
+                    })
+            ) {
+                Box(
+                    modifier = Modifier
+                        .align(Alignment.Center)
+                        .size(100.dp)
+                        .receiveContent(setOf(MediaType.All), object : ReceiveContentListener {
+                            override fun onDragStart() {
+                                calls += "start-2"
+                            }
+
+                            override fun onDragEnd() {
+                                calls += "end-2"
+                            }
+
+                            override fun onReceive(
+                                transferableContent: TransferableContent
+                            ): TransferableContent = transferableContent
+                        })
+                ) {
+                    Box(
+                        modifier = Modifier
+                            .align(Alignment.Center)
+                            .size(50.dp)
+                            .receiveContent(setOf(MediaType.All), object : ReceiveContentListener {
+                                override fun onDragStart() {
+                                    calls += "start-3"
+                                }
+
+                                override fun onDragEnd() {
+                                    calls += "end-3"
+                                }
+
+                                override fun onReceive(
+                                    transferableContent: TransferableContent
+                                ): TransferableContent = transferableContent
+                            })
+                    )
+                }
+            }
+        }
+
+        val draggingUri = Uri.parse("content://com.example/content.jpg")
+        testDragAndDrop(view, rule.density) {
+            drag(Offset(225.dp.toPx(), 225.dp.toPx()), draggingUri)
+            cancelDrag()
+        }
+
+        rule.runOnIdle {
+            assertThat(calls.take(3)).containsExactlyElementsIn(
+                listOf("start-1", "start-2", "start-3")
+            )
+            assertThat(calls.drop(3)).containsExactlyElementsIn(
+                listOf("end-1", "end-2", "end-3")
+            )
+        }
+    }
+
+    private data class TestElement(
+        val onNode: (TestNode) -> Unit
+    ) : ModifierNodeElement<TestNode>() {
+        override fun create(): TestNode = TestNode(onNode)
+        override fun update(node: TestNode) {
+            node.onNode = onNode
+        }
+    }
+
+    private class TestNode(
+        var onNode: (TestNode) -> Unit
+    ) : Modifier.Node(), ModifierLocalModifierNode {
+
+        override fun onAttach() {
+            onNode(this)
+        }
     }
 }
 
@@ -201,3 +921,11 @@
     Uri.parse("https://example.com")
 )
 private val defaultUri = Uri.parse("content://com.example.app/image")
+
+@OptIn(ExperimentalFoundationApi::class)
+private val MediaType.Companion.Video: MediaType
+    get() = MediaType("video/*")
+
+@OptIn(ExperimentalFoundationApi::class)
+private val MediaType.Companion.Audio: MediaType
+    get() = MediaType("audio/*")
diff --git a/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/content/TestDragAndDrop.kt b/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/content/TestDragAndDrop.kt
new file mode 100644
index 0000000..bb04b09
--- /dev/null
+++ b/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/content/TestDragAndDrop.kt
@@ -0,0 +1,145 @@
+/*
+ * 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.compose.foundation.content
+
+import android.content.ClipData
+import android.content.ClipDescription
+import android.net.Uri
+import android.view.DragEvent
+import android.view.View
+import androidx.compose.foundation.text2.input.internal.DragAndDropTestUtils
+import androidx.compose.ui.geometry.Offset
+import androidx.compose.ui.unit.Density
+
+/**
+ * A helper scope creator to test multi-window Drag And Drop interactions.
+ */
+internal fun testDragAndDrop(view: View, density: Density, block: DragAndDropScope.() -> Unit) {
+    DragAndDropScopeImpl(view, density).block()
+}
+
+@Suppress("DELEGATED_MEMBER_HIDES_SUPERTYPE_OVERRIDE")
+private class DragAndDropScopeImpl(
+    val view: View,
+    density: Density
+) : DragAndDropScope, Density by density {
+    private var lastDraggingItem: Pair<Offset, Any>? = null
+
+    override fun drag(
+        offset: Offset,
+        item: Any,
+    ) {
+        val _lastDraggingItem = lastDraggingItem
+        if (_lastDraggingItem == null || _lastDraggingItem.second != item) {
+            view.dispatchDragEvent(
+                makeDragEvent(DragEvent.ACTION_DRAG_STARTED, item)
+            )
+        }
+        view.dispatchDragEvent(
+            makeDragEvent(
+                DragEvent.ACTION_DRAG_LOCATION,
+                item = item,
+                offset = offset
+            )
+        )
+        lastDraggingItem = offset to item
+    }
+
+    override fun drop() {
+        val _lastDraggingItem = lastDraggingItem
+        check(_lastDraggingItem != null) { "There are no ongoing dragging event to drop" }
+
+        view.dispatchDragEvent(
+            makeDragEvent(
+                DragEvent.ACTION_DROP,
+                item = _lastDraggingItem.second,
+                offset = _lastDraggingItem.first
+            )
+        )
+    }
+
+    override fun cancelDrag() {
+        view.dispatchDragEvent(
+            DragAndDropTestUtils.makeTextDragEvent(DragEvent.ACTION_DRAG_ENDED)
+        )
+    }
+
+    private fun makeDragEvent(
+        action: Int,
+        item: Any,
+        offset: Offset = Offset.Zero
+    ): DragEvent {
+        return when (item) {
+            is String -> {
+                DragAndDropTestUtils.makeTextDragEvent(action, item, offset)
+            }
+
+            is Uri -> {
+                DragAndDropTestUtils.makeImageDragEvent(action, item, offset)
+            }
+
+            is List<*> -> {
+                val mimeTypes = mutableSetOf<String>()
+                val clipDataItems = mutableListOf<ClipData.Item>()
+                item.filterNotNull().forEach { actualItem ->
+                    when (actualItem) {
+                        is String -> {
+                            mimeTypes.add(ClipDescription.MIMETYPE_TEXT_PLAIN)
+                            clipDataItems.add(ClipData.Item(actualItem))
+                        }
+
+                        is Uri -> {
+                            mimeTypes.add("image/*")
+                            clipDataItems.add(ClipData.Item(actualItem))
+                        }
+                    }
+                }
+                DragAndDropTestUtils.makeDragEvent(
+                    action = action,
+                    items = clipDataItems,
+                    mimeTypes = mimeTypes.toList(),
+                    offset = offset
+                )
+            }
+
+            else -> {
+                DragAndDropTestUtils.makeImageDragEvent(action, offset = offset)
+            }
+        }
+    }
+}
+
+internal interface DragAndDropScope : Density {
+
+    /**
+     * Drags an item which represent the payload to the [offset] location.
+     *
+     * @param item Should either be a [String] or a [Uri]. It can also be a [List] of [String]s or
+     * [Uri]s.
+     */
+    fun drag(offset: Offset, item: Any)
+
+    /**
+     * Drops the previously declared dragging item.
+     */
+    fun drop()
+
+    /**
+     * Cancels the ongoing drag without dropping it.
+     */
+    fun cancelDrag()
+}
diff --git a/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/content/internal/DragAndDropRequestPermissionTest.kt b/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/content/internal/DragAndDropRequestPermissionTest.kt
index 58cd47c..38a4e7a 100644
--- a/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/content/internal/DragAndDropRequestPermissionTest.kt
+++ b/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/content/internal/DragAndDropRequestPermissionTest.kt
@@ -60,7 +60,7 @@
         testNode.dragAndDropRequestPermission(event)
 
         // assert
-        Truth.assertThat(rule.activity.requestedDragAndDropPermission).isNotNull()
+        Truth.assertThat(rule.activity.requestedDragAndDropPermissions).isNotEmpty()
     }
 
     @SdkSuppress(minSdkVersion = 24)
@@ -79,7 +79,7 @@
         testNode.dragAndDropRequestPermission(event)
 
         // assert
-        Truth.assertThat(rule.activity.requestedDragAndDropPermission).isNull()
+        Truth.assertThat(rule.activity.requestedDragAndDropPermissions).isEmpty()
     }
 
     @SdkSuppress(minSdkVersion = 24)
@@ -103,7 +103,7 @@
         testNode.dragAndDropRequestPermission(event)
 
         // assert
-        Truth.assertThat(rule.activity.requestedDragAndDropPermission).isNull()
+        Truth.assertThat(rule.activity.requestedDragAndDropPermissions).isEmpty()
     }
 
     private data class TestElement(
diff --git a/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/pager/BasePagerTest.kt b/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/pager/BasePagerTest.kt
index c6b4947..e629ece 100644
--- a/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/pager/BasePagerTest.kt
+++ b/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/pager/BasePagerTest.kt
@@ -23,7 +23,7 @@
 import androidx.compose.foundation.background
 import androidx.compose.foundation.focusable
 import androidx.compose.foundation.gestures.Orientation
-import androidx.compose.foundation.gestures.snapping.SnapFlingBehavior
+import androidx.compose.foundation.gestures.TargetedFlingBehavior
 import androidx.compose.foundation.gestures.snapping.SnapPosition
 import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.PaddingValues
@@ -129,6 +129,7 @@
         snapPositionalThreshold: Float = 0.5f,
         key: ((index: Int) -> Any)? = null,
         snapPosition: SnapPosition = config.snapPosition.first,
+        flingBehavior: TargetedFlingBehavior? = null,
         pageContent: @Composable PagerScope.(page: Int) -> Unit = { Page(index = it) }
     ) {
 
@@ -138,12 +139,11 @@
             }
             composeView = LocalView.current
             focusManager = LocalFocusManager.current
-            val flingBehavior =
-                PagerDefaults.flingBehavior(
-                    state = state,
-                    pagerSnapDistance = snappingPage,
-                    snapPositionalThreshold = snapPositionalThreshold
-                )
+            val resolvedFlingBehavior = flingBehavior ?: PagerDefaults.flingBehavior(
+                state = state,
+                pagerSnapDistance = snappingPage,
+                snapPositionalThreshold = snapPositionalThreshold
+            )
             CompositionLocalProvider(
                 LocalLayoutDirection provides config.layoutDirection,
                 LocalOverscrollConfiguration provides null
@@ -163,7 +163,7 @@
                         pageSize = pageSize(),
                         userScrollEnabled = userScrollEnabled,
                         reverseLayout = reverseLayout,
-                        flingBehavior = flingBehavior,
+                        flingBehavior = resolvedFlingBehavior,
                         pageSpacing = pageSpacing,
                         contentPadding = contentPadding,
                         pageContent = pageContent,
@@ -287,7 +287,7 @@
         contentPadding: PaddingValues = PaddingValues(0.dp),
         outOfBoundsPageCount: Int = 0,
         pageSize: PageSize = PageSize.Fill,
-        flingBehavior: SnapFlingBehavior = PagerDefaults.flingBehavior(state = state),
+        flingBehavior: TargetedFlingBehavior = PagerDefaults.flingBehavior(state = state),
         pageSpacing: Dp = 0.dp,
         key: ((index: Int) -> Any)? = null,
         snapPosition: SnapPosition = config.snapPosition.first,
@@ -392,6 +392,7 @@
 internal const val DefaultPageCount = 20
 internal const val DefaultAnimationRepetition = 2
 internal val TestOrientation = listOf(Orientation.Vertical, Orientation.Horizontal)
+
 @OptIn(ExperimentalFoundationApi::class)
 internal val AllOrientationsParams = mutableListOf<ParamConfig>().apply {
     for (orientation in TestOrientation) {
@@ -407,6 +408,7 @@
     SnapPosition.Center to "Center",
     SnapPosition.End to "End"
 )
+
 internal fun testContentPaddings(orientation: Orientation) = listOf(
     PaddingValues(0.dp),
     if (orientation == Orientation.Vertical)
diff --git a/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/pager/PagerStateTest.kt b/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/pager/PagerStateTest.kt
index 1b70fff..fbc8903 100644
--- a/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/pager/PagerStateTest.kt
+++ b/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/pager/PagerStateTest.kt
@@ -17,10 +17,16 @@
 package androidx.compose.foundation.pager
 
 import androidx.compose.animation.core.AnimationSpec
+import androidx.compose.animation.core.AnimationState
 import androidx.compose.animation.core.animate
+import androidx.compose.animation.core.animateDecay
+import androidx.compose.animation.core.calculateTargetValue
 import androidx.compose.animation.core.tween
+import androidx.compose.animation.splineBasedDecay
 import androidx.compose.foundation.AutoTestFrameClock
 import androidx.compose.foundation.ExperimentalFoundationApi
+import androidx.compose.foundation.gestures.ScrollScope
+import androidx.compose.foundation.gestures.TargetedFlingBehavior
 import androidx.compose.foundation.gestures.scrollBy
 import androidx.compose.foundation.layout.fillMaxSize
 import androidx.compose.runtime.LaunchedEffect
@@ -32,6 +38,8 @@
 import androidx.test.filters.LargeTest
 import androidx.test.filters.SdkSuppress
 import com.google.common.truth.Truth.assertThat
+import kotlin.math.abs
+import kotlin.math.roundToInt
 import kotlin.test.assertTrue
 import kotlinx.coroutines.Dispatchers
 import kotlinx.coroutines.launch
@@ -461,7 +469,7 @@
     }
 
     @Test
-    fun targetPage_performingFling_shouldGoToPredictedPage() {
+    fun targetPage_performingFlingWithSnapFlingBehavior_shouldGoToPredictedPage() {
         // Arrange
 
         createPager(
@@ -506,6 +514,96 @@
     }
 
     @Test
+    fun targetPage_performingFlingWithCustomFling_shouldGoToPredictedPage() {
+        // Arrange
+        var flingPredictedPage = -1
+        val myCustomFling = object : TargetedFlingBehavior {
+            val decay = splineBasedDecay<Float>(rule.density)
+
+            override suspend fun ScrollScope.performFling(
+                initialVelocity: Float,
+                onRemainingDistanceUpdated: (Float) -> Unit
+            ): Float {
+                val finalOffset = decay.calculateTargetValue(
+                    0.0f,
+                    initialVelocity
+                )
+                val pageDisplacement = finalOffset / pagerState.pageSizeWithSpacing
+                val targetPage = pageDisplacement.roundToInt() + pagerState.currentPage
+                flingPredictedPage = targetPage
+                return if (abs(initialVelocity) > 1f) {
+                    var velocityLeft = initialVelocity
+                    var lastValue = 0f
+                    val animationState = AnimationState(
+                        initialValue = 0f,
+                        initialVelocity = initialVelocity,
+                    )
+                    animationState.animateDecay(decay) {
+                        onRemainingDistanceUpdated(finalOffset - value)
+                        val delta = value - lastValue
+                        val consumed = scrollBy(delta)
+                        lastValue = value
+                        velocityLeft = this.velocity
+                        // avoid rounding errors and stop if anything is unconsumed
+                        if (abs(delta - consumed) > 0.5f) this.cancelAnimation()
+                    }
+                    velocityLeft
+                } else {
+                    initialVelocity
+                }
+            }
+        }
+
+        createPager(
+            pageCount = { 100 },
+            modifier = Modifier.fillMaxSize(),
+            flingBehavior = myCustomFling
+        )
+        rule.runOnIdle { assertThat(pagerState.targetPage).isEqualTo(pagerState.currentPage) }
+
+        // Act
+        // Moving forward
+        rule.mainClock.autoAdvance = false
+        val forwardDelta = pagerSize * scrollForwardSign.toFloat()
+        onPager().performTouchInput {
+            swipeWithVelocityAcrossMainAxis(20000f, forwardDelta)
+        }
+        rule.mainClock.advanceTimeUntil { flingPredictedPage != -1 }
+        var targetPage = pagerState.targetPage
+
+        // wait for targetPage to change
+        rule.mainClock.advanceTimeUntil { pagerState.targetPage != targetPage }
+
+        // Assert
+        // Check if target page changed
+        rule.runOnIdle { assertThat(pagerState.targetPage).isEqualTo(flingPredictedPage) }
+        rule.mainClock.autoAdvance = true // let time run
+        // Check if we actually stopped in the predicted page
+        rule.runOnIdle { assertThat(pagerState.currentPage).isEqualTo(flingPredictedPage) }
+
+        // Act
+        // Moving backward
+        flingPredictedPage = -1
+        rule.mainClock.autoAdvance = false
+        val backwardDelta = -pagerSize * scrollForwardSign.toFloat()
+        onPager().performTouchInput {
+            swipeWithVelocityAcrossMainAxis(20000f, backwardDelta)
+        }
+        rule.mainClock.advanceTimeUntil { flingPredictedPage != -1 }
+        targetPage = pagerState.targetPage
+
+        // wait for targetPage to change
+        rule.mainClock.advanceTimeUntil { pagerState.targetPage != targetPage }
+
+        // Assert
+        // Check if target page changed
+        rule.runOnIdle { assertThat(pagerState.targetPage).isEqualTo(flingPredictedPage) }
+        rule.mainClock.autoAdvance = true // let time run
+        // Check if we actually stopped in the predicted page
+        rule.runOnIdle { assertThat(pagerState.currentPage).isEqualTo(flingPredictedPage) }
+    }
+
+    @Test
     fun targetPage_shouldReflectTargetWithAnimation() {
         // Arrange
 
diff --git a/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/pager/PagerTest.kt b/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/pager/PagerTest.kt
index 091ac12..c486755 100644
--- a/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/pager/PagerTest.kt
+++ b/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/pager/PagerTest.kt
@@ -17,7 +17,7 @@
 package androidx.compose.foundation.pager
 
 import androidx.compose.foundation.ExperimentalFoundationApi
-import androidx.compose.foundation.gestures.snapping.SnapFlingBehavior
+import androidx.compose.foundation.gestures.FlingBehavior
 import androidx.compose.foundation.gestures.snapping.SnapPosition
 import androidx.compose.foundation.layout.Spacer
 import androidx.compose.foundation.layout.fillMaxSize
@@ -317,8 +317,8 @@
 
     @Test
     fun pagerStateChange_flingBehaviorShouldRecreate() {
-        var previousFlingBehavior: SnapFlingBehavior? = null
-        var latestFlingBehavior: SnapFlingBehavior? = null
+        var previousFlingBehavior: FlingBehavior? = null
+        var latestFlingBehavior: FlingBehavior? = null
         val stateHolder = mutableStateOf(PagerState(0, 0.0f) { 10 })
         rule.setContent {
             HorizontalOrVerticalPager(
diff --git a/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/text2/input/TextFieldDragAndDropTest.kt b/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/text2/input/TextFieldDragAndDropTest.kt
index 5e1155e..c32aa761 100644
--- a/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/text2/input/TextFieldDragAndDropTest.kt
+++ b/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/text2/input/TextFieldDragAndDropTest.kt
@@ -16,18 +16,16 @@
 
 package androidx.compose.foundation.text2.input
 
-import android.content.ClipData
-import android.content.ClipDescription
 import android.net.Uri
-import android.view.DragEvent
 import android.view.View
 import androidx.compose.foundation.ExperimentalFoundationApi
+import androidx.compose.foundation.content.DragAndDropScope
+import androidx.compose.foundation.content.testDragAndDrop
 import androidx.compose.foundation.interaction.MutableInteractionSource
 import androidx.compose.foundation.interaction.collectIsHoveredAsState
 import androidx.compose.foundation.layout.width
 import androidx.compose.foundation.text.TEST_FONT_FAMILY
 import androidx.compose.foundation.text2.BasicTextField2
-import androidx.compose.foundation.text2.input.internal.DragAndDropTestUtils
 import androidx.compose.runtime.CompositionLocalProvider
 import androidx.compose.runtime.State
 import androidx.compose.runtime.getValue
@@ -64,7 +62,7 @@
 
     @Test
     fun nonTextContent_isNotAccepted() {
-        rule.testDragAndDrop {
+        rule.setContentAndTestDragAndDrop {
             val startSelection = state.text.selectionInChars
             drag(
                 Offset(fontSize.toPx() * 2, 10f),
@@ -76,33 +74,33 @@
 
     @Test
     fun textContent_isAccepted() {
-        rule.testDragAndDrop {
-            drag(Offset(fontSize.toPx() * 2, 10f))
+        rule.setContentAndTestDragAndDrop {
+            drag(Offset(fontSize.toPx() * 2, 10f), "hello")
             assertThat(state.text.selectionInChars).isEqualTo(TextRange(2))
         }
     }
 
     @Test
     fun draggingText_updatesSelection() {
-        rule.testDragAndDrop {
-            drag(Offset(fontSize.toPx() * 1, 10f))
+        rule.setContentAndTestDragAndDrop {
+            drag(Offset(fontSize.toPx() * 1, 10f), "hello")
             assertThat(state.text.selectionInChars).isEqualTo(TextRange(1))
-            drag(Offset(fontSize.toPx() * 2, 10f))
+            drag(Offset(fontSize.toPx() * 2, 10f), "hello")
             assertThat(state.text.selectionInChars).isEqualTo(TextRange(2))
-            drag(Offset(fontSize.toPx() * 3, 10f))
+            drag(Offset(fontSize.toPx() * 3, 10f), "hello")
             assertThat(state.text.selectionInChars).isEqualTo(TextRange(3))
         }
     }
 
     @Test
     fun draggingText_toEndPadding_updatesSelection() {
-        rule.testDragAndDrop(
+        rule.setContentAndTestDragAndDrop(
             style = TextStyle(textAlign = TextAlign.Center),
             modifier = Modifier.width(300.dp)
         ) {
-            drag(Offset.Zero)
+            drag(Offset.Zero, "hello")
             assertThat(state.text.selectionInChars).isEqualTo(TextRange(0))
-            drag(Offset(295.dp.toPx(), 10f))
+            drag(Offset(295.dp.toPx(), 10f), "hello")
             assertThat(state.text.selectionInChars).isEqualTo(TextRange(4))
         }
     }
@@ -110,12 +108,12 @@
     @Test
     fun interactionSource_receivesHoverEnter_whenDraggingTextEnters() {
         val interactionSource = MutableInteractionSource()
-        rule.testDragAndDrop(
+        rule.setContentAndTestDragAndDrop(
             style = TextStyle(textAlign = TextAlign.Center),
             interactionSource = interactionSource,
             modifier = Modifier.width(200.dp)
         ) {
-            drag(Offset(1f, 1f))
+            drag(Offset(1f, 1f), "hello")
             assertThat(isHovered).isTrue()
         }
     }
@@ -123,15 +121,15 @@
     @Test
     fun interactionSource_receivesHoverExit_whenDraggingTextExits() {
         val interactionSource = MutableInteractionSource()
-        rule.testDragAndDrop(
+        rule.setContentAndTestDragAndDrop(
             style = TextStyle(textAlign = TextAlign.Center),
             interactionSource = interactionSource,
             modifier = Modifier.width(200.dp)
         ) {
-            drag(Offset(1f, 1f))
+            drag(Offset(1f, 1f), "hello")
             assertThat(isHovered).isTrue()
 
-            drag(Offset(1000f, 1f))
+            drag(Offset(1000f, 1f), "hello")
             assertThat(isHovered).isFalse()
         }
     }
@@ -139,12 +137,12 @@
     @Test
     fun interactionSource_receivesHoverExit_whenDraggingTextEnds() {
         val interactionSource = MutableInteractionSource()
-        rule.testDragAndDrop(
+        rule.setContentAndTestDragAndDrop(
             style = TextStyle(textAlign = TextAlign.Center),
             interactionSource = interactionSource,
             modifier = Modifier.width(200.dp)
         ) {
-            drag(Offset(1f, 1f))
+            drag(Offset(1f, 1f), "hello")
             assertThat(isHovered).isTrue()
 
             cancelDrag()
@@ -155,12 +153,12 @@
     @Test
     fun interactionSource_receivesHoverExit_whenDraggingTextDrops() {
         val interactionSource = MutableInteractionSource()
-        rule.testDragAndDrop(
+        rule.setContentAndTestDragAndDrop(
             style = TextStyle(textAlign = TextAlign.Center),
             interactionSource = interactionSource,
             modifier = Modifier.width(200.dp)
         ) {
-            drag(Offset(1f, 1f))
+            drag(Offset(1f, 1f), "hello")
             assertThat(isHovered).isTrue()
 
             drop()
@@ -170,7 +168,7 @@
 
     @Test
     fun droppedText_insertsAtCursor() {
-        rule.testDragAndDrop("Hello World!") {
+        rule.setContentAndTestDragAndDrop("Hello World!") {
             drag(
                 Offset(fontSize.toPx() * 5, 10f),
                 " Awesome"
@@ -183,7 +181,7 @@
 
     @Test
     fun multipleClipDataItems_concatsByNewLine() {
-        rule.testDragAndDrop("aaaa") {
+        rule.setContentAndTestDragAndDrop("aaaa") {
             drag(
                 Offset(fontSize.toPx() * 2, 10f),
                 listOf("Hello", "World")
@@ -193,7 +191,7 @@
         }
     }
 
-    private inline fun ComposeContentTestRule.testDragAndDrop(
+    private fun ComposeContentTestRule.setContentAndTestDragAndDrop(
         textContent: String = "aaaa",
         isWindowFocused: Boolean = false,
         style: TextStyle = TextStyle.Default,
@@ -231,101 +229,18 @@
             }
         }
 
-        DragAndDropTestScope(state, mergedStyle.fontSize, density, isHovered, view!!).block()
+        testDragAndDrop(view!!, density) {
+            DragAndDropTestScope(state, mergedStyle.fontSize, isHovered, this).block()
+        }
     }
 
+    @OptIn(ExperimentalFoundationApi::class)
     private class DragAndDropTestScope(
         val state: TextFieldState,
         val fontSize: TextUnit,
-        density: Density,
         isHovered: State<Boolean>?,
-        private val view: View
-    ) : Density by density {
-        private var lastDraggingItem: Pair<Offset, Any>? = null
-
+        dragAndDropScopeImpl: DragAndDropScope,
+    ) : DragAndDropScope by dragAndDropScopeImpl {
         val isHovered: Boolean by (isHovered ?: mutableStateOf(false))
-
-        fun drag(
-            offset: Offset = Offset.Zero,
-            item: Any = "hello",
-        ) {
-            val _lastDraggingItem = lastDraggingItem
-            if (_lastDraggingItem == null || _lastDraggingItem.second != item) {
-                view.dispatchDragEvent(
-                    makeDragEvent(DragEvent.ACTION_DRAG_STARTED, item)
-                )
-            }
-            view.dispatchDragEvent(
-                makeDragEvent(
-                    DragEvent.ACTION_DRAG_LOCATION,
-                    item = item,
-                    offset = offset
-                )
-            )
-            lastDraggingItem = offset to item
-        }
-
-        fun drop() {
-            val _lastDraggingItem = lastDraggingItem
-            check(_lastDraggingItem != null) { "There are no ongoing dragging event to drop" }
-
-            view.dispatchDragEvent(
-                makeDragEvent(
-                    DragEvent.ACTION_DROP,
-                    item = _lastDraggingItem.second,
-                    offset = _lastDraggingItem.first
-                )
-            )
-        }
-
-        fun cancelDrag() {
-            view.dispatchDragEvent(
-                DragAndDropTestUtils.makeTextDragEvent(DragEvent.ACTION_DRAG_ENDED)
-            )
-        }
-
-        private fun makeDragEvent(
-            action: Int,
-            item: Any,
-            offset: Offset = Offset.Zero
-        ): DragEvent {
-            return when (item) {
-                is String -> {
-                    DragAndDropTestUtils.makeTextDragEvent(action, item, offset)
-                }
-
-                is Uri -> {
-                    DragAndDropTestUtils.makeImageDragEvent(action, item, offset)
-                }
-
-                is List<*> -> {
-                    val mimeTypes = mutableSetOf<String>()
-                    val clipDataItems = mutableListOf<ClipData.Item>()
-                    item.filterNotNull().forEach { actualItem ->
-                        when (actualItem) {
-                            is String -> {
-                                mimeTypes.add(ClipDescription.MIMETYPE_TEXT_PLAIN)
-                                clipDataItems.add(ClipData.Item(actualItem))
-                            }
-
-                            is Uri -> {
-                                mimeTypes.add("image/*")
-                                clipDataItems.add(ClipData.Item(actualItem))
-                            }
-                        }
-                    }
-                    DragAndDropTestUtils.makeDragEvent(
-                        action = action,
-                        items = clipDataItems,
-                        mimeTypes = mimeTypes.toList(),
-                        offset = offset
-                    )
-                }
-
-                else -> {
-                    DragAndDropTestUtils.makeImageDragEvent(action, offset = offset)
-                }
-            }
-        }
     }
 }
diff --git a/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/text2/input/TextFieldReceiveContentTest.kt b/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/text2/input/TextFieldReceiveContentTest.kt
index 8b38004..ded6bb20 100644
--- a/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/text2/input/TextFieldReceiveContentTest.kt
+++ b/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/text2/input/TextFieldReceiveContentTest.kt
@@ -124,7 +124,7 @@
                 state = rememberTextFieldState(),
                 modifier = Modifier
                     .testTag(tag)
-                    .receiveContent(MediaType.Image) { null }
+                    .receiveContent(setOf(MediaType.Image)) { null }
             )
         }
         rule.onNodeWithTag(tag).requestFocus()
@@ -142,10 +142,12 @@
                 modifier = Modifier
                     .testTag(tag)
                     .receiveContent(
-                        MediaType.Image,
-                        MediaType.PlainText,
-                        MediaType.Image,
-                        MediaType.HtmlText
+                        setOf(
+                            MediaType.Image,
+                            MediaType.PlainText,
+                            MediaType.Image,
+                            MediaType.HtmlText
+                        )
                     ) { null }
             )
         }
@@ -165,14 +167,12 @@
     @Test
     fun multiReceiveContent_mergesMediaTypes() {
         inputMethodInterceptor.setContent {
-            Box(modifier = Modifier.receiveContent(
-                MediaType.Text
-            ) { null }) {
+            Box(modifier = Modifier.receiveContent(setOf(MediaType.Text)) { null }) {
                 BasicTextField2(
                     state = rememberTextFieldState(),
                     modifier = Modifier
                         .testTag(tag)
-                        .receiveContent(MediaType.Image) { null }
+                        .receiveContent(setOf(MediaType.Image)) { null }
                 )
             }
         }
@@ -192,13 +192,13 @@
     fun multiReceiveContent_mergesMediaTypes_uniquely() {
         inputMethodInterceptor.setContent {
             Box(modifier = Modifier.receiveContent(
-                MediaType.Text, MediaType.Image
+                setOf(MediaType.Text, MediaType.Image)
             ) { null }) {
                 BasicTextField2(
                     state = rememberTextFieldState(),
                     modifier = Modifier
                         .testTag(tag)
-                        .receiveContent(MediaType.Image) { null }
+                        .receiveContent(setOf(MediaType.Image)) { null }
                 )
             }
         }
@@ -218,9 +218,7 @@
     fun multiReceiveContent_mergesMediaTypes_includingAnotherTraversableNode() {
         inputMethodInterceptor.setContent {
             Box(modifier = Modifier
-                .receiveContent(
-                    MediaType.Text
-                ) { null }
+                .receiveContent(setOf(MediaType.Text)) { null }
                 .dragAndDropTarget({ true }, object : DragAndDropTarget {
                     override fun onDrop(event: DragAndDropEvent): Boolean {
                         return false
@@ -231,7 +229,7 @@
                     state = rememberTextFieldState(),
                     modifier = Modifier
                         .testTag(tag)
-                        .receiveContent(MediaType.Image) { null }
+                        .receiveContent(setOf(MediaType.Image)) { null }
                 )
             }
         }
@@ -255,7 +253,7 @@
                 state = rememberTextFieldState(),
                 modifier = Modifier
                     .testTag(tag)
-                    .receiveContent(MediaType.All) {
+                    .receiveContent(setOf(MediaType.All)) {
                         transferableContent = it
                         null
                     }
@@ -301,7 +299,7 @@
                 state = rememberTextFieldState(),
                 modifier = Modifier
                     .testTag(tag)
-                    .receiveContent(MediaType.All) {
+                    .receiveContent(setOf(MediaType.All)) {
                         transferableContent = it
                         null
                     }
@@ -340,11 +338,11 @@
                 state = rememberTextFieldState(),
                 modifier = Modifier
                     .testTag(tag)
-                    .receiveContent(MediaType.All) {
+                    .receiveContent(setOf(MediaType.All)) {
                         parentTransferableContent = it
                         null
                     }
-                    .receiveContent(MediaType.All) {
+                    .receiveContent(setOf(MediaType.All)) {
                         childTransferableContent = it
                         it
                     }
@@ -385,11 +383,11 @@
                 state = rememberTextFieldState(),
                 modifier = Modifier
                     .testTag(tag)
-                    .receiveContent(MediaType.All) {
+                    .receiveContent(setOf(MediaType.All)) {
                         parentTransferableContent = it
                         null
                     }
-                    .receiveContent(MediaType.All) {
+                    .receiveContent(setOf(MediaType.All)) {
                         childTransferableContent = it
                         null
                     }
@@ -424,7 +422,7 @@
                     state = rememberTextFieldState(),
                     modifier = Modifier
                         .testTag(tag)
-                        .receiveContent(MediaType.Image) {
+                        .receiveContent(setOf(MediaType.Image)) {
                             transferableContent = it
                             null
                         }
@@ -457,7 +455,7 @@
                     state = state,
                     modifier = Modifier
                         .testTag(tag)
-                        .receiveContent(MediaType.Image, MediaType.Text) {
+                        .receiveContent(setOf(MediaType.Image, MediaType.Text)) {
                             it.consumeEach { item ->
                                 // only consume if there's no text
                                 item.text == null
@@ -496,19 +494,19 @@
                     state = state,
                     modifier = Modifier
                         .testTag(tag)
-                        .receiveContent(MediaType.Text) {
+                        .receiveContent(setOf(MediaType.Text)) {
                             transferableContent1 = it
                             it.consumeEach {
                                 it.text.contains("a")
                             }
                         }
-                        .receiveContent(MediaType.Text) {
+                        .receiveContent(setOf(MediaType.Text)) {
                             transferableContent2 = it
                             it.consumeEach {
                                 it.text.contains("b")
                             }
                         }
-                        .receiveContent(MediaType.Text) {
+                        .receiveContent(setOf(MediaType.Text)) {
                             transferableContent3 = it
                             it.consumeEach {
                                 it.text.contains("c")
@@ -550,7 +548,7 @@
                     state = rememberTextFieldState(),
                     modifier = Modifier
                         .testTag(tag)
-                        .receiveContent(MediaType.Image) {
+                        .receiveContent(setOf(MediaType.Image)) {
                             transferableContent = it
                             null
                         }
diff --git a/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/text2/input/internal/AndroidTextInputSessionTest.kt b/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/text2/input/internal/AndroidTextInputSessionTest.kt
index 8659a05..0560732 100644
--- a/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/text2/input/internal/AndroidTextInputSessionTest.kt
+++ b/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/text2/input/internal/AndroidTextInputSessionTest.kt
@@ -20,7 +20,7 @@
 import android.view.View
 import android.view.inputmethod.EditorInfo
 import androidx.compose.foundation.ExperimentalFoundationApi
-import androidx.compose.foundation.content.TransferableContent
+import androidx.compose.foundation.content.internal.ReceiveContentConfiguration
 import androidx.compose.foundation.focusable
 import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.size
@@ -219,8 +219,7 @@
         state: TextFieldState = TextFieldState(),
         imeOptions: ImeOptions = ImeOptions.Default,
         onImeAction: (ImeAction) -> Unit = {},
-        acceptedMimeTypes: Set<String>? = null,
-        onCommitContent: ((TransferableContent) -> Boolean)? = null
+        receiveContentConfiguration: ReceiveContentConfiguration? = null
     ): Nothing = platformSpecificTextInputSession(
         state = TransformedTextFieldState(
             textFieldState = state,
@@ -229,9 +228,8 @@
         ),
         layoutState = TextLayoutState(),
         imeOptions = imeOptions,
-        acceptedMimeTypes = acceptedMimeTypes,
+        receiveContentConfiguration = receiveContentConfiguration,
         onImeAction = onImeAction,
-        onCommitContent = onCommitContent
     )
 
     private inner class TestTextElement : ModifierNodeElement<TestTextNode>() {
diff --git a/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/text2/input/internal/EditorInfoTest.kt b/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/text2/input/internal/EditorInfoTest.kt
index d848862..d55dec4 100644
--- a/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/text2/input/internal/EditorInfoTest.kt
+++ b/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/text2/input/internal/EditorInfoTest.kt
@@ -18,7 +18,6 @@
 
 import android.text.InputType
 import android.view.inputmethod.EditorInfo
-import androidx.compose.foundation.ExperimentalFoundationApi
 import androidx.compose.foundation.text.input.internal.update
 import androidx.compose.ui.text.TextRange
 import androidx.compose.ui.text.input.ImeAction
@@ -27,11 +26,11 @@
 import androidx.compose.ui.text.input.KeyboardType
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.MediumTest
+import androidx.test.filters.SdkSuppress
 import com.google.common.truth.Truth.assertThat
 import org.junit.Test
 import org.junit.runner.RunWith
 
-@OptIn(ExperimentalFoundationApi::class)
 @MediumTest
 @RunWith(AndroidJUnit4::class)
 class EditorInfoTest {
@@ -538,7 +537,43 @@
         assertThat(info.initialSelEnd).isEqualTo(selection.end)
     }
 
-    private fun EditorInfo.update(imeOptions: ImeOptions) {
-        this.update("", TextRange.Zero, imeOptions)
+    @SdkSuppress(minSdkVersion = 25)
+    @Test
+    fun if_not_null_contentMimeTypes_are_set_above25() {
+        val contentMimeTypes = arrayOf("text/*", "image/png")
+        val info = EditorInfo()
+        info.update(ImeOptions.Default, contentMimeTypes)
+
+        assertThat(info.contentMimeTypes).isEqualTo(contentMimeTypes)
+    }
+
+    @SdkSuppress(minSdkVersion = 25)
+    @Test
+    fun if_null_contentMimeTypes_are_not_set() {
+        val contentMimeTypes = arrayOf("text/*", "image/png")
+        val info = EditorInfo()
+        info.update(ImeOptions.Default, contentMimeTypes)
+
+        assertThat(info.contentMimeTypes).isEqualTo(contentMimeTypes)
+
+        info.update(ImeOptions.Default, null)
+        assertThat(info.contentMimeTypes).isEqualTo(contentMimeTypes)
+    }
+
+    @SdkSuppress(maxSdkVersion = 24)
+    @Test
+    fun if_not_null_contentMimeTypes_are_set_below24() {
+        val contentMimeTypes = arrayOf("text/*", "image/png")
+        val info = EditorInfo()
+        info.update(ImeOptions.Default, contentMimeTypes)
+
+        assertThat(info.extras.keySet().any { it.contains("CONTENT_MIME_TYPES") }).isTrue()
+    }
+
+    private fun EditorInfo.update(
+        imeOptions: ImeOptions,
+        contentMimeTypes: Array<String>? = null
+    ) {
+        this.update("", TextRange.Zero, imeOptions, contentMimeTypes)
     }
 }
diff --git a/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/text2/input/internal/TextInputServiceAndroidCursorAnchorInfoTest.kt b/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/text2/input/internal/TextInputServiceAndroidCursorAnchorInfoTest.kt
index 295c466..32b62ca 100644
--- a/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/text2/input/internal/TextInputServiceAndroidCursorAnchorInfoTest.kt
+++ b/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/text2/input/internal/TextInputServiceAndroidCursorAnchorInfoTest.kt
@@ -156,9 +156,8 @@
                 state = transformedState,
                 layoutState = layoutState,
                 imeOptions = ImeOptions.Default,
-                acceptedMimeTypes = null,
+                receiveContentConfiguration = null,
                 onImeAction = null,
-                onCommitContent = null
             )
         }
 
@@ -295,9 +294,8 @@
                 state = transformedState,
                 layoutState = layoutState,
                 imeOptions = ImeOptions.Default,
-                acceptedMimeTypes = null,
+                receiveContentConfiguration = null,
                 onImeAction = null,
-                onCommitContent = null
             )
         }
 
diff --git a/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/text2/input/internal/selection/TextFieldTextToolbarTest.kt b/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/text2/input/internal/selection/TextFieldTextToolbarTest.kt
index 7dd9f63..3e9e1ca 100644
--- a/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/text2/input/internal/selection/TextFieldTextToolbarTest.kt
+++ b/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/text2/input/internal/selection/TextFieldTextToolbarTest.kt
@@ -582,7 +582,7 @@
             toolbar = textToolbar,
             singleLine = true,
             clipboardManager = clipboardManager,
-            modifier = Modifier.receiveContent(MediaType.Image) { null }
+            modifier = Modifier.receiveContent(setOf(MediaType.Image)) { null }
         )
 
         rule.onNodeWithTag(TAG).performTouchInput { click() }
diff --git a/compose/foundation/foundation/src/androidMain/kotlin/androidx/compose/foundation/content/internal/ReceiveContentDragAndDropNode.android.kt b/compose/foundation/foundation/src/androidMain/kotlin/androidx/compose/foundation/content/internal/ReceiveContentDragAndDropNode.android.kt
new file mode 100644
index 0000000..0e63977b2
--- /dev/null
+++ b/compose/foundation/foundation/src/androidMain/kotlin/androidx/compose/foundation/content/internal/ReceiveContentDragAndDropNode.android.kt
@@ -0,0 +1,76 @@
+/*
+ * 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.compose.foundation.content.internal
+
+import androidx.compose.foundation.ExperimentalFoundationApi
+import androidx.compose.foundation.content.TransferableContent
+import androidx.compose.ui.draganddrop.DragAndDropEvent
+import androidx.compose.ui.draganddrop.DragAndDropModifierNode
+import androidx.compose.ui.draganddrop.DragAndDropTarget
+import androidx.compose.ui.draganddrop.toAndroidDragEvent
+import androidx.compose.ui.platform.toClipEntry
+import androidx.compose.ui.platform.toClipMetadata
+
+@OptIn(ExperimentalFoundationApi::class)
+internal actual fun ReceiveContentDragAndDropNode(
+    receiveContentConfiguration: ReceiveContentConfiguration,
+    dragAndDropRequestPermission: (DragAndDropEvent) -> Unit
+): DragAndDropModifierNode {
+    return DragAndDropModifierNode(
+        shouldStartDragAndDrop = {
+            // accept any dragging item. The actual decider will be the onReceive callback.
+            true
+        },
+        target = object : DragAndDropTarget {
+            override fun onStarted(event: DragAndDropEvent) {
+                receiveContentConfiguration.receiveContentListener.onDragStart()
+            }
+
+            override fun onEnded(event: DragAndDropEvent) {
+                receiveContentConfiguration.receiveContentListener.onDragEnd()
+            }
+
+            override fun onEntered(event: DragAndDropEvent) {
+                receiveContentConfiguration.receiveContentListener.onDragEnter()
+            }
+
+            override fun onExited(event: DragAndDropEvent) {
+                receiveContentConfiguration.receiveContentListener.onDragExit()
+            }
+
+            override fun onDrop(event: DragAndDropEvent): Boolean {
+                dragAndDropRequestPermission(event)
+
+                val original = event.toTransferableContent()
+                val remaining = receiveContentConfiguration
+                    .receiveContentListener
+                    .onReceive(original)
+                return original != remaining
+            }
+        })
+}
+
+@OptIn(ExperimentalFoundationApi::class)
+internal fun DragAndDropEvent.toTransferableContent(): TransferableContent {
+    return with(toAndroidDragEvent()) {
+        TransferableContent(
+            clipEntry = clipData.toClipEntry(),
+            clipMetadata = clipDescription.toClipMetadata(),
+            source = TransferableContent.Source.DragAndDrop
+        )
+    }
+}
diff --git a/compose/foundation/foundation/src/androidMain/kotlin/androidx/compose/foundation/text/input/internal/EditorInfo.android.kt b/compose/foundation/foundation/src/androidMain/kotlin/androidx/compose/foundation/text/input/internal/EditorInfo.android.kt
index 769d289..c92e5e8 100644
--- a/compose/foundation/foundation/src/androidMain/kotlin/androidx/compose/foundation/text/input/internal/EditorInfo.android.kt
+++ b/compose/foundation/foundation/src/androidMain/kotlin/androidx/compose/foundation/text/input/internal/EditorInfo.android.kt
@@ -32,7 +32,7 @@
     text: CharSequence,
     selection: TextRange,
     imeOptions: ImeOptions,
-    acceptedMimeTypes: Set<String>? = null
+    contentMimeTypes: Array<String>? = null
 ) {
     this.imeOptions = when (imeOptions.imeAction) {
         ImeAction.Default -> {
@@ -139,8 +139,8 @@
 
     EditorInfoCompat.setInitialSurroundingText(this, text)
 
-    if (acceptedMimeTypes != null) {
-        EditorInfoCompat.setContentMimeTypes(this, acceptedMimeTypes.toTypedArray())
+    if (contentMimeTypes != null) {
+        EditorInfoCompat.setContentMimeTypes(this, contentMimeTypes)
     }
 
     this.imeOptions = this.imeOptions or EditorInfo.IME_FLAG_NO_FULLSCREEN
diff --git a/compose/foundation/foundation/src/androidMain/kotlin/androidx/compose/foundation/text2/input/internal/AndroidTextInputSession.android.kt b/compose/foundation/foundation/src/androidMain/kotlin/androidx/compose/foundation/text2/input/internal/AndroidTextInputSession.android.kt
index 3d4f2916..2995f36 100644
--- a/compose/foundation/foundation/src/androidMain/kotlin/androidx/compose/foundation/text2/input/internal/AndroidTextInputSession.android.kt
+++ b/compose/foundation/foundation/src/androidMain/kotlin/androidx/compose/foundation/text2/input/internal/AndroidTextInputSession.android.kt
@@ -23,6 +23,7 @@
 import androidx.annotation.VisibleForTesting
 import androidx.compose.foundation.ExperimentalFoundationApi
 import androidx.compose.foundation.content.TransferableContent
+import androidx.compose.foundation.content.internal.ReceiveContentConfiguration
 import androidx.compose.foundation.text.input.internal.update
 import androidx.compose.foundation.text2.input.TextFieldCharSequence
 import androidx.compose.ui.platform.PlatformTextInputSession
@@ -42,17 +43,15 @@
     state: TransformedTextFieldState,
     layoutState: TextLayoutState,
     imeOptions: ImeOptions,
-    acceptedMimeTypes: Set<String>?,
-    onImeAction: ((ImeAction) -> Unit)?,
-    onCommitContent: ((TransferableContent) -> Boolean)?,
+    receiveContentConfiguration: ReceiveContentConfiguration?,
+    onImeAction: ((ImeAction) -> Unit)?
 ): Nothing {
     platformSpecificTextInputSession(
         state = state,
         layoutState = layoutState,
         imeOptions = imeOptions,
-        acceptedMimeTypes = acceptedMimeTypes,
+        receiveContentConfiguration = receiveContentConfiguration,
         onImeAction = onImeAction,
-        onCommitContent = onCommitContent,
         composeImm = ComposeInputMethodManager(view)
     )
 }
@@ -62,9 +61,8 @@
     state: TransformedTextFieldState,
     layoutState: TextLayoutState,
     imeOptions: ImeOptions,
-    acceptedMimeTypes: Set<String>?,
+    receiveContentConfiguration: ReceiveContentConfiguration?,
     onImeAction: ((ImeAction) -> Unit)?,
-    onCommitContent: ((TransferableContent) -> Boolean)?,
     composeImm: ComposeInputMethodManager
 ): Nothing {
     coroutineScope {
@@ -120,18 +118,32 @@
                 }
 
                 override fun onCommitContent(transferableContent: TransferableContent): Boolean {
-                    return onCommitContent?.invoke(transferableContent) ?: false
+                    return receiveContentConfiguration?.onCommitContent(transferableContent)
+                        ?: false
                 }
 
                 override fun requestCursorUpdates(cursorUpdateMode: Int) {
                     cursorUpdatesController.requestUpdates(cursorUpdateMode)
                 }
             }
+
+            val hintMediaTypes = receiveContentConfiguration?.hintMediaTypes
+            val contentMimeTypes: Array<String>? =
+                if (!hintMediaTypes.isNullOrEmpty()) {
+                    val arr = Array(hintMediaTypes.size) { "" }
+                    hintMediaTypes.forEachIndexed { i, mediaType ->
+                        arr[i] = mediaType.representation
+                    }
+                    arr
+                } else {
+                    null
+                }
+
             outAttrs.update(
                 text = state.visualText,
                 selection = state.visualText.selectionInChars,
                 imeOptions = imeOptions,
-                acceptedMimeTypes = acceptedMimeTypes
+                contentMimeTypes = contentMimeTypes
             )
             StatelessInputConnection(textInputSession, outAttrs)
         }
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/content/ReceiveContent.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/content/ReceiveContent.kt
index 33296da..90d2762 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/content/ReceiveContent.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/content/ReceiveContent.kt
@@ -17,11 +17,18 @@
 package androidx.compose.foundation.content
 
 import androidx.compose.foundation.ExperimentalFoundationApi
+import androidx.compose.foundation.content.internal.DynamicReceiveContentConfiguration
+import androidx.compose.foundation.content.internal.ModifierLocalReceiveContent
+import androidx.compose.foundation.content.internal.ReceiveContentConfiguration
+import androidx.compose.foundation.content.internal.ReceiveContentDragAndDropNode
+import androidx.compose.foundation.content.internal.dragAndDropRequestPermission
 import androidx.compose.ui.Modifier
-import androidx.compose.ui.node.DelegatableNode
+import androidx.compose.ui.modifier.ModifierLocalMap
+import androidx.compose.ui.modifier.ModifierLocalModifierNode
+import androidx.compose.ui.modifier.modifierLocalMapOf
+import androidx.compose.ui.node.CompositionLocalConsumerModifierNode
 import androidx.compose.ui.node.DelegatingNode
 import androidx.compose.ui.node.ModifierNodeElement
-import androidx.compose.ui.node.TraversableNode
 import androidx.compose.ui.platform.InspectorInfo
 
 /**
@@ -30,11 +37,11 @@
  * Content in this context refers to a [TransferableContent] that could be received from another
  * app through Drag-and-Drop, Copy/Paste, or from the Software Keyboard.
  *
- * @param acceptedMediaTypes A list of media types that are expected by this receiver. This list
+ * @param hintMediaTypes A set of media types that are expected by this receiver. This set
  * gets passed to the Software Keyboard to send information about what type of content the editor
- * supports. It's possible that this modifier receives other type of content that's not listed in
- * this list. Please make sure to check again whether the received [TransferableContent] carries a
- * supported [MediaType].
+ * supports. It's possible that this modifier receives other type of content that's not specified in
+ * this set. Please make sure to check again whether the received [TransferableContent] carries a
+ * supported [MediaType]. An empty [MediaType] set implies [MediaType.All].
  * @param onReceive Callback that's triggered when a content is successfully committed. Return
  * an optional [TransferableContent] that contains the unprocessed or unaccepted parts of the
  * received [TransferableContent]. The remaining [TransferableContent] first will be sent to to the
@@ -48,47 +55,96 @@
  */
 @ExperimentalFoundationApi
 fun Modifier.receiveContent(
-    vararg acceptedMediaTypes: MediaType,
+    hintMediaTypes: Set<MediaType>,
     onReceive: (TransferableContent) -> TransferableContent?
-): Modifier = then(ReceiveContentElement(acceptedMediaTypes.toSet(), onReceive))
+): Modifier = then(
+    ReceiveContentElement(
+        hintMediaTypes = hintMediaTypes,
+        receiveContentListener = ReceiveContentListener(onReceive)
+    )
+)
+
+/**
+ * Configures the current node and any children nodes as a Content Receiver.
+ *
+ * Content in this context refers to a [TransferableContent] that could be received from another
+ * app through Drag-and-Drop, Copy/Paste, or from the Software Keyboard.
+ *
+ * @param hintMediaTypes A set of media types that are expected by this receiver. This set
+ * gets passed to the Software Keyboard to send information about what type of content the editor
+ * supports. It's possible that this modifier receives other type of content that's not specified in
+ * this set. Please make sure to check again whether the received [TransferableContent] carries a
+ * supported [MediaType]. An empty [MediaType] set implies [MediaType.All].
+ * @param receiveContentListener A set of callbacks that includes certain Drag-and-Drop state
+ * changes. Please checkout [ReceiveContentListener] docs for an explanation of each callback.
+ *
+ * @sample androidx.compose.foundation.samples.ReceiveContentFullSample
+ */
+@Suppress("ExecutorRegistration")
+@ExperimentalFoundationApi
+fun Modifier.receiveContent(
+    hintMediaTypes: Set<MediaType>,
+    receiveContentListener: ReceiveContentListener
+): Modifier = then(
+    ReceiveContentElement(
+        hintMediaTypes = hintMediaTypes.toSet(),
+        receiveContentListener = receiveContentListener
+    )
+)
 
 @OptIn(ExperimentalFoundationApi::class)
 internal data class ReceiveContentElement(
-    val acceptedMediaTypes: Set<MediaType>,
-    val onReceive: (TransferableContent) -> TransferableContent?
+    val hintMediaTypes: Set<MediaType>,
+    val receiveContentListener: ReceiveContentListener
 ) : ModifierNodeElement<ReceiveContentNode>() {
     override fun create(): ReceiveContentNode {
-        return ReceiveContentNode(acceptedMediaTypes, onReceive)
+        return ReceiveContentNode(hintMediaTypes, receiveContentListener)
     }
 
     override fun update(node: ReceiveContentNode) {
-        node.updateNode(acceptedMediaTypes, onReceive)
+        node.updateNode(hintMediaTypes, receiveContentListener)
     }
 
     override fun InspectorInfo.inspectableProperties() {
         name = "receiveContent"
-        properties["acceptedMediaType"] = acceptedMediaTypes
+        properties["hintMediaTypes"] = hintMediaTypes
     }
 }
 
+// This node uses ModifierLocals instead of TraversableNode to find ancestor due to b/311181532.
+// Since the usage of modifier locals are minimal and exactly correspond to how we would use
+// TraversableNode if it was available, the switch should be fairly easy when the bug is fixed.
 @OptIn(ExperimentalFoundationApi::class)
 internal class ReceiveContentNode(
-    var acceptedMediaTypes: Set<MediaType>,
-    var onReceive: (TransferableContent) -> TransferableContent?
-) : DelegatingNode(), DelegatableNode, TraversableNode {
+    var hintMediaTypes: Set<MediaType>,
+    var receiveContentListener: ReceiveContentListener
+) : DelegatingNode(), ModifierLocalModifierNode,
+    CompositionLocalConsumerModifierNode {
 
-    /**
-     * The key to find this type of node while traversing a node chain.
-     */
-    internal object ReceiveContentTraversableKey
+    private val receiveContentConfiguration: ReceiveContentConfiguration =
+        DynamicReceiveContentConfiguration(this)
 
-    override val traverseKey: Any = ReceiveContentTraversableKey
+    // The default provided configuration is the one supplied to this node. Once the node is
+    // attached, it should provide a delegating version to ancestor nodes.
+    override val providedValues: ModifierLocalMap =
+        modifierLocalMapOf<ReceiveContentConfiguration?>(
+            ModifierLocalReceiveContent to receiveContentConfiguration
+        )
+
+    init {
+        delegate(
+            ReceiveContentDragAndDropNode(
+                receiveContentConfiguration = receiveContentConfiguration,
+                dragAndDropRequestPermission = { dragAndDropRequestPermission(it) }
+            )
+        )
+    }
 
     fun updateNode(
-        acceptedMediaTypes: Set<MediaType>,
-        onReceive: (TransferableContent) -> TransferableContent?
+        hintMediaTypes: Set<MediaType>,
+        receiveContentListener: ReceiveContentListener
     ) {
-        this.acceptedMediaTypes = acceptedMediaTypes
-        this.onReceive = onReceive
+        this.hintMediaTypes = hintMediaTypes
+        this.receiveContentListener = receiveContentListener
     }
 }
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/content/ReceiveContentListener.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/content/ReceiveContentListener.kt
new file mode 100644
index 0000000..40934de
--- /dev/null
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/content/ReceiveContentListener.kt
@@ -0,0 +1,108 @@
+/*
+ * 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.compose.foundation.content
+
+import androidx.compose.foundation.ExperimentalFoundationApi
+import androidx.compose.foundation.draganddrop.dragAndDropTarget
+
+/**
+ * A set of callbacks for [receiveContent] modifier to get information about certain Drag-and-Drop
+ * state changes, as well as receiving the payload carrying [TransferableContent].
+ *
+ * [receiveContent]'s drop target supports nesting. When two [receiveContent] modifiers are nested
+ * on the composition tree, parent's drop target actually includes child's bounds, meaning that
+ * they are not mutually exclusive like the regular [dragAndDropTarget].
+ *
+ * Let's assume we have two [receiveContent] boxes named A and B where B is a child of A, aligned
+ * to bottom end.
+ *
+ * ---------
+ * | A     |
+ * |   |---|
+ * |   | B |
+ * ---------
+ *
+ * When a dragging item moves over to A from left, then over to B, then starts moving up and goes
+ * back to A leaving B, then finally leaves them both, the following would be the list of expected
+ * [ReceiveContentListener] calls in order to both nodes.
+ *
+ * - A#onStart
+ * - B#onStart
+ * - A#onEnter
+ * - B#onEnter
+ * - B#onExit
+ * - A#onExit
+ * - B#onEnd
+ * - A#onEnd
+ *
+ * The interesting part in this order of calls is that A does not receive an exit event when the
+ * item moves over to B. This is different than what would happen if you were to use
+ * [dragAndDropTarget] modifier because semantically [receiveContent] works as a chain of nodes.
+ * If the item were to be dropped on B, its [onReceive] chain would also call A's [onReceive] with
+ * what's left from B.
+ */
+@ExperimentalFoundationApi
+interface ReceiveContentListener {
+
+    /**
+     * Optional callback that's called when a dragging session starts. All [receiveContent] nodes
+     * in the current composition tree receives this callback immediately.
+     */
+    fun onDragStart() = Unit
+
+    /**
+     * Optional callback that's called when a dragging session ends by either successful drop, or
+     * cancellation. All [receiveContent] nodes in the current composition tree receives this
+     * callback immediately.
+     */
+    fun onDragEnd() = Unit
+
+    /**
+     * Optional callback that's called when a dragging item moves into this node's coordinates.
+     */
+    fun onDragEnter() = Unit
+
+    /**
+     * Optional callback that's called when a dragging item moves out of this node's coordinates.
+     */
+    fun onDragExit() = Unit
+
+    /**
+     * Callback that's triggered when a content is successfully committed.
+     * Return an optional [TransferableContent] that contains the ignored parts of the received
+     * [TransferableContent] by this node. The remaining [TransferableContent] first will be sent to
+     * to the closest ancestor [receiveContent] modifier. This chain will continue until there's no
+     * ancestor modifier left, or [TransferableContent] is fully consumed. After, the source
+     * subsystem that created the original [TransferableContent] and initiated the chain will
+     * receive any remaining items to apply its default behavior. For example a text editor that
+     * receives content by DragAndDrop should insert the remaining text from the receive chain
+     * to the drop position.
+     */
+    fun onReceive(transferableContent: TransferableContent): TransferableContent?
+}
+
+@OptIn(ExperimentalFoundationApi::class)
+internal fun ReceiveContentListener(
+    onReceive: (TransferableContent) -> TransferableContent?
+): ReceiveContentListener {
+    val paramOnReceive = onReceive
+    return object : ReceiveContentListener {
+        override fun onReceive(transferableContent: TransferableContent): TransferableContent? {
+            return paramOnReceive(transferableContent)
+        }
+    }
+}
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/content/internal/ReceiveContentConfiguration.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/content/internal/ReceiveContentConfiguration.kt
index d3664b38..dbe906e 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/content/internal/ReceiveContentConfiguration.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/content/internal/ReceiveContentConfiguration.kt
@@ -19,81 +19,195 @@
 package androidx.compose.foundation.content.internal
 
 import androidx.compose.foundation.ExperimentalFoundationApi
+import androidx.compose.foundation.content.MediaType
+import androidx.compose.foundation.content.ReceiveContentListener
 import androidx.compose.foundation.content.ReceiveContentNode
 import androidx.compose.foundation.content.TransferableContent
-import androidx.compose.ui.node.DelegatableNode
-import androidx.compose.ui.node.traverseAncestors
+import androidx.compose.foundation.content.receiveContent
+import androidx.compose.ui.modifier.ModifierLocalModifierNode
+import androidx.compose.ui.modifier.modifierLocalOf
 
-internal data class ReceiveContentConfiguration(
-    val acceptedMimeTypes: Set<String>,
-    val onReceive: (TransferableContent) -> TransferableContent?
-) {
-    /**
-     * `InputConnection#commitContent` callback that's delegates to [onReceive], then returns true
-     * if the remaining content is different than the original content, which indicates a
-     * consumption.
-     */
-    val onCommitContent: (TransferableContent) -> Boolean = { content ->
-        val remaining = onReceive(content)
-        remaining != content
+internal abstract class ReceiveContentConfiguration {
+    abstract val hintMediaTypes: Set<MediaType>
+    abstract val receiveContentListener: ReceiveContentListener
+
+    fun onCommitContent(transferableContent: TransferableContent): Boolean {
+        val remaining = receiveContentListener.onReceive(transferableContent)
+        return remaining != transferableContent
+    }
+
+    companion object {
+        operator fun invoke(
+            hintMediaTypes: Set<MediaType>,
+            receiveContentListener: ReceiveContentListener
+        ): ReceiveContentConfiguration = ReceiveContentConfigurationImpl(
+            hintMediaTypes, receiveContentListener
+        )
     }
 }
 
+private data class ReceiveContentConfigurationImpl(
+    override val hintMediaTypes: Set<MediaType>,
+    override val receiveContentListener: ReceiveContentListener
+) : ReceiveContentConfiguration()
+
+internal val ModifierLocalReceiveContent = modifierLocalOf<ReceiveContentConfiguration?> { null }
+
 /**
- * Travels among ancestor nodes to find each [ReceiveContentNode] that would be interested
- * in the content that's sent by the IME.
- *
- * - acceptedMimeTypes of each node is merged together since each node has a right to register
- * its interest.
- * - onReceive callbacks are also chained from inner most (closest ancestor) to outer most
- * (furthest ancestor). Each node receives a [TransferableContent], then returns another or the
- * same [TransferableContent] indicating what's left unconsumed and should be delegated to
- * the rest of the chain.
+ * In a [ModifierLocalModifierNode], reads the current [ReceiveContentConfiguration] that's supplied
+ * by [ModifierLocalReceiveContent] if the node is currently attached.
  */
-internal fun DelegatableNode.mergeReceiveContentConfiguration(): ReceiveContentConfiguration? {
-    // do not pre-allocate
-    var mutableAcceptedMimeTypes: MutableSet<String>? = null
-    var mutableOnReceiveCallbacks: MutableList<(TransferableContent) -> TransferableContent?>? =
-        null
-    traverseAncestors(
-        ReceiveContentNode.ReceiveContentTraversableKey
-    ) { traversableNode ->
-        val receiveContentNode = traversableNode as? ReceiveContentNode
-            ?: return@traverseAncestors true
+internal fun ModifierLocalModifierNode.getReceiveContentConfiguration() = if (node.isAttached) {
+    ModifierLocalReceiveContent.current
+} else {
+    null
+}
 
-        if (mutableAcceptedMimeTypes == null) mutableAcceptedMimeTypes = mutableSetOf()
-        if (mutableOnReceiveCallbacks == null) mutableOnReceiveCallbacks = mutableListOf()
+/**
+ * Combines the current [ReceiveContentNode]'s [ReceiveContentConfiguration] with the parent
+ * [ReceiveContentNode]s'. It also counts the drag and drop enter/exit calls to merge drag and drop
+ * areas of parent/children [ReceiveContentListener]s. Unlike regular drop targets, ReceiveContent
+ * does not call onExit when the dragging item moves from parent node to child node since they
+ * share the same boundaries.
+ */
+@OptIn(ExperimentalFoundationApi::class)
+internal class DynamicReceiveContentConfiguration(
+    val receiveContentNode: ReceiveContentNode
+) : ReceiveContentConfiguration() {
 
-        receiveContentNode.acceptedMediaTypes.forEach {
-            mutableAcceptedMimeTypes?.add(it.representation)
+    /**
+     * The set of media types that were read from the ancestor nodes when [cachedHintMediaTypes]
+     * was last calculated.
+     */
+    private var lastParentHintMediaTypes: Set<MediaType>? = null
+
+    /**
+     * The set of media types that were configured for this node when [cachedHintMediaTypes]
+     * was last calculated.
+     */
+    private var lastHintMediaTypes: Set<MediaType>? = null
+
+    /**
+     * The merged set of [lastParentHintMediaTypes] and [lastHintMediaTypes]. [hintMediaTypes]
+     * should always return this value.
+     */
+    private var cachedHintMediaTypes: Set<MediaType> = receiveContentNode.hintMediaTypes
+
+    override val hintMediaTypes: Set<MediaType>
+        get() {
+            val fromParent = with(receiveContentNode) {
+                getReceiveContentConfiguration()?.hintMediaTypes
+            }
+            val fromNode = receiveContentNode.hintMediaTypes
+            var calculatedHintMediaTypes = when {
+                // do not allocate again. return the last merged set.
+                fromParent == lastParentHintMediaTypes && fromNode == lastHintMediaTypes ->
+                    cachedHintMediaTypes
+                // nothing coming from top, we can just return this node's configuration.
+                fromParent == null -> fromNode
+                // there's a change from the last calculation, recalculate
+                else -> fromNode + fromParent
+            }
+
+            if (calculatedHintMediaTypes.isEmpty()) {
+                calculatedHintMediaTypes = setOf(MediaType.All)
+            }
+
+            // after calculating the result, cache the inputs and the output before returning.
+            lastParentHintMediaTypes = fromParent
+            lastHintMediaTypes = fromNode
+            cachedHintMediaTypes = calculatedHintMediaTypes
+
+            return calculatedHintMediaTypes
         }
 
-        mutableOnReceiveCallbacks?.add(receiveContentNode.onReceive)
-        true
+    /**
+     * A getter that returns the closest [receiveContent] modifier configuration if this node is
+     * attached. It returns null if the node is detached or there is no parent [receiveContent]
+     * found.
+     */
+    private fun getParentReceiveContentListener(): ReceiveContentListener? {
+        return receiveContentNode.getReceiveContentConfiguration()?.receiveContentListener
     }
 
-    // InputConnection#onCommitContent requires a boolean return value indicating that some
-    // part of the content is consumed by the app in some way. Meanwhile regular ReceiveContent
-    // callback expects TransferableContent items to be returned. Here we do a conversion from
-    // content based callback to boolean based callback.
-    // If the remaining items returned from the callback chain is different than the one
-    // we started with, it is regarded as an action has been taken and we return true.
-    val acceptedMimeTypes = mutableAcceptedMimeTypes
-    val onReceiveCallbacks = mutableOnReceiveCallbacks
+    override val receiveContentListener: ReceiveContentListener = object : ReceiveContentListener {
+        /**
+         * ---------
+         * | A     |
+         * |   |---|
+         * |   | B |
+         * ---------
+         *
+         * DragAndDrop's own callbacks do not work well with nested content. Simply, when B is
+         * nested in A, and the dragging item moves from (A\B) to (A∩B), A receives an exit event
+         * and B receives an enter event. From ReceiveContent's chaining perspective, anything
+         * that gets dropped on B is also dropped on A. Hence, A should not receive an exit event
+         * when the item moves over B.
+         *
+         * This variable counts the difference between number of times enter and exit are called,
+         * but not just on this node. ReceiveContent chaining makes sure that every enter event
+         * that B receives is also delegated A. For example;
+         *
+         * - Dragging item moves onto A.
+         *   - A receives an enter event from DragAndDrop system. Enter=1, Exit=0
+         * - Dragging item moves onto B.
+         *   - A receives an exit event from DragAndDrop system. Enter=1, Exit=1.
+         *   - B receives an enter event from DragAndDrop system.
+         *     - B delegates this to A.
+         *     - A receives an enter event from B. Enter=2, Exit=1
+         *
+         * In conclusion, nodeEnterCount would be 1, meaning that this node is still hovered.
+         */
+        private var nodeEnterCount: Int = 0
 
-    if (acceptedMimeTypes.isNullOrEmpty() || onReceiveCallbacks.isNullOrEmpty()) {
-        return null
-    }
-
-    val mergedOnReceive: ((TransferableContent) -> TransferableContent?) = {
-        // The order of callbacks go from closest node to furthest node
-        var remaining: TransferableContent? = it
-        var index = 0
-        while (remaining != null && index < onReceiveCallbacks.size) {
-            remaining = onReceiveCallbacks[index].invoke(remaining)
-            index++
+        override fun onDragStart() {
+            // no need to call parent on this because all nodes are going to receive
+            // onStart at the same time from DragAndDrop system.
+            nodeEnterCount = 0
+            receiveContentNode.receiveContentListener.onDragStart()
         }
-        remaining
+
+        override fun onDragEnd() {
+            // no need to call parent on this because all nodes are going to receive
+            // onEnd at the same time from DragAndDrop system.
+            receiveContentNode.receiveContentListener.onDragEnd()
+            nodeEnterCount = 0
+        }
+
+        override fun onDragEnter() {
+            nodeEnterCount++
+            if (nodeEnterCount == 1) {
+                // enter became 1 from 0. Trigger the callback.
+                receiveContentNode.receiveContentListener.onDragEnter()
+            }
+            // We need to call enter on parent because they will receive onExit from their
+            // own DragAndDropTarget.
+            getParentReceiveContentListener()?.onDragEnter()
+        }
+
+        override fun onDragExit() {
+            val previous = nodeEnterCount
+            nodeEnterCount = (nodeEnterCount - 1).coerceAtLeast(0)
+            if (nodeEnterCount == 0 && previous > 0) {
+                receiveContentNode.receiveContentListener.onDragExit()
+            }
+            // We need to call exit on parent because they also received an enter from us.
+            getParentReceiveContentListener()?.onDragExit()
+        }
+
+        override fun onReceive(transferableContent: TransferableContent): TransferableContent? {
+            // first let this node do whatever it wants. If it consumes everything, we can end
+            // the chain here.
+            val remaining = receiveContentNode
+                .receiveContentListener
+                .onReceive(transferableContent) ?: return null
+
+            // Check whether we have a parent node. If not, we can return the remaining here.
+            val parentReceiveContentListener = getParentReceiveContentListener()
+                ?: return remaining
+
+            // Delegate the rest to the parent node to continue the chain.
+            return parentReceiveContentListener.onReceive(remaining)
+        }
     }
-    return ReceiveContentConfiguration(acceptedMimeTypes, mergedOnReceive)
 }
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/content/internal/ReceiveContentDragAndDropNode.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/content/internal/ReceiveContentDragAndDropNode.kt
new file mode 100644
index 0000000..d49df0d
--- /dev/null
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/content/internal/ReceiveContentDragAndDropNode.kt
@@ -0,0 +1,25 @@
+/*
+ * 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.compose.foundation.content.internal
+
+import androidx.compose.ui.draganddrop.DragAndDropEvent
+import androidx.compose.ui.draganddrop.DragAndDropModifierNode
+
+internal expect fun ReceiveContentDragAndDropNode(
+    receiveContentConfiguration: ReceiveContentConfiguration,
+    dragAndDropRequestPermission: (DragAndDropEvent) -> Unit
+): DragAndDropModifierNode
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/gestures/snapping/LazyGridSnapLayoutInfoProvider.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/gestures/snapping/LazyGridSnapLayoutInfoProvider.kt
index 13c1420..9f6aaf7 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/gestures/snapping/LazyGridSnapLayoutInfoProvider.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/gestures/snapping/LazyGridSnapLayoutInfoProvider.kt
@@ -16,7 +16,6 @@
 
 package androidx.compose.foundation.gestures.snapping
 
-import androidx.compose.foundation.ExperimentalFoundationApi
 import androidx.compose.foundation.gestures.Orientation
 import androidx.compose.foundation.lazy.grid.LazyGridItemInfo
 import androidx.compose.foundation.lazy.grid.LazyGridLayoutInfo
@@ -33,7 +32,6 @@
  *
  * @return A [SnapLayoutInfoProvider] that can be used with [SnapFlingBehavior]
  */
-@ExperimentalFoundationApi
 fun SnapLayoutInfoProvider(
     lazyGridState: LazyGridState,
     snapPosition: SnapPosition = SnapPosition.Center
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/gestures/snapping/LazyListSnapLayoutInfoProvider.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/gestures/snapping/LazyListSnapLayoutInfoProvider.kt
index 10444eb..73fc7ad 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/gestures/snapping/LazyListSnapLayoutInfoProvider.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/gestures/snapping/LazyListSnapLayoutInfoProvider.kt
@@ -16,7 +16,6 @@
 
 package androidx.compose.foundation.gestures.snapping
 
-import androidx.compose.foundation.ExperimentalFoundationApi
 import androidx.compose.foundation.gestures.FlingBehavior
 import androidx.compose.foundation.gestures.Orientation
 import androidx.compose.foundation.lazy.LazyListLayoutInfo
@@ -37,7 +36,6 @@
  *
  * @return A [SnapLayoutInfoProvider] that can be used with [SnapFlingBehavior]
  */
-@ExperimentalFoundationApi
 fun SnapLayoutInfoProvider(
     lazyListState: LazyListState,
     snapPosition: SnapPosition = SnapPosition.Center
@@ -89,7 +87,6 @@
  * @param lazyListState The [LazyListState] from the LazyList where this [FlingBehavior] will
  * be used.
  */
-@ExperimentalFoundationApi
 @Composable
 fun rememberSnapFlingBehavior(lazyListState: LazyListState): FlingBehavior {
     val snappingLayout = remember(lazyListState) { SnapLayoutInfoProvider(lazyListState) }
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/gestures/snapping/SnapFlingBehavior.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/gestures/snapping/SnapFlingBehavior.kt
index a0fa6f7..ab8ddfc 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/gestures/snapping/SnapFlingBehavior.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/gestures/snapping/SnapFlingBehavior.kt
@@ -29,7 +29,6 @@
 import androidx.compose.animation.core.copy
 import androidx.compose.animation.core.spring
 import androidx.compose.animation.rememberSplineBasedDecay
-import androidx.compose.foundation.ExperimentalFoundationApi
 import androidx.compose.foundation.gestures.DefaultScrollMotionDurationScale
 import androidx.compose.foundation.gestures.FlingBehavior
 import androidx.compose.foundation.gestures.ScrollScope
@@ -65,56 +64,12 @@
  * @param snapAnimationSpec The animation spec used to finally snap to the correct bound.
  *
  */
-@ExperimentalFoundationApi
 class SnapFlingBehavior(
     private val snapLayoutInfoProvider: SnapLayoutInfoProvider,
     private val decayAnimationSpec: DecayAnimationSpec<Float>,
     private val snapAnimationSpec: AnimationSpec<Float>
 ) : TargetedFlingBehavior {
 
-    /**
-     * A [FlingBehavior] that performs snapping of items to a given position. The algorithm will
-     * differentiate between short/scroll snapping and long/fling snapping.
-     *
-     * A short snap usually happens after a fling with low velocity.
-     *
-     * When long snapping, you can use [SnapLayoutInfoProvider.calculateApproachOffset] to
-     * indicate that snapping should happen after this offset. If the velocity generated by the
-     * fling is high enough to get there, we'll use [highVelocityAnimationSpec] to get to that
-     * offset and then we'll snap to the next bound calculated by
-     * [SnapLayoutInfoProvider.calculateSnappingOffset] using [snapAnimationSpec].
-     *
-     * If the velocity is not high enough, we'll use [lowVelocityAnimationSpec] to approach and then
-     * use [snapAnimationSpec] to snap into place.
-     *
-     * Please refer to the sample to learn how to use this API.
-     * @sample androidx.compose.foundation.samples.SnapFlingBehaviorSimpleSample
-     * @sample androidx.compose.foundation.samples.SnapFlingBehaviorCustomizedSample
-     *
-     * @param snapLayoutInfoProvider The information about the layout being snapped.
-     * @param lowVelocityAnimationSpec The animation spec used to approach the target offset. When
-     * the fling velocity is not large enough. Large enough means large enough to naturally decay.
-     * @param highVelocityAnimationSpec The animation spec used to approach the target offset. When
-     * the fling velocity is large enough. Large enough means large enough to naturally decay.
-     * @param snapAnimationSpec The animation spec used to finally snap to the correct bound.
-     *
-     */
-    @Suppress("UNUSED_PARAMETER")
-    @Deprecated(
-        "Please use the constructor without the lowVelocityAnimationSpec.",
-        level = DeprecationLevel.ERROR
-    )
-    constructor(
-        snapLayoutInfoProvider: SnapLayoutInfoProvider,
-        lowVelocityAnimationSpec: AnimationSpec<Float>,
-        highVelocityAnimationSpec: DecayAnimationSpec<Float>,
-        snapAnimationSpec: AnimationSpec<Float>,
-    ) : this(
-        snapLayoutInfoProvider,
-        highVelocityAnimationSpec,
-        snapAnimationSpec
-    )
-
     internal var motionScaleDuration = DefaultScrollMotionDurationScale
 
     /**
@@ -311,7 +266,6 @@
  * Creates and remember a [FlingBehavior] that performs snapping.
  * @param snapLayoutInfoProvider The information about the layout that will do snapping
  */
-@ExperimentalFoundationApi
 @Composable
 fun rememberSnapFlingBehavior(
     snapLayoutInfoProvider: SnapLayoutInfoProvider
@@ -342,7 +296,6 @@
  * define too far as over half a step offset away) we continue the approach animation a bit further
  * and leave the remainder to be snapped.
  */
-@OptIn(ExperimentalFoundationApi::class)
 private suspend fun ScrollScope.approach(
     initialTargetOffset: Float,
     initialVelocity: Float,
@@ -483,7 +436,6 @@
     ): AnimationResult<T, V>
 }
 
-@OptIn(ExperimentalFoundationApi::class)
 private class TargetApproachAnimation(
     private val animationSpec: AnimationSpec<Float>
 ) : ApproachAnimation<Float, AnimationVector1D> {
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/gestures/snapping/SnapLayoutInfoProvider.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/gestures/snapping/SnapLayoutInfoProvider.kt
index 17afc80..4285b0f 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/gestures/snapping/SnapLayoutInfoProvider.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/gestures/snapping/SnapLayoutInfoProvider.kt
@@ -16,8 +16,6 @@
 
 package androidx.compose.foundation.gestures.snapping
 
-import androidx.compose.foundation.ExperimentalFoundationApi
-
 /**
  * Provides information about the layout that is using a SnapFlingBehavior.
  * The provider should give the following information:
@@ -31,7 +29,6 @@
  * we'll naturally decay if possible. In the snapping phase, [SnapFlingBehavior] will use an
  * animation to consume all of the offset provided by [calculateSnappingOffset].
  */
-@ExperimentalFoundationApi
 interface SnapLayoutInfoProvider {
 
     /**
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/pager/LazyLayoutPager.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/pager/LazyLayoutPager.kt
index 99a40f1..973ed6d 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/pager/LazyLayoutPager.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/pager/LazyLayoutPager.kt
@@ -20,7 +20,10 @@
 import androidx.compose.animation.core.spring
 import androidx.compose.foundation.ExperimentalFoundationApi
 import androidx.compose.foundation.gestures.BringIntoViewSpec
+import androidx.compose.foundation.gestures.FlingBehavior
 import androidx.compose.foundation.gestures.Orientation
+import androidx.compose.foundation.gestures.ScrollScope
+import androidx.compose.foundation.gestures.TargetedFlingBehavior
 import androidx.compose.foundation.gestures.awaitEachGesture
 import androidx.compose.foundation.gestures.awaitFirstDown
 import androidx.compose.foundation.gestures.snapping.SnapFlingBehavior
@@ -57,6 +60,7 @@
 import androidx.compose.ui.unit.dp
 import androidx.compose.ui.util.fastAll
 import kotlin.math.absoluteValue
+import kotlin.math.roundToInt
 import kotlinx.coroutines.coroutineScope
 
 @ExperimentalFoundationApi
@@ -73,7 +77,7 @@
     /** The layout orientation of the Pager */
     orientation: Orientation,
     /** fling behavior to be used for flinging */
-    flingBehavior: SnapFlingBehavior,
+    flingBehavior: TargetedFlingBehavior,
     /** Whether scrolling via the user gestures is allowed. */
     userScrollEnabled: Boolean,
     /** Number of pages to compose and layout before and after the visible pages */
@@ -121,16 +125,16 @@
         pageCount = { state.pageCount }
     )
 
-    val pagerFlingBehavior = remember(flingBehavior, state) {
-        PagerWrapperFlingBehavior(flingBehavior, state)
-    }
-
     val semanticState = rememberPagerSemanticState(
         state,
         reverseLayout,
         orientation == Orientation.Vertical
     )
 
+    val resolvedFlingBehavior = remember(state, flingBehavior) {
+        PagerWrapperFlingBehavior(flingBehavior, state)
+    }
+
     val pagerBringIntoViewSpec = remember(state) { PagerBringIntoViewSpec(state) }
 
     val coroutineScope = rememberCoroutineScope()
@@ -163,7 +167,7 @@
                 orientation = orientation,
                 enabled = userScrollEnabled,
                 reverseScrolling = reverseLayout,
-                flingBehavior = pagerFlingBehavior,
+                flingBehavior = resolvedFlingBehavior,
                 interactionSource = state.internalInteractionSource,
                 bringIntoViewSpec = pagerBringIntoViewSpec
             )
@@ -320,3 +324,25 @@
         }
     }
 }
+
+/**
+ * Wraps [SnapFlingBehavior] to give out information about target page coming from flings.
+ */
+@OptIn(ExperimentalFoundationApi::class)
+private class PagerWrapperFlingBehavior(
+    val originalFlingBehavior: TargetedFlingBehavior,
+    val pagerState: PagerState
+) : FlingBehavior {
+    override suspend fun ScrollScope.performFling(initialVelocity: Float): Float {
+        val scope: ScrollScope = this
+        return with(originalFlingBehavior) {
+            performFling(initialVelocity) { remainingScrollOffset ->
+                val flingPageDisplacement = remainingScrollOffset / (pagerState.pageSizeWithSpacing)
+                val targetPage = flingPageDisplacement.roundToInt() + pagerState.currentPage
+                with(pagerState) {
+                    scope.updateTargetPage(targetPage)
+                }
+            }
+        }
+    }
+}
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/pager/Pager.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/pager/Pager.kt
index 391cfa6..13b10ea 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/pager/Pager.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/pager/Pager.kt
@@ -27,7 +27,7 @@
 import androidx.compose.foundation.ExperimentalFoundationApi
 import androidx.compose.foundation.gestures.FlingBehavior
 import androidx.compose.foundation.gestures.Orientation
-import androidx.compose.foundation.gestures.ScrollScope
+import androidx.compose.foundation.gestures.TargetedFlingBehavior
 import androidx.compose.foundation.gestures.snapping.SnapFlingBehavior
 import androidx.compose.foundation.gestures.snapping.SnapLayoutInfoProvider
 import androidx.compose.foundation.gestures.snapping.SnapPosition
@@ -86,7 +86,7 @@
  * the direction of the scroll during scroll events.
  * @param pageSpacing The amount of space to be used to separate the pages in this Pager
  * @param verticalAlignment How pages are aligned vertically in this Pager.
- * @param flingBehavior The [FlingBehavior] to be used for post scroll gestures.
+ * @param flingBehavior The [TargetedFlingBehavior] to be used for post scroll gestures.
  * @param userScrollEnabled whether the scrolling via the user gestures or accessibility actions
  * is allowed. You can still scroll programmatically using [PagerState.scroll] even when it is
  * disabled.
@@ -114,7 +114,7 @@
     outOfBoundsPageCount: Int = PagerDefaults.OutOfBoundsPageCount,
     pageSpacing: Dp = 0.dp,
     verticalAlignment: Alignment.Vertical = Alignment.CenterVertically,
-    flingBehavior: SnapFlingBehavior = PagerDefaults.flingBehavior(state = state),
+    flingBehavior: TargetedFlingBehavior = PagerDefaults.flingBehavior(state = state),
     userScrollEnabled: Boolean = true,
     reverseLayout: Boolean = false,
     key: ((index: Int) -> Any)? = null,
@@ -173,7 +173,7 @@
  *  * the direction of the scroll during scroll events.
  * @param pageSpacing The amount of space to be used to separate the pages in this Pager
  * @param horizontalAlignment How pages are aligned horizontally in this Pager.
- * @param flingBehavior The [FlingBehavior] to be used for post scroll gestures.
+ * @param flingBehavior The [TargetedFlingBehavior] to be used for post scroll gestures.
  * @param userScrollEnabled whether the scrolling via the user gestures or accessibility actions
  * is allowed. You can still scroll programmatically using [PagerState.scroll] even when it is
  * disabled.
@@ -201,7 +201,7 @@
     outOfBoundsPageCount: Int = PagerDefaults.OutOfBoundsPageCount,
     pageSpacing: Dp = 0.dp,
     horizontalAlignment: Alignment.Horizontal = Alignment.CenterHorizontally,
-    flingBehavior: SnapFlingBehavior = PagerDefaults.flingBehavior(state = state),
+    flingBehavior: TargetedFlingBehavior = PagerDefaults.flingBehavior(state = state),
     userScrollEnabled: Boolean = true,
     reverseLayout: Boolean = false,
     key: ((index: Int) -> Any)? = null,
@@ -298,7 +298,7 @@
         decayAnimationSpec: DecayAnimationSpec<Float> = rememberSplineBasedDecay(),
         snapAnimationSpec: AnimationSpec<Float> = spring(stiffness = Spring.StiffnessMediumLow),
         @FloatRange(from = 0.0, to = 1.0) snapPositionalThreshold: Float = 0.5f
-    ): SnapFlingBehavior {
+    ): TargetedFlingBehavior {
         require(snapPositionalThreshold in 0f..1f) {
             "snapPositionalThreshold should be a number between 0 and 1. " +
                 "You've specified $snapPositionalThreshold"
@@ -462,20 +462,6 @@
 }
 
 @OptIn(ExperimentalFoundationApi::class)
-internal class PagerWrapperFlingBehavior(
-    val originalFlingBehavior: SnapFlingBehavior,
-    val pagerState: PagerState
-) : FlingBehavior {
-    override suspend fun ScrollScope.performFling(initialVelocity: Float): Float {
-        return with(originalFlingBehavior) {
-            performFling(initialVelocity) { remainingScrollOffset ->
-                pagerState.snapRemainingScrollOffset = remainingScrollOffset
-            }
-        }
-    }
-}
-
-@OptIn(ExperimentalFoundationApi::class)
 private class DefaultPagerNestedScrollConnection(
     val state: PagerState,
     val orientation: Orientation
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/pager/PagerState.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/pager/PagerState.kt
index 3d00697..940f9d0 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/pager/PagerState.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/pager/PagerState.kt
@@ -37,7 +37,6 @@
 import androidx.compose.runtime.Stable
 import androidx.compose.runtime.derivedStateOf
 import androidx.compose.runtime.getValue
-import androidx.compose.runtime.mutableFloatStateOf
 import androidx.compose.runtime.mutableIntStateOf
 import androidx.compose.runtime.mutableStateOf
 import androidx.compose.runtime.neverEqualPolicy
@@ -173,8 +172,6 @@
      * Difference between the last up and last down events of a scroll event.
      */
     internal var upDownDifference: Offset by mutableStateOf(Offset.Zero)
-    internal var snapRemainingScrollOffset by mutableFloatStateOf(0f)
-
     private val animatedScrollScope = PagerLazyAnimateScrollScope(this)
 
     private var isScrollingForward: Boolean by mutableStateOf(false)
@@ -401,7 +398,7 @@
             this.currentPage
         } else if (programmaticScrollTargetPage != -1) {
             programmaticScrollTargetPage
-        } else if (snapRemainingScrollOffset == 0.0f) {
+        } else {
             // act on scroll only
             if (abs(this.currentPageOffsetFraction) >= abs(positionThresholdFraction)) {
                 if (isScrollingForward) {
@@ -412,10 +409,6 @@
             } else {
                 this.currentPage
             }
-        } else {
-            // act on flinging
-            val pageDisplacement = snapRemainingScrollOffset / pageSizeWithSpacing
-            (this.currentPage + pageDisplacement.roundToInt())
         }
         finalPage.coerceInPageRange()
     }
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text2/input/internal/TextFieldDecoratorModifier.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text2/input/internal/TextFieldDecoratorModifier.kt
index b4a2b52..fe69b94 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text2/input/internal/TextFieldDecoratorModifier.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text2/input/internal/TextFieldDecoratorModifier.kt
@@ -17,9 +17,8 @@
 package androidx.compose.foundation.text2.input.internal
 
 import androidx.compose.foundation.ExperimentalFoundationApi
-import androidx.compose.foundation.content.TransferableContent
 import androidx.compose.foundation.content.internal.ReceiveContentConfiguration
-import androidx.compose.foundation.content.internal.mergeReceiveContentConfiguration
+import androidx.compose.foundation.content.internal.getReceiveContentConfiguration
 import androidx.compose.foundation.interaction.HoverInteraction
 import androidx.compose.foundation.interaction.MutableInteractionSource
 import androidx.compose.foundation.text.Handle
@@ -42,6 +41,7 @@
 import androidx.compose.ui.input.pointer.PointerEventPass
 import androidx.compose.ui.input.pointer.SuspendingPointerInputModifierNode
 import androidx.compose.ui.layout.LayoutCoordinates
+import androidx.compose.ui.modifier.ModifierLocalModifierNode
 import androidx.compose.ui.node.CompositionLocalConsumerModifierNode
 import androidx.compose.ui.node.DelegatingNode
 import androidx.compose.ui.node.GlobalPositionAwareModifierNode
@@ -164,6 +164,7 @@
     PointerInputModifierNode,
     KeyInputModifierNode,
     CompositionLocalConsumerModifierNode,
+    ModifierLocalModifierNode,
     ObserverModifierNode {
 
     private val editable get() = enabled && !readOnly
@@ -294,7 +295,7 @@
     private var inputSessionJob: Job? = null
 
     private val receiveContentConfigurationProvider: () -> ReceiveContentConfiguration? = {
-        mergeReceiveContentConfiguration()
+        getReceiveContentConfiguration()
     }
 
     /**
@@ -551,7 +552,7 @@
     private fun startInputSession(fromTap: Boolean) {
         if (!fromTap && !keyboardOptions.shouldShowKeyboardOnFocus) return
 
-        val receiveContentConfiguration = mergeReceiveContentConfiguration()
+        val receiveContentConfiguration = getReceiveContentConfiguration()
 
         inputSessionJob = coroutineScope.launch {
             // This will automatically cancel the previous session, if any, so we don't need to
@@ -563,12 +564,11 @@
                 }
 
                 platformSpecificTextInputSession(
-                    textFieldState,
-                    textLayoutState,
-                    keyboardOptions.toImeOptions(singleLine),
-                    acceptedMimeTypes = receiveContentConfiguration?.acceptedMimeTypes,
-                    onImeAction = onImeActionPerformed,
-                    onCommitContent = receiveContentConfiguration?.onCommitContent
+                    state = textFieldState,
+                    layoutState = textLayoutState,
+                    imeOptions = keyboardOptions.toImeOptions(singleLine),
+                    receiveContentConfiguration = receiveContentConfiguration,
+                    onImeAction = onImeActionPerformed
                 )
             }
         }
@@ -603,14 +603,12 @@
 /**
  * Runs platform-specific text input logic.
  */
-@OptIn(ExperimentalFoundationApi::class)
 internal expect suspend fun PlatformTextInputSession.platformSpecificTextInputSession(
     state: TransformedTextFieldState,
     layoutState: TextLayoutState,
     imeOptions: ImeOptions,
-    acceptedMimeTypes: Set<String>?,
-    onImeAction: ((ImeAction) -> Unit)?,
-    onCommitContent: ((TransferableContent) -> Boolean)?
+    receiveContentConfiguration: ReceiveContentConfiguration?,
+    onImeAction: ((ImeAction) -> Unit)?
 ): Nothing
 
 /**
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text2/input/internal/selection/TextFieldSelectionState.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text2/input/internal/selection/TextFieldSelectionState.kt
index 5d0a88f..ac7259e 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text2/input/internal/selection/TextFieldSelectionState.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text2/input/internal/selection/TextFieldSelectionState.kt
@@ -1144,7 +1144,7 @@
         val clipEntry = clipboardManager?.getClip() ?: return
         val clipMetadata = clipboardManager?.getClipMetadata() ?: return pasteAsPlainText()
 
-        val remaining = receiveContentConfiguration.onReceive(
+        val remaining = receiveContentConfiguration.receiveContentListener.onReceive(
             TransferableContent(
                 clipEntry = clipEntry,
                 source = TransferableContent.Source.Clipboard,
diff --git a/compose/foundation/foundation/src/desktopMain/kotlin/androidx/compose/foundation/content/internal/ReceiveContentDragAndDropNode.desktop.kt b/compose/foundation/foundation/src/desktopMain/kotlin/androidx/compose/foundation/content/internal/ReceiveContentDragAndDropNode.desktop.kt
new file mode 100644
index 0000000..8cdfb48
--- /dev/null
+++ b/compose/foundation/foundation/src/desktopMain/kotlin/androidx/compose/foundation/content/internal/ReceiveContentDragAndDropNode.desktop.kt
@@ -0,0 +1,27 @@
+/*
+ * 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.compose.foundation.content.internal
+
+import androidx.compose.ui.draganddrop.DragAndDropEvent
+import androidx.compose.ui.draganddrop.DragAndDropModifierNode
+
+internal actual fun ReceiveContentDragAndDropNode(
+    receiveContentConfiguration: ReceiveContentConfiguration,
+    dragAndDropRequestPermission: (DragAndDropEvent) -> Unit
+): DragAndDropModifierNode {
+    return DragAndDropModifierNode()
+}
diff --git a/compose/foundation/foundation/src/desktopMain/kotlin/androidx/compose/foundation/text2/input/internal/DesktopTextInputSession.desktop.kt b/compose/foundation/foundation/src/desktopMain/kotlin/androidx/compose/foundation/text2/input/internal/DesktopTextInputSession.desktop.kt
index f2bad31..028fe3e 100644
--- a/compose/foundation/foundation/src/desktopMain/kotlin/androidx/compose/foundation/text2/input/internal/DesktopTextInputSession.desktop.kt
+++ b/compose/foundation/foundation/src/desktopMain/kotlin/androidx/compose/foundation/text2/input/internal/DesktopTextInputSession.desktop.kt
@@ -17,7 +17,7 @@
 package androidx.compose.foundation.text2.input.internal
 
 import androidx.compose.foundation.ExperimentalFoundationApi
-import androidx.compose.foundation.content.TransferableContent
+import androidx.compose.foundation.content.internal.ReceiveContentConfiguration
 import androidx.compose.ui.platform.PlatformTextInputSession
 import androidx.compose.ui.text.input.ImeAction
 import androidx.compose.ui.text.input.ImeOptions
@@ -31,9 +31,8 @@
     state: TransformedTextFieldState,
     layoutState: TextLayoutState,
     imeOptions: ImeOptions,
-    acceptedMimeTypes: Set<String>?,
-    onImeAction: ((ImeAction) -> Unit)?,
-    onCommitContent: ((TransferableContent) -> Boolean)?
+    receiveContentConfiguration: ReceiveContentConfiguration?,
+    onImeAction: ((ImeAction) -> Unit)?
 ): Nothing {
     // TODO(b/267235947) Wire up desktop.
     awaitCancellation()
diff --git a/compose/integration-tests/demos/src/main/AndroidManifest.xml b/compose/integration-tests/demos/src/main/AndroidManifest.xml
index 8ce6972..1e40680 100644
--- a/compose/integration-tests/demos/src/main/AndroidManifest.xml
+++ b/compose/integration-tests/demos/src/main/AndroidManifest.xml
@@ -21,7 +21,8 @@
     <application
             android:label="Jetpack Compose Demos"
             android:supportsRtl="true" tools:ignore="GoogleAppIndexingWarning"
-            android:allowBackup="false" android:icon="@mipmap/ic_launcher">
+            android:allowBackup="false" android:icon="@mipmap/ic_launcher"
+            android:enableOnBackInvokedCallback="true">
 
         <activity
             android:name=".DemoActivity"
diff --git a/compose/material/material/src/androidInstrumentedTest/kotlin/androidx/compose/material/BottomSheetScaffoldTest.kt b/compose/material/material/src/androidInstrumentedTest/kotlin/androidx/compose/material/BottomSheetScaffoldTest.kt
index 8e2ec05..a5dbebf 100644
--- a/compose/material/material/src/androidInstrumentedTest/kotlin/androidx/compose/material/BottomSheetScaffoldTest.kt
+++ b/compose/material/material/src/androidInstrumentedTest/kotlin/androidx/compose/material/BottomSheetScaffoldTest.kt
@@ -204,7 +204,7 @@
     }
 
     @Test
-    fun backdropScaffold_revealAndConceal_manually(): Unit = runBlocking(AutoTestFrameClock()) {
+    fun bottomSheetScaffold_revealAndConceal_manually(): Unit = runBlocking(AutoTestFrameClock()) {
         lateinit var bottomSheetState: BottomSheetState
         rule.setContent {
             bottomSheetState = rememberBottomSheetState(BottomSheetValue.Collapsed)
diff --git a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/TabRow.kt b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/TabRow.kt
index 8c83d9b..713a331 100644
--- a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/TabRow.kt
+++ b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/TabRow.kt
@@ -48,6 +48,7 @@
 import androidx.compose.ui.unit.Constraints
 import androidx.compose.ui.unit.Density
 import androidx.compose.ui.unit.Dp
+import androidx.compose.ui.unit.IntOffset
 import androidx.compose.ui.unit.dp
 import androidx.compose.ui.util.fastForEach
 import androidx.compose.ui.util.fastForEachIndexed
@@ -420,7 +421,7 @@
         )
         fillMaxWidth()
             .wrapContentSize(Alignment.BottomStart)
-            .offset(x = indicatorOffset)
+            .offset { IntOffset(x = indicatorOffset.roundToPx(), y = 0) }
             .width(currentTabWidth)
     }
 
diff --git a/compose/material3/material3-adaptive-navigation-suite/api/current.txt b/compose/material3/material3-adaptive-navigation-suite/api/current.txt
index 131dea0..a87d1e4 100644
--- a/compose/material3/material3-adaptive-navigation-suite/api/current.txt
+++ b/compose/material3/material3-adaptive-navigation-suite/api/current.txt
@@ -45,7 +45,7 @@
   }
 
   @SuppressCompatibility @androidx.compose.material3.adaptive.navigation.suite.ExperimentalMaterial3AdaptiveNavigationSuiteApi public interface NavigationSuiteScope {
-    method public void item(boolean selected, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, kotlin.jvm.functions.Function0<kotlin.Unit> icon, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.jvm.functions.Function0<kotlin.Unit>? label, optional boolean alwaysShowLabel, optional kotlin.jvm.functions.Function0<kotlin.Unit>? badge, optional androidx.compose.material3.adaptive.navigation.suite.NavigationSuiteItemColors? colors, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource);
+    method public void item(boolean selected, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, kotlin.jvm.functions.Function0<kotlin.Unit> icon, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.jvm.functions.Function0<kotlin.Unit>? label, optional boolean alwaysShowLabel, optional kotlin.jvm.functions.Function0<kotlin.Unit>? badge, optional androidx.compose.material3.adaptive.navigation.suite.NavigationSuiteItemColors? colors, optional androidx.compose.foundation.interaction.MutableInteractionSource? interactionSource);
   }
 
   @SuppressCompatibility @androidx.compose.material3.adaptive.navigation.suite.ExperimentalMaterial3AdaptiveNavigationSuiteApi @kotlin.jvm.JvmInline public final value class NavigationSuiteType {
diff --git a/compose/material3/material3-adaptive-navigation-suite/api/restricted_current.txt b/compose/material3/material3-adaptive-navigation-suite/api/restricted_current.txt
index 131dea0..a87d1e4 100644
--- a/compose/material3/material3-adaptive-navigation-suite/api/restricted_current.txt
+++ b/compose/material3/material3-adaptive-navigation-suite/api/restricted_current.txt
@@ -45,7 +45,7 @@
   }
 
   @SuppressCompatibility @androidx.compose.material3.adaptive.navigation.suite.ExperimentalMaterial3AdaptiveNavigationSuiteApi public interface NavigationSuiteScope {
-    method public void item(boolean selected, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, kotlin.jvm.functions.Function0<kotlin.Unit> icon, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.jvm.functions.Function0<kotlin.Unit>? label, optional boolean alwaysShowLabel, optional kotlin.jvm.functions.Function0<kotlin.Unit>? badge, optional androidx.compose.material3.adaptive.navigation.suite.NavigationSuiteItemColors? colors, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource);
+    method public void item(boolean selected, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, kotlin.jvm.functions.Function0<kotlin.Unit> icon, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.jvm.functions.Function0<kotlin.Unit>? label, optional boolean alwaysShowLabel, optional kotlin.jvm.functions.Function0<kotlin.Unit>? badge, optional androidx.compose.material3.adaptive.navigation.suite.NavigationSuiteItemColors? colors, optional androidx.compose.foundation.interaction.MutableInteractionSource? interactionSource);
   }
 
   @SuppressCompatibility @androidx.compose.material3.adaptive.navigation.suite.ExperimentalMaterial3AdaptiveNavigationSuiteApi @kotlin.jvm.JvmInline public final value class NavigationSuiteType {
diff --git a/compose/material3/material3-adaptive-navigation-suite/src/androidInstrumentedTest/kotlin/androidx/compose/material3/adaptive-navigation-suite/NavigationSuiteScaffoldTest.kt b/compose/material3/material3-adaptive-navigation-suite/src/androidInstrumentedTest/kotlin/androidx/compose/material3/adaptive-navigation-suite/NavigationSuiteScaffoldTest.kt
new file mode 100644
index 0000000..7cbf1c3
--- /dev/null
+++ b/compose/material3/material3-adaptive-navigation-suite/src/androidInstrumentedTest/kotlin/androidx/compose/material3/adaptive-navigation-suite/NavigationSuiteScaffoldTest.kt
@@ -0,0 +1,110 @@
+/*
+ * 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.compose.material3.adaptive.navigation.suite
+
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.material3.Surface
+import androidx.compose.runtime.Composable
+import androidx.compose.testutils.assertIsEqualTo
+import androidx.compose.testutils.assertIsNotEqualTo
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.platform.testTag
+import androidx.compose.ui.test.getUnclippedBoundsInRoot
+import androidx.compose.ui.test.junit4.createComposeRule
+import androidx.compose.ui.test.onNodeWithTag
+import androidx.compose.ui.test.onRoot
+import androidx.compose.ui.unit.height
+import androidx.compose.ui.unit.width
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+
+@OptIn(ExperimentalMaterial3AdaptiveNavigationSuiteApi::class)
+@RunWith(JUnit4::class)
+class NavigationSuiteScaffoldTest {
+    @get:Rule
+    val rule = createComposeRule()
+
+    @Test
+    fun navigationSuiteScaffoldTest_fillMaxSize_withNavBar_succeeds() {
+        rule.setContent {
+            Surface(modifier = Modifier.fillMaxSize()) {
+                SampleNavigationSuiteScaffoldLayout(NavigationSuiteType.NavigationBar)
+            }
+        }
+
+        // Assert that Modifier.fillMaxSize didn't propagate to the nav bar (its height should not
+        // fill the screen).
+        rule.onNodeWithTag(NavigationSuiteTag).getUnclippedBoundsInRoot()
+            .height.assertIsNotEqualTo(rule.onRoot().getUnclippedBoundsInRoot().height)
+        // Nav bar width is always the same as screen width.
+        rule.onNodeWithTag(NavigationSuiteTag).getUnclippedBoundsInRoot()
+            .width.assertIsEqualTo(rule.onRoot().getUnclippedBoundsInRoot().width)
+    }
+
+    @Test
+    fun navigationSuiteScaffoldTest_fillMaxSize_withNavRail_succeeds() {
+        rule.setContent {
+            Surface(modifier = Modifier.fillMaxSize()) {
+                SampleNavigationSuiteScaffoldLayout(NavigationSuiteType.NavigationRail)
+            }
+        }
+
+        // Nav rail height is always the same as screen height.
+        rule.onNodeWithTag(NavigationSuiteTag).getUnclippedBoundsInRoot()
+            .height.assertIsEqualTo(rule.onRoot().getUnclippedBoundsInRoot().height)
+        // Assert that Modifier.fillMaxSize didn't propagate to the nav rail (its width should not
+        // fill the screen).
+        rule.onNodeWithTag(NavigationSuiteTag).getUnclippedBoundsInRoot()
+            .width.assertIsNotEqualTo(rule.onRoot().getUnclippedBoundsInRoot().width)
+    }
+
+    @Test
+    fun navigationSuiteScaffoldTest_fillMaxSize_withNavDrawer_succeeds() {
+        rule.setContent {
+            Surface(modifier = Modifier.fillMaxSize()) {
+                SampleNavigationSuiteScaffoldLayout(NavigationSuiteType.NavigationDrawer)
+            }
+        }
+
+        // Nav drawer height is always the same as screen height.
+        rule.onNodeWithTag(NavigationSuiteTag).getUnclippedBoundsInRoot()
+            .height.assertIsEqualTo(rule.onRoot().getUnclippedBoundsInRoot().height)
+        // Assert that Modifier.fillMaxSize didn't propagate to the nav drawer (its width should not
+        // fill the screen).
+        rule.onNodeWithTag(NavigationSuiteTag).getUnclippedBoundsInRoot()
+            .width.assertIsNotEqualTo(rule.onRoot().getUnclippedBoundsInRoot().width)
+    }
+}
+
+@OptIn(ExperimentalMaterial3AdaptiveNavigationSuiteApi::class)
+@Composable
+private fun SampleNavigationSuiteScaffoldLayout(
+    layoutType: NavigationSuiteType
+) {
+    NavigationSuiteScaffoldLayout(
+        navigationSuite = {
+            NavigationSuite(
+                modifier = Modifier.testTag(NavigationSuiteTag),
+                layoutType = layoutType
+            ) { }
+        }
+    )
+}
+
+private const val NavigationSuiteTag = "NavigationSuite"
diff --git a/compose/material3/material3-adaptive-navigation-suite/src/commonMain/kotlin/androidx/compose/material3/adaptive/navigation-suite/NavigationSuiteScaffold.kt b/compose/material3/material3-adaptive-navigation-suite/src/commonMain/kotlin/androidx/compose/material3/adaptive/navigation-suite/NavigationSuiteScaffold.kt
index aa5fae8..4787981 100644
--- a/compose/material3/material3-adaptive-navigation-suite/src/commonMain/kotlin/androidx/compose/material3/adaptive/navigation-suite/NavigationSuiteScaffold.kt
+++ b/compose/material3/material3-adaptive-navigation-suite/src/commonMain/kotlin/androidx/compose/material3/adaptive/navigation-suite/NavigationSuiteScaffold.kt
@@ -309,9 +309,10 @@
      * @param badge optional badge to show on this item
      * @param colors [NavigationSuiteItemColors] that will be used to resolve the colors used for this
      * item in different states.
-     * @param interactionSource the [MutableInteractionSource] representing the stream of [Interaction]s
-     * for this item. You can create and pass in your own `remember`ed instance to observe
-     * [Interaction]s and customize the appearance / behavior of this item in different states
+     * @param interactionSource an optional hoisted [MutableInteractionSource] for observing and
+     * emitting [Interaction]s for this item. You can use this to change the item's appearance
+     * or preview the item in different states. Note that if `null` is provided, interactions will
+     * still happen internally.
      */
     fun item(
         selected: Boolean,
@@ -323,7 +324,7 @@
         alwaysShowLabel: Boolean = true,
         badge: (@Composable () -> Unit)? = null,
         colors: NavigationSuiteItemColors? = null,
-        interactionSource: MutableInteractionSource = MutableInteractionSource()
+        interactionSource: MutableInteractionSource? = null
     )
 }
 
@@ -509,7 +510,7 @@
     val alwaysShowLabel: Boolean,
     val badge: (@Composable () -> Unit)?,
     val colors: NavigationSuiteItemColors?,
-    val interactionSource: MutableInteractionSource
+    val interactionSource: MutableInteractionSource?
 )
 
 @OptIn(ExperimentalMaterial3AdaptiveNavigationSuiteApi::class)
@@ -526,7 +527,7 @@
         alwaysShowLabel: Boolean,
         badge: (@Composable () -> Unit)?,
         colors: NavigationSuiteItemColors?,
-        interactionSource: MutableInteractionSource
+        interactionSource: MutableInteractionSource?
     ) {
         itemList.add(
             NavigationSuiteItem(
diff --git a/compose/material3/material3/api/current.txt b/compose/material3/material3/api/current.txt
index e886d19..05ecd27 100644
--- a/compose/material3/material3/api/current.txt
+++ b/compose/material3/material3/api/current.txt
@@ -24,9 +24,10 @@
   }
 
   public final class AndroidMenu_androidKt {
-    method @androidx.compose.runtime.Composable public static void DropdownMenu(boolean expanded, kotlin.jvm.functions.Function0<kotlin.Unit> onDismissRequest, optional androidx.compose.ui.Modifier modifier, optional long offset, optional androidx.compose.foundation.ScrollState scrollState, optional androidx.compose.ui.window.PopupProperties properties, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void DropdownMenu(boolean expanded, kotlin.jvm.functions.Function0<kotlin.Unit> onDismissRequest, optional androidx.compose.ui.Modifier modifier, optional long offset, optional androidx.compose.foundation.ScrollState scrollState, optional androidx.compose.ui.window.PopupProperties properties, optional androidx.compose.ui.graphics.Shape shape, optional long containerColor, optional float tonalElevation, optional float shadowElevation, optional androidx.compose.foundation.BorderStroke? border, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> content);
+    method @Deprecated @androidx.compose.runtime.Composable public static void DropdownMenu(boolean expanded, kotlin.jvm.functions.Function0<kotlin.Unit> onDismissRequest, optional androidx.compose.ui.Modifier modifier, optional long offset, optional androidx.compose.foundation.ScrollState scrollState, optional androidx.compose.ui.window.PopupProperties properties, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> content);
     method @Deprecated @androidx.compose.runtime.Composable public static void DropdownMenu(boolean expanded, kotlin.jvm.functions.Function0<kotlin.Unit> onDismissRequest, optional androidx.compose.ui.Modifier modifier, optional long offset, optional androidx.compose.ui.window.PopupProperties properties, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> content);
-    method @androidx.compose.runtime.Composable public static void DropdownMenuItem(kotlin.jvm.functions.Function0<kotlin.Unit> text, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional boolean enabled, optional androidx.compose.material3.MenuItemColors colors, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource);
+    method @androidx.compose.runtime.Composable public static void DropdownMenuItem(kotlin.jvm.functions.Function0<kotlin.Unit> text, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional boolean enabled, optional androidx.compose.material3.MenuItemColors colors, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.interaction.MutableInteractionSource? interactionSource);
   }
 
   public final class AppBarKt {
@@ -228,11 +229,11 @@
   }
 
   public final class ButtonKt {
-    method @androidx.compose.runtime.Composable public static void Button(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.ButtonColors colors, optional androidx.compose.material3.ButtonElevation? elevation, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content);
-    method @androidx.compose.runtime.Composable public static void ElevatedButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.ButtonColors colors, optional androidx.compose.material3.ButtonElevation? elevation, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content);
-    method @androidx.compose.runtime.Composable public static void FilledTonalButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.ButtonColors colors, optional androidx.compose.material3.ButtonElevation? elevation, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content);
-    method @androidx.compose.runtime.Composable public static void OutlinedButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.ButtonColors colors, optional androidx.compose.material3.ButtonElevation? elevation, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content);
-    method @androidx.compose.runtime.Composable public static void TextButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.ButtonColors colors, optional androidx.compose.material3.ButtonElevation? elevation, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void Button(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.ButtonColors colors, optional androidx.compose.material3.ButtonElevation? elevation, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.interaction.MutableInteractionSource? interactionSource, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void ElevatedButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.ButtonColors colors, optional androidx.compose.material3.ButtonElevation? elevation, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.interaction.MutableInteractionSource? interactionSource, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void FilledTonalButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.ButtonColors colors, optional androidx.compose.material3.ButtonElevation? elevation, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.interaction.MutableInteractionSource? interactionSource, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void OutlinedButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.ButtonColors colors, optional androidx.compose.material3.ButtonElevation? elevation, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.interaction.MutableInteractionSource? interactionSource, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void TextButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.ButtonColors colors, optional androidx.compose.material3.ButtonElevation? elevation, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.interaction.MutableInteractionSource? interactionSource, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content);
   }
 
   public final class CalendarModel_androidKt {
@@ -277,11 +278,11 @@
 
   public final class CardKt {
     method @androidx.compose.runtime.Composable public static void Card(optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.CardColors colors, optional androidx.compose.material3.CardElevation elevation, optional androidx.compose.foundation.BorderStroke? border, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> content);
-    method @androidx.compose.runtime.Composable public static void Card(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.CardColors colors, optional androidx.compose.material3.CardElevation elevation, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void Card(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.CardColors colors, optional androidx.compose.material3.CardElevation elevation, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.interaction.MutableInteractionSource? interactionSource, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> content);
     method @androidx.compose.runtime.Composable public static void ElevatedCard(optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.CardColors colors, optional androidx.compose.material3.CardElevation elevation, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> content);
-    method @androidx.compose.runtime.Composable public static void ElevatedCard(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.CardColors colors, optional androidx.compose.material3.CardElevation elevation, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void ElevatedCard(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.CardColors colors, optional androidx.compose.material3.CardElevation elevation, optional androidx.compose.foundation.interaction.MutableInteractionSource? interactionSource, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> content);
     method @androidx.compose.runtime.Composable public static void OutlinedCard(optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.CardColors colors, optional androidx.compose.material3.CardElevation elevation, optional androidx.compose.foundation.BorderStroke border, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> content);
-    method @androidx.compose.runtime.Composable public static void OutlinedCard(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.CardColors colors, optional androidx.compose.material3.CardElevation elevation, optional androidx.compose.foundation.BorderStroke border, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void OutlinedCard(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.CardColors colors, optional androidx.compose.material3.CardElevation elevation, optional androidx.compose.foundation.BorderStroke border, optional androidx.compose.foundation.interaction.MutableInteractionSource? interactionSource, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> content);
   }
 
   @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Stable public final class CaretProperties {
@@ -335,8 +336,8 @@
   }
 
   public final class CheckboxKt {
-    method @androidx.compose.runtime.Composable public static void Checkbox(boolean checked, kotlin.jvm.functions.Function1<? super java.lang.Boolean,kotlin.Unit>? onCheckedChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.material3.CheckboxColors colors, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource);
-    method @androidx.compose.runtime.Composable public static void TriStateCheckbox(androidx.compose.ui.state.ToggleableState state, kotlin.jvm.functions.Function0<kotlin.Unit>? onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.material3.CheckboxColors colors, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource);
+    method @androidx.compose.runtime.Composable public static void Checkbox(boolean checked, kotlin.jvm.functions.Function1<? super java.lang.Boolean,kotlin.Unit>? onCheckedChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.material3.CheckboxColors colors, optional androidx.compose.foundation.interaction.MutableInteractionSource? interactionSource);
+    method @androidx.compose.runtime.Composable public static void TriStateCheckbox(androidx.compose.ui.state.ToggleableState state, kotlin.jvm.functions.Function0<kotlin.Unit>? onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.material3.CheckboxColors colors, optional androidx.compose.foundation.interaction.MutableInteractionSource? interactionSource);
   }
 
   @Deprecated @androidx.compose.runtime.Immutable public final class ChipBorder {
@@ -380,16 +381,16 @@
   }
 
   public final class ChipKt {
-    method @androidx.compose.runtime.Composable public static void AssistChip(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, kotlin.jvm.functions.Function0<kotlin.Unit> label, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.ChipColors colors, optional androidx.compose.material3.ChipElevation? elevation, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource);
+    method @androidx.compose.runtime.Composable public static void AssistChip(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, kotlin.jvm.functions.Function0<kotlin.Unit> label, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.ChipColors colors, optional androidx.compose.material3.ChipElevation? elevation, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.interaction.MutableInteractionSource? interactionSource);
     method @Deprecated @androidx.compose.runtime.Composable public static void AssistChip(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, kotlin.jvm.functions.Function0<kotlin.Unit> label, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.ChipColors colors, optional androidx.compose.material3.ChipElevation? elevation, optional androidx.compose.material3.ChipBorder? border, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource);
-    method @androidx.compose.runtime.Composable public static void ElevatedAssistChip(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, kotlin.jvm.functions.Function0<kotlin.Unit> label, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.ChipColors colors, optional androidx.compose.material3.ChipElevation? elevation, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource);
+    method @androidx.compose.runtime.Composable public static void ElevatedAssistChip(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, kotlin.jvm.functions.Function0<kotlin.Unit> label, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.ChipColors colors, optional androidx.compose.material3.ChipElevation? elevation, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.interaction.MutableInteractionSource? interactionSource);
     method @Deprecated @androidx.compose.runtime.Composable public static void ElevatedAssistChip(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, kotlin.jvm.functions.Function0<kotlin.Unit> label, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.ChipColors colors, optional androidx.compose.material3.ChipElevation? elevation, optional androidx.compose.material3.ChipBorder? border, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource);
-    method @androidx.compose.runtime.Composable public static void ElevatedFilterChip(boolean selected, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, kotlin.jvm.functions.Function0<kotlin.Unit> label, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.SelectableChipColors colors, optional androidx.compose.material3.SelectableChipElevation? elevation, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource);
-    method @androidx.compose.runtime.Composable public static void ElevatedSuggestionChip(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, kotlin.jvm.functions.Function0<kotlin.Unit> label, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.jvm.functions.Function0<kotlin.Unit>? icon, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.ChipColors colors, optional androidx.compose.material3.ChipElevation? elevation, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource);
+    method @androidx.compose.runtime.Composable public static void ElevatedFilterChip(boolean selected, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, kotlin.jvm.functions.Function0<kotlin.Unit> label, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.SelectableChipColors colors, optional androidx.compose.material3.SelectableChipElevation? elevation, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.interaction.MutableInteractionSource? interactionSource);
+    method @androidx.compose.runtime.Composable public static void ElevatedSuggestionChip(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, kotlin.jvm.functions.Function0<kotlin.Unit> label, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.jvm.functions.Function0<kotlin.Unit>? icon, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.ChipColors colors, optional androidx.compose.material3.ChipElevation? elevation, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.interaction.MutableInteractionSource? interactionSource);
     method @Deprecated @androidx.compose.runtime.Composable public static void ElevatedSuggestionChip(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, kotlin.jvm.functions.Function0<kotlin.Unit> label, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.jvm.functions.Function0<kotlin.Unit>? icon, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.ChipColors colors, optional androidx.compose.material3.ChipElevation? elevation, optional androidx.compose.material3.ChipBorder? border, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource);
-    method @androidx.compose.runtime.Composable public static void FilterChip(boolean selected, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, kotlin.jvm.functions.Function0<kotlin.Unit> label, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.SelectableChipColors colors, optional androidx.compose.material3.SelectableChipElevation? elevation, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource);
-    method @androidx.compose.runtime.Composable public static void InputChip(boolean selected, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, kotlin.jvm.functions.Function0<kotlin.Unit> label, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? avatar, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.SelectableChipColors colors, optional androidx.compose.material3.SelectableChipElevation? elevation, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource);
-    method @androidx.compose.runtime.Composable public static void SuggestionChip(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, kotlin.jvm.functions.Function0<kotlin.Unit> label, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.jvm.functions.Function0<kotlin.Unit>? icon, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.ChipColors colors, optional androidx.compose.material3.ChipElevation? elevation, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource);
+    method @androidx.compose.runtime.Composable public static void FilterChip(boolean selected, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, kotlin.jvm.functions.Function0<kotlin.Unit> label, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.SelectableChipColors colors, optional androidx.compose.material3.SelectableChipElevation? elevation, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.interaction.MutableInteractionSource? interactionSource);
+    method @androidx.compose.runtime.Composable public static void InputChip(boolean selected, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, kotlin.jvm.functions.Function0<kotlin.Unit> label, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? avatar, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.SelectableChipColors colors, optional androidx.compose.material3.SelectableChipElevation? elevation, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.interaction.MutableInteractionSource? interactionSource);
+    method @androidx.compose.runtime.Composable public static void SuggestionChip(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, kotlin.jvm.functions.Function0<kotlin.Unit> label, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.jvm.functions.Function0<kotlin.Unit>? icon, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.ChipColors colors, optional androidx.compose.material3.ChipElevation? elevation, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.interaction.MutableInteractionSource? interactionSource);
     method @Deprecated @androidx.compose.runtime.Composable public static void SuggestionChip(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, kotlin.jvm.functions.Function0<kotlin.Unit> label, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.jvm.functions.Function0<kotlin.Unit>? icon, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.ChipColors colors, optional androidx.compose.material3.ChipElevation? elevation, optional androidx.compose.material3.ChipBorder? border, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource);
   }
 
@@ -806,11 +807,11 @@
   }
 
   public final class FloatingActionButtonKt {
-    method @androidx.compose.runtime.Composable public static void ExtendedFloatingActionButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.graphics.Shape shape, optional long containerColor, optional long contentColor, optional androidx.compose.material3.FloatingActionButtonElevation elevation, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content);
-    method @androidx.compose.runtime.Composable public static void ExtendedFloatingActionButton(kotlin.jvm.functions.Function0<kotlin.Unit> text, kotlin.jvm.functions.Function0<kotlin.Unit> icon, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean expanded, optional androidx.compose.ui.graphics.Shape shape, optional long containerColor, optional long contentColor, optional androidx.compose.material3.FloatingActionButtonElevation elevation, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource);
-    method @androidx.compose.runtime.Composable public static void FloatingActionButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.graphics.Shape shape, optional long containerColor, optional long contentColor, optional androidx.compose.material3.FloatingActionButtonElevation elevation, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function0<kotlin.Unit> content);
-    method @androidx.compose.runtime.Composable public static void LargeFloatingActionButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.graphics.Shape shape, optional long containerColor, optional long contentColor, optional androidx.compose.material3.FloatingActionButtonElevation elevation, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function0<kotlin.Unit> content);
-    method @androidx.compose.runtime.Composable public static void SmallFloatingActionButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.graphics.Shape shape, optional long containerColor, optional long contentColor, optional androidx.compose.material3.FloatingActionButtonElevation elevation, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void ExtendedFloatingActionButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.graphics.Shape shape, optional long containerColor, optional long contentColor, optional androidx.compose.material3.FloatingActionButtonElevation elevation, optional androidx.compose.foundation.interaction.MutableInteractionSource? interactionSource, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void ExtendedFloatingActionButton(kotlin.jvm.functions.Function0<kotlin.Unit> text, kotlin.jvm.functions.Function0<kotlin.Unit> icon, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean expanded, optional androidx.compose.ui.graphics.Shape shape, optional long containerColor, optional long contentColor, optional androidx.compose.material3.FloatingActionButtonElevation elevation, optional androidx.compose.foundation.interaction.MutableInteractionSource? interactionSource);
+    method @androidx.compose.runtime.Composable public static void FloatingActionButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.graphics.Shape shape, optional long containerColor, optional long contentColor, optional androidx.compose.material3.FloatingActionButtonElevation elevation, optional androidx.compose.foundation.interaction.MutableInteractionSource? interactionSource, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void LargeFloatingActionButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.graphics.Shape shape, optional long containerColor, optional long contentColor, optional androidx.compose.material3.FloatingActionButtonElevation elevation, optional androidx.compose.foundation.interaction.MutableInteractionSource? interactionSource, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void SmallFloatingActionButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.graphics.Shape shape, optional long containerColor, optional long contentColor, optional androidx.compose.material3.FloatingActionButtonElevation elevation, optional androidx.compose.foundation.interaction.MutableInteractionSource? interactionSource, kotlin.jvm.functions.Function0<kotlin.Unit> content);
   }
 
   @androidx.compose.runtime.Immutable public final class IconButtonColors {
@@ -846,14 +847,14 @@
   }
 
   public final class IconButtonKt {
-    method @androidx.compose.runtime.Composable public static void FilledIconButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.IconButtonColors colors, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function0<kotlin.Unit> content);
-    method @androidx.compose.runtime.Composable public static void FilledIconToggleButton(boolean checked, kotlin.jvm.functions.Function1<? super java.lang.Boolean,kotlin.Unit> onCheckedChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.IconToggleButtonColors colors, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function0<kotlin.Unit> content);
-    method @androidx.compose.runtime.Composable public static void FilledTonalIconButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.IconButtonColors colors, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function0<kotlin.Unit> content);
-    method @androidx.compose.runtime.Composable public static void FilledTonalIconToggleButton(boolean checked, kotlin.jvm.functions.Function1<? super java.lang.Boolean,kotlin.Unit> onCheckedChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.IconToggleButtonColors colors, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function0<kotlin.Unit> content);
-    method @androidx.compose.runtime.Composable public static void IconButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.material3.IconButtonColors colors, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function0<kotlin.Unit> content);
-    method @androidx.compose.runtime.Composable public static void IconToggleButton(boolean checked, kotlin.jvm.functions.Function1<? super java.lang.Boolean,kotlin.Unit> onCheckedChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.material3.IconToggleButtonColors colors, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function0<kotlin.Unit> content);
-    method @androidx.compose.runtime.Composable public static void OutlinedIconButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.IconButtonColors colors, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function0<kotlin.Unit> content);
-    method @androidx.compose.runtime.Composable public static void OutlinedIconToggleButton(boolean checked, kotlin.jvm.functions.Function1<? super java.lang.Boolean,kotlin.Unit> onCheckedChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.IconToggleButtonColors colors, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void FilledIconButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.IconButtonColors colors, optional androidx.compose.foundation.interaction.MutableInteractionSource? interactionSource, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void FilledIconToggleButton(boolean checked, kotlin.jvm.functions.Function1<? super java.lang.Boolean,kotlin.Unit> onCheckedChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.IconToggleButtonColors colors, optional androidx.compose.foundation.interaction.MutableInteractionSource? interactionSource, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void FilledTonalIconButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.IconButtonColors colors, optional androidx.compose.foundation.interaction.MutableInteractionSource? interactionSource, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void FilledTonalIconToggleButton(boolean checked, kotlin.jvm.functions.Function1<? super java.lang.Boolean,kotlin.Unit> onCheckedChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.IconToggleButtonColors colors, optional androidx.compose.foundation.interaction.MutableInteractionSource? interactionSource, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void IconButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.material3.IconButtonColors colors, optional androidx.compose.foundation.interaction.MutableInteractionSource? interactionSource, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void IconToggleButton(boolean checked, kotlin.jvm.functions.Function1<? super java.lang.Boolean,kotlin.Unit> onCheckedChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.material3.IconToggleButtonColors colors, optional androidx.compose.foundation.interaction.MutableInteractionSource? interactionSource, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void OutlinedIconButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.IconButtonColors colors, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.interaction.MutableInteractionSource? interactionSource, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void OutlinedIconToggleButton(boolean checked, kotlin.jvm.functions.Function1<? super java.lang.Boolean,kotlin.Unit> onCheckedChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.IconToggleButtonColors colors, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.interaction.MutableInteractionSource? interactionSource, kotlin.jvm.functions.Function0<kotlin.Unit> content);
   }
 
   public final class IconKt {
@@ -903,7 +904,7 @@
   }
 
   public final class LabelKt {
-    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void Label(kotlin.jvm.functions.Function1<? super androidx.compose.material3.CaretScope,kotlin.Unit> label, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional boolean isPersistent, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void Label(kotlin.jvm.functions.Function1<? super androidx.compose.material3.CaretScope,kotlin.Unit> label, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.foundation.interaction.MutableInteractionSource? interactionSource, optional boolean isPersistent, kotlin.jvm.functions.Function0<kotlin.Unit> content);
   }
 
   @androidx.compose.runtime.Immutable public final class ListItemColors {
@@ -960,10 +961,18 @@
   }
 
   public final class MenuDefaults {
+    method @androidx.compose.runtime.Composable public long getContainerColor();
     method public androidx.compose.foundation.layout.PaddingValues getDropdownMenuItemContentPadding();
+    method public float getShadowElevation();
+    method @androidx.compose.runtime.Composable public androidx.compose.ui.graphics.Shape getShape();
+    method public float getTonalElevation();
     method @androidx.compose.runtime.Composable public androidx.compose.material3.MenuItemColors itemColors();
     method @androidx.compose.runtime.Composable public androidx.compose.material3.MenuItemColors itemColors(optional long textColor, optional long leadingIconColor, optional long trailingIconColor, optional long disabledTextColor, optional long disabledLeadingIconColor, optional long disabledTrailingIconColor);
     property public final androidx.compose.foundation.layout.PaddingValues DropdownMenuItemContentPadding;
+    property public final float ShadowElevation;
+    property public final float TonalElevation;
+    property @androidx.compose.runtime.Composable public final long containerColor;
+    property @androidx.compose.runtime.Composable public final androidx.compose.ui.graphics.Shape shape;
     field public static final androidx.compose.material3.MenuDefaults INSTANCE;
   }
 
@@ -1045,7 +1054,7 @@
 
   public final class NavigationBarKt {
     method @androidx.compose.runtime.Composable public static void NavigationBar(optional androidx.compose.ui.Modifier modifier, optional long containerColor, optional long contentColor, optional float tonalElevation, optional androidx.compose.foundation.layout.WindowInsets windowInsets, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content);
-    method @androidx.compose.runtime.Composable public static void NavigationBarItem(androidx.compose.foundation.layout.RowScope, boolean selected, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, kotlin.jvm.functions.Function0<kotlin.Unit> icon, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.jvm.functions.Function0<kotlin.Unit>? label, optional boolean alwaysShowLabel, optional androidx.compose.material3.NavigationBarItemColors colors, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource);
+    method @androidx.compose.runtime.Composable public static void NavigationBarItem(androidx.compose.foundation.layout.RowScope, boolean selected, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, kotlin.jvm.functions.Function0<kotlin.Unit> icon, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.jvm.functions.Function0<kotlin.Unit>? label, optional boolean alwaysShowLabel, optional androidx.compose.material3.NavigationBarItemColors colors, optional androidx.compose.foundation.interaction.MutableInteractionSource? interactionSource);
   }
 
   @androidx.compose.runtime.Stable public interface NavigationDrawerItemColors {
@@ -1067,7 +1076,7 @@
     method @androidx.compose.runtime.Composable public static void DismissibleNavigationDrawer(kotlin.jvm.functions.Function0<kotlin.Unit> drawerContent, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.material3.DrawerState drawerState, optional boolean gesturesEnabled, kotlin.jvm.functions.Function0<kotlin.Unit> content);
     method @androidx.compose.runtime.Composable public static void ModalDrawerSheet(optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.graphics.Shape drawerShape, optional long drawerContainerColor, optional long drawerContentColor, optional float drawerTonalElevation, optional androidx.compose.foundation.layout.WindowInsets windowInsets, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> content);
     method @androidx.compose.runtime.Composable public static void ModalNavigationDrawer(kotlin.jvm.functions.Function0<kotlin.Unit> drawerContent, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.material3.DrawerState drawerState, optional boolean gesturesEnabled, optional long scrimColor, kotlin.jvm.functions.Function0<kotlin.Unit> content);
-    method @androidx.compose.runtime.Composable public static void NavigationDrawerItem(kotlin.jvm.functions.Function0<kotlin.Unit> label, boolean selected, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function0<kotlin.Unit>? icon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? badge, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.NavigationDrawerItemColors colors, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource);
+    method @androidx.compose.runtime.Composable public static void NavigationDrawerItem(kotlin.jvm.functions.Function0<kotlin.Unit> label, boolean selected, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function0<kotlin.Unit>? icon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? badge, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.NavigationDrawerItemColors colors, optional androidx.compose.foundation.interaction.MutableInteractionSource? interactionSource);
     method @androidx.compose.runtime.Composable public static void PermanentDrawerSheet(optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.graphics.Shape drawerShape, optional long drawerContainerColor, optional long drawerContentColor, optional float drawerTonalElevation, optional androidx.compose.foundation.layout.WindowInsets windowInsets, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> content);
     method @androidx.compose.runtime.Composable public static void PermanentNavigationDrawer(kotlin.jvm.functions.Function0<kotlin.Unit> drawerContent, optional androidx.compose.ui.Modifier modifier, kotlin.jvm.functions.Function0<kotlin.Unit> content);
     method @androidx.compose.runtime.Composable public static androidx.compose.material3.DrawerState rememberDrawerState(androidx.compose.material3.DrawerValue initialValue, optional kotlin.jvm.functions.Function1<? super androidx.compose.material3.DrawerValue,java.lang.Boolean> confirmStateChange);
@@ -1109,7 +1118,7 @@
 
   public final class NavigationRailKt {
     method @androidx.compose.runtime.Composable public static void NavigationRail(optional androidx.compose.ui.Modifier modifier, optional long containerColor, optional long contentColor, optional kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit>? header, optional androidx.compose.foundation.layout.WindowInsets windowInsets, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> content);
-    method @androidx.compose.runtime.Composable public static void NavigationRailItem(boolean selected, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, kotlin.jvm.functions.Function0<kotlin.Unit> icon, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.jvm.functions.Function0<kotlin.Unit>? label, optional boolean alwaysShowLabel, optional androidx.compose.material3.NavigationRailItemColors colors, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource);
+    method @androidx.compose.runtime.Composable public static void NavigationRailItem(boolean selected, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, kotlin.jvm.functions.Function0<kotlin.Unit> icon, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.jvm.functions.Function0<kotlin.Unit>? label, optional boolean alwaysShowLabel, optional androidx.compose.material3.NavigationRailItemColors colors, optional androidx.compose.foundation.interaction.MutableInteractionSource? interactionSource);
   }
 
   @androidx.compose.runtime.Immutable public final class OutlinedTextFieldDefaults {
@@ -1133,9 +1142,9 @@
 
   public final class OutlinedTextFieldKt {
     method @Deprecated @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void OutlinedTextField(androidx.compose.ui.text.input.TextFieldValue value, kotlin.jvm.functions.Function1<? super androidx.compose.ui.text.input.TextFieldValue,kotlin.Unit> onValueChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional boolean readOnly, optional androidx.compose.ui.text.TextStyle textStyle, optional kotlin.jvm.functions.Function0<kotlin.Unit>? label, optional kotlin.jvm.functions.Function0<kotlin.Unit>? placeholder, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? supportingText, optional boolean isError, optional androidx.compose.ui.text.input.VisualTransformation visualTransformation, optional androidx.compose.foundation.text.KeyboardOptions keyboardOptions, optional androidx.compose.foundation.text.KeyboardActions keyboardActions, optional boolean singleLine, optional int maxLines, optional int minLines, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.TextFieldColors colors);
-    method @androidx.compose.runtime.Composable public static void OutlinedTextField(androidx.compose.ui.text.input.TextFieldValue value, kotlin.jvm.functions.Function1<? super androidx.compose.ui.text.input.TextFieldValue,kotlin.Unit> onValueChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional boolean readOnly, optional androidx.compose.ui.text.TextStyle textStyle, optional kotlin.jvm.functions.Function0<kotlin.Unit>? label, optional kotlin.jvm.functions.Function0<kotlin.Unit>? placeholder, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? prefix, optional kotlin.jvm.functions.Function0<kotlin.Unit>? suffix, optional kotlin.jvm.functions.Function0<kotlin.Unit>? supportingText, optional boolean isError, optional androidx.compose.ui.text.input.VisualTransformation visualTransformation, optional androidx.compose.foundation.text.KeyboardOptions keyboardOptions, optional androidx.compose.foundation.text.KeyboardActions keyboardActions, optional boolean singleLine, optional int maxLines, optional int minLines, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.TextFieldColors colors);
+    method @androidx.compose.runtime.Composable public static void OutlinedTextField(androidx.compose.ui.text.input.TextFieldValue value, kotlin.jvm.functions.Function1<? super androidx.compose.ui.text.input.TextFieldValue,kotlin.Unit> onValueChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional boolean readOnly, optional androidx.compose.ui.text.TextStyle textStyle, optional kotlin.jvm.functions.Function0<kotlin.Unit>? label, optional kotlin.jvm.functions.Function0<kotlin.Unit>? placeholder, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? prefix, optional kotlin.jvm.functions.Function0<kotlin.Unit>? suffix, optional kotlin.jvm.functions.Function0<kotlin.Unit>? supportingText, optional boolean isError, optional androidx.compose.ui.text.input.VisualTransformation visualTransformation, optional androidx.compose.foundation.text.KeyboardOptions keyboardOptions, optional androidx.compose.foundation.text.KeyboardActions keyboardActions, optional boolean singleLine, optional int maxLines, optional int minLines, optional androidx.compose.foundation.interaction.MutableInteractionSource? interactionSource, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.TextFieldColors colors);
     method @Deprecated @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void OutlinedTextField(String value, kotlin.jvm.functions.Function1<? super java.lang.String,kotlin.Unit> onValueChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional boolean readOnly, optional androidx.compose.ui.text.TextStyle textStyle, optional kotlin.jvm.functions.Function0<kotlin.Unit>? label, optional kotlin.jvm.functions.Function0<kotlin.Unit>? placeholder, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? supportingText, optional boolean isError, optional androidx.compose.ui.text.input.VisualTransformation visualTransformation, optional androidx.compose.foundation.text.KeyboardOptions keyboardOptions, optional androidx.compose.foundation.text.KeyboardActions keyboardActions, optional boolean singleLine, optional int maxLines, optional int minLines, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.TextFieldColors colors);
-    method @androidx.compose.runtime.Composable public static void OutlinedTextField(String value, kotlin.jvm.functions.Function1<? super java.lang.String,kotlin.Unit> onValueChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional boolean readOnly, optional androidx.compose.ui.text.TextStyle textStyle, optional kotlin.jvm.functions.Function0<kotlin.Unit>? label, optional kotlin.jvm.functions.Function0<kotlin.Unit>? placeholder, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? prefix, optional kotlin.jvm.functions.Function0<kotlin.Unit>? suffix, optional kotlin.jvm.functions.Function0<kotlin.Unit>? supportingText, optional boolean isError, optional androidx.compose.ui.text.input.VisualTransformation visualTransformation, optional androidx.compose.foundation.text.KeyboardOptions keyboardOptions, optional androidx.compose.foundation.text.KeyboardActions keyboardActions, optional boolean singleLine, optional int maxLines, optional int minLines, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.TextFieldColors colors);
+    method @androidx.compose.runtime.Composable public static void OutlinedTextField(String value, kotlin.jvm.functions.Function1<? super java.lang.String,kotlin.Unit> onValueChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional boolean readOnly, optional androidx.compose.ui.text.TextStyle textStyle, optional kotlin.jvm.functions.Function0<kotlin.Unit>? label, optional kotlin.jvm.functions.Function0<kotlin.Unit>? placeholder, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? prefix, optional kotlin.jvm.functions.Function0<kotlin.Unit>? suffix, optional kotlin.jvm.functions.Function0<kotlin.Unit>? supportingText, optional boolean isError, optional androidx.compose.ui.text.input.VisualTransformation visualTransformation, optional androidx.compose.foundation.text.KeyboardOptions keyboardOptions, optional androidx.compose.foundation.text.KeyboardActions keyboardActions, optional boolean singleLine, optional int maxLines, optional int minLines, optional androidx.compose.foundation.interaction.MutableInteractionSource? interactionSource, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.TextFieldColors colors);
   }
 
   public final class ProgressIndicatorDefaults {
@@ -1193,7 +1202,7 @@
   }
 
   public final class RadioButtonKt {
-    method @androidx.compose.runtime.Composable public static void RadioButton(boolean selected, kotlin.jvm.functions.Function0<kotlin.Unit>? onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.material3.RadioButtonColors colors, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource);
+    method @androidx.compose.runtime.Composable public static void RadioButton(boolean selected, kotlin.jvm.functions.Function0<kotlin.Unit>? onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.material3.RadioButtonColors colors, optional androidx.compose.foundation.interaction.MutableInteractionSource? interactionSource);
   }
 
   @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Stable public final class RangeSliderState {
@@ -1296,8 +1305,8 @@
   }
 
   public final class SearchBar_androidKt {
-    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void DockedSearchBar(String query, kotlin.jvm.functions.Function1<? super java.lang.String,kotlin.Unit> onQueryChange, kotlin.jvm.functions.Function1<? super java.lang.String,kotlin.Unit> onSearch, boolean active, kotlin.jvm.functions.Function1<? super java.lang.Boolean,kotlin.Unit> onActiveChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.jvm.functions.Function0<kotlin.Unit>? placeholder, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.SearchBarColors colors, optional float tonalElevation, optional float shadowElevation, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> content);
-    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void SearchBar(String query, kotlin.jvm.functions.Function1<? super java.lang.String,kotlin.Unit> onQueryChange, kotlin.jvm.functions.Function1<? super java.lang.String,kotlin.Unit> onSearch, boolean active, kotlin.jvm.functions.Function1<? super java.lang.Boolean,kotlin.Unit> onActiveChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.jvm.functions.Function0<kotlin.Unit>? placeholder, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.SearchBarColors colors, optional float tonalElevation, optional float shadowElevation, optional androidx.compose.foundation.layout.WindowInsets windowInsets, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> content);
+    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void DockedSearchBar(String query, kotlin.jvm.functions.Function1<? super java.lang.String,kotlin.Unit> onQueryChange, kotlin.jvm.functions.Function1<? super java.lang.String,kotlin.Unit> onSearch, boolean active, kotlin.jvm.functions.Function1<? super java.lang.Boolean,kotlin.Unit> onActiveChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.jvm.functions.Function0<kotlin.Unit>? placeholder, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.SearchBarColors colors, optional float tonalElevation, optional float shadowElevation, optional androidx.compose.foundation.interaction.MutableInteractionSource? interactionSource, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> content);
+    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void SearchBar(String query, kotlin.jvm.functions.Function1<? super java.lang.String,kotlin.Unit> onQueryChange, kotlin.jvm.functions.Function1<? super java.lang.String,kotlin.Unit> onSearch, boolean active, kotlin.jvm.functions.Function1<? super java.lang.Boolean,kotlin.Unit> onActiveChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.jvm.functions.Function0<kotlin.Unit>? placeholder, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.SearchBarColors colors, optional float tonalElevation, optional float shadowElevation, optional androidx.compose.foundation.layout.WindowInsets windowInsets, optional androidx.compose.foundation.interaction.MutableInteractionSource? interactionSource, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> content);
   }
 
   @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Immutable public final class SegmentedButtonColors {
@@ -1347,8 +1356,8 @@
 
   public final class SegmentedButtonKt {
     method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void MultiChoiceSegmentedButtonRow(optional androidx.compose.ui.Modifier modifier, optional float space, kotlin.jvm.functions.Function1<? super androidx.compose.material3.MultiChoiceSegmentedButtonRowScope,kotlin.Unit> content);
-    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void SegmentedButton(androidx.compose.material3.MultiChoiceSegmentedButtonRowScope, boolean checked, kotlin.jvm.functions.Function1<? super java.lang.Boolean,kotlin.Unit> onCheckedChange, androidx.compose.ui.graphics.Shape shape, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.material3.SegmentedButtonColors colors, optional androidx.compose.foundation.BorderStroke border, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional kotlin.jvm.functions.Function0<kotlin.Unit> icon, kotlin.jvm.functions.Function0<kotlin.Unit> label);
-    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void SegmentedButton(androidx.compose.material3.SingleChoiceSegmentedButtonRowScope, boolean selected, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, androidx.compose.ui.graphics.Shape shape, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.material3.SegmentedButtonColors colors, optional androidx.compose.foundation.BorderStroke border, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional kotlin.jvm.functions.Function0<kotlin.Unit> icon, kotlin.jvm.functions.Function0<kotlin.Unit> label);
+    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void SegmentedButton(androidx.compose.material3.MultiChoiceSegmentedButtonRowScope, boolean checked, kotlin.jvm.functions.Function1<? super java.lang.Boolean,kotlin.Unit> onCheckedChange, androidx.compose.ui.graphics.Shape shape, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.material3.SegmentedButtonColors colors, optional androidx.compose.foundation.BorderStroke border, optional androidx.compose.foundation.interaction.MutableInteractionSource? interactionSource, optional kotlin.jvm.functions.Function0<kotlin.Unit> icon, kotlin.jvm.functions.Function0<kotlin.Unit> label);
+    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void SegmentedButton(androidx.compose.material3.SingleChoiceSegmentedButtonRowScope, boolean selected, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, androidx.compose.ui.graphics.Shape shape, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.material3.SegmentedButtonColors colors, optional androidx.compose.foundation.BorderStroke border, optional androidx.compose.foundation.interaction.MutableInteractionSource? interactionSource, optional kotlin.jvm.functions.Function0<kotlin.Unit> icon, kotlin.jvm.functions.Function0<kotlin.Unit> label);
     method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void SingleChoiceSegmentedButtonRow(optional androidx.compose.ui.Modifier modifier, optional float space, kotlin.jvm.functions.Function1<? super androidx.compose.material3.SingleChoiceSegmentedButtonRowScope,kotlin.Unit> content);
   }
 
@@ -1597,9 +1606,9 @@
 
   public final class SurfaceKt {
     method @androidx.compose.runtime.Composable @androidx.compose.runtime.NonRestartableComposable public static void Surface(optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.graphics.Shape shape, optional long color, optional long contentColor, optional float tonalElevation, optional float shadowElevation, optional androidx.compose.foundation.BorderStroke? border, kotlin.jvm.functions.Function0<kotlin.Unit> content);
-    method @androidx.compose.runtime.Composable @androidx.compose.runtime.NonRestartableComposable public static void Surface(boolean selected, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional long color, optional long contentColor, optional float tonalElevation, optional float shadowElevation, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function0<kotlin.Unit> content);
-    method @androidx.compose.runtime.Composable @androidx.compose.runtime.NonRestartableComposable public static void Surface(boolean checked, kotlin.jvm.functions.Function1<? super java.lang.Boolean,kotlin.Unit> onCheckedChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional long color, optional long contentColor, optional float tonalElevation, optional float shadowElevation, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function0<kotlin.Unit> content);
-    method @androidx.compose.runtime.Composable @androidx.compose.runtime.NonRestartableComposable public static void Surface(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional long color, optional long contentColor, optional float tonalElevation, optional float shadowElevation, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable @androidx.compose.runtime.NonRestartableComposable public static void Surface(boolean selected, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional long color, optional long contentColor, optional float tonalElevation, optional float shadowElevation, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.interaction.MutableInteractionSource? interactionSource, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable @androidx.compose.runtime.NonRestartableComposable public static void Surface(boolean checked, kotlin.jvm.functions.Function1<? super java.lang.Boolean,kotlin.Unit> onCheckedChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional long color, optional long contentColor, optional float tonalElevation, optional float shadowElevation, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.interaction.MutableInteractionSource? interactionSource, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable @androidx.compose.runtime.NonRestartableComposable public static void Surface(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional long color, optional long contentColor, optional float tonalElevation, optional float shadowElevation, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.interaction.MutableInteractionSource? interactionSource, kotlin.jvm.functions.Function0<kotlin.Unit> content);
     method public static androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.unit.Dp> getLocalAbsoluteTonalElevation();
     property public static final androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.unit.Dp> LocalAbsoluteTonalElevation;
   }
@@ -1692,7 +1701,7 @@
   }
 
   public final class SwitchKt {
-    method @androidx.compose.runtime.Composable public static void Switch(boolean checked, kotlin.jvm.functions.Function1<? super java.lang.Boolean,kotlin.Unit>? onCheckedChange, optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function0<kotlin.Unit>? thumbContent, optional boolean enabled, optional androidx.compose.material3.SwitchColors colors, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource);
+    method @androidx.compose.runtime.Composable public static void Switch(boolean checked, kotlin.jvm.functions.Function1<? super java.lang.Boolean,kotlin.Unit>? onCheckedChange, optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function0<kotlin.Unit>? thumbContent, optional boolean enabled, optional androidx.compose.material3.SwitchColors colors, optional androidx.compose.foundation.interaction.MutableInteractionSource? interactionSource);
   }
 
   @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api public interface TabIndicatorScope {
@@ -1701,9 +1710,9 @@
   }
 
   public final class TabKt {
-    method @androidx.compose.runtime.Composable public static void LeadingIconTab(boolean selected, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, kotlin.jvm.functions.Function0<kotlin.Unit> text, kotlin.jvm.functions.Function0<kotlin.Unit> icon, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional long selectedContentColor, optional long unselectedContentColor, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource);
-    method @androidx.compose.runtime.Composable public static void Tab(boolean selected, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.jvm.functions.Function0<kotlin.Unit>? text, optional kotlin.jvm.functions.Function0<kotlin.Unit>? icon, optional long selectedContentColor, optional long unselectedContentColor, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource);
-    method @androidx.compose.runtime.Composable public static void Tab(boolean selected, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional long selectedContentColor, optional long unselectedContentColor, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void LeadingIconTab(boolean selected, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, kotlin.jvm.functions.Function0<kotlin.Unit> text, kotlin.jvm.functions.Function0<kotlin.Unit> icon, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional long selectedContentColor, optional long unselectedContentColor, optional androidx.compose.foundation.interaction.MutableInteractionSource? interactionSource);
+    method @androidx.compose.runtime.Composable public static void Tab(boolean selected, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.jvm.functions.Function0<kotlin.Unit>? text, optional kotlin.jvm.functions.Function0<kotlin.Unit>? icon, optional long selectedContentColor, optional long unselectedContentColor, optional androidx.compose.foundation.interaction.MutableInteractionSource? interactionSource);
+    method @androidx.compose.runtime.Composable public static void Tab(boolean selected, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional long selectedContentColor, optional long unselectedContentColor, optional androidx.compose.foundation.interaction.MutableInteractionSource? interactionSource, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> content);
   }
 
   @androidx.compose.runtime.Immutable public final class TabPosition {
@@ -1883,9 +1892,9 @@
 
   public final class TextFieldKt {
     method @Deprecated @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void TextField(androidx.compose.ui.text.input.TextFieldValue value, kotlin.jvm.functions.Function1<? super androidx.compose.ui.text.input.TextFieldValue,kotlin.Unit> onValueChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional boolean readOnly, optional androidx.compose.ui.text.TextStyle textStyle, optional kotlin.jvm.functions.Function0<kotlin.Unit>? label, optional kotlin.jvm.functions.Function0<kotlin.Unit>? placeholder, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? supportingText, optional boolean isError, optional androidx.compose.ui.text.input.VisualTransformation visualTransformation, optional androidx.compose.foundation.text.KeyboardOptions keyboardOptions, optional androidx.compose.foundation.text.KeyboardActions keyboardActions, optional boolean singleLine, optional int maxLines, optional int minLines, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.TextFieldColors colors);
-    method @androidx.compose.runtime.Composable public static void TextField(androidx.compose.ui.text.input.TextFieldValue value, kotlin.jvm.functions.Function1<? super androidx.compose.ui.text.input.TextFieldValue,kotlin.Unit> onValueChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional boolean readOnly, optional androidx.compose.ui.text.TextStyle textStyle, optional kotlin.jvm.functions.Function0<kotlin.Unit>? label, optional kotlin.jvm.functions.Function0<kotlin.Unit>? placeholder, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? prefix, optional kotlin.jvm.functions.Function0<kotlin.Unit>? suffix, optional kotlin.jvm.functions.Function0<kotlin.Unit>? supportingText, optional boolean isError, optional androidx.compose.ui.text.input.VisualTransformation visualTransformation, optional androidx.compose.foundation.text.KeyboardOptions keyboardOptions, optional androidx.compose.foundation.text.KeyboardActions keyboardActions, optional boolean singleLine, optional int maxLines, optional int minLines, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.TextFieldColors colors);
+    method @androidx.compose.runtime.Composable public static void TextField(androidx.compose.ui.text.input.TextFieldValue value, kotlin.jvm.functions.Function1<? super androidx.compose.ui.text.input.TextFieldValue,kotlin.Unit> onValueChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional boolean readOnly, optional androidx.compose.ui.text.TextStyle textStyle, optional kotlin.jvm.functions.Function0<kotlin.Unit>? label, optional kotlin.jvm.functions.Function0<kotlin.Unit>? placeholder, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? prefix, optional kotlin.jvm.functions.Function0<kotlin.Unit>? suffix, optional kotlin.jvm.functions.Function0<kotlin.Unit>? supportingText, optional boolean isError, optional androidx.compose.ui.text.input.VisualTransformation visualTransformation, optional androidx.compose.foundation.text.KeyboardOptions keyboardOptions, optional androidx.compose.foundation.text.KeyboardActions keyboardActions, optional boolean singleLine, optional int maxLines, optional int minLines, optional androidx.compose.foundation.interaction.MutableInteractionSource? interactionSource, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.TextFieldColors colors);
     method @Deprecated @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void TextField(String value, kotlin.jvm.functions.Function1<? super java.lang.String,kotlin.Unit> onValueChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional boolean readOnly, optional androidx.compose.ui.text.TextStyle textStyle, optional kotlin.jvm.functions.Function0<kotlin.Unit>? label, optional kotlin.jvm.functions.Function0<kotlin.Unit>? placeholder, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? supportingText, optional boolean isError, optional androidx.compose.ui.text.input.VisualTransformation visualTransformation, optional androidx.compose.foundation.text.KeyboardOptions keyboardOptions, optional androidx.compose.foundation.text.KeyboardActions keyboardActions, optional boolean singleLine, optional int maxLines, optional int minLines, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.TextFieldColors colors);
-    method @androidx.compose.runtime.Composable public static void TextField(String value, kotlin.jvm.functions.Function1<? super java.lang.String,kotlin.Unit> onValueChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional boolean readOnly, optional androidx.compose.ui.text.TextStyle textStyle, optional kotlin.jvm.functions.Function0<kotlin.Unit>? label, optional kotlin.jvm.functions.Function0<kotlin.Unit>? placeholder, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? prefix, optional kotlin.jvm.functions.Function0<kotlin.Unit>? suffix, optional kotlin.jvm.functions.Function0<kotlin.Unit>? supportingText, optional boolean isError, optional androidx.compose.ui.text.input.VisualTransformation visualTransformation, optional androidx.compose.foundation.text.KeyboardOptions keyboardOptions, optional androidx.compose.foundation.text.KeyboardActions keyboardActions, optional boolean singleLine, optional int maxLines, optional int minLines, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.TextFieldColors colors);
+    method @androidx.compose.runtime.Composable public static void TextField(String value, kotlin.jvm.functions.Function1<? super java.lang.String,kotlin.Unit> onValueChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional boolean readOnly, optional androidx.compose.ui.text.TextStyle textStyle, optional kotlin.jvm.functions.Function0<kotlin.Unit>? label, optional kotlin.jvm.functions.Function0<kotlin.Unit>? placeholder, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? prefix, optional kotlin.jvm.functions.Function0<kotlin.Unit>? suffix, optional kotlin.jvm.functions.Function0<kotlin.Unit>? supportingText, optional boolean isError, optional androidx.compose.ui.text.input.VisualTransformation visualTransformation, optional androidx.compose.foundation.text.KeyboardOptions keyboardOptions, optional androidx.compose.foundation.text.KeyboardActions keyboardActions, optional boolean singleLine, optional int maxLines, optional int minLines, optional androidx.compose.foundation.interaction.MutableInteractionSource? interactionSource, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.TextFieldColors colors);
   }
 
   public final class TextKt {
diff --git a/compose/material3/material3/api/restricted_current.txt b/compose/material3/material3/api/restricted_current.txt
index e886d19..05ecd27 100644
--- a/compose/material3/material3/api/restricted_current.txt
+++ b/compose/material3/material3/api/restricted_current.txt
@@ -24,9 +24,10 @@
   }
 
   public final class AndroidMenu_androidKt {
-    method @androidx.compose.runtime.Composable public static void DropdownMenu(boolean expanded, kotlin.jvm.functions.Function0<kotlin.Unit> onDismissRequest, optional androidx.compose.ui.Modifier modifier, optional long offset, optional androidx.compose.foundation.ScrollState scrollState, optional androidx.compose.ui.window.PopupProperties properties, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void DropdownMenu(boolean expanded, kotlin.jvm.functions.Function0<kotlin.Unit> onDismissRequest, optional androidx.compose.ui.Modifier modifier, optional long offset, optional androidx.compose.foundation.ScrollState scrollState, optional androidx.compose.ui.window.PopupProperties properties, optional androidx.compose.ui.graphics.Shape shape, optional long containerColor, optional float tonalElevation, optional float shadowElevation, optional androidx.compose.foundation.BorderStroke? border, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> content);
+    method @Deprecated @androidx.compose.runtime.Composable public static void DropdownMenu(boolean expanded, kotlin.jvm.functions.Function0<kotlin.Unit> onDismissRequest, optional androidx.compose.ui.Modifier modifier, optional long offset, optional androidx.compose.foundation.ScrollState scrollState, optional androidx.compose.ui.window.PopupProperties properties, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> content);
     method @Deprecated @androidx.compose.runtime.Composable public static void DropdownMenu(boolean expanded, kotlin.jvm.functions.Function0<kotlin.Unit> onDismissRequest, optional androidx.compose.ui.Modifier modifier, optional long offset, optional androidx.compose.ui.window.PopupProperties properties, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> content);
-    method @androidx.compose.runtime.Composable public static void DropdownMenuItem(kotlin.jvm.functions.Function0<kotlin.Unit> text, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional boolean enabled, optional androidx.compose.material3.MenuItemColors colors, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource);
+    method @androidx.compose.runtime.Composable public static void DropdownMenuItem(kotlin.jvm.functions.Function0<kotlin.Unit> text, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional boolean enabled, optional androidx.compose.material3.MenuItemColors colors, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.interaction.MutableInteractionSource? interactionSource);
   }
 
   public final class AppBarKt {
@@ -228,11 +229,11 @@
   }
 
   public final class ButtonKt {
-    method @androidx.compose.runtime.Composable public static void Button(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.ButtonColors colors, optional androidx.compose.material3.ButtonElevation? elevation, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content);
-    method @androidx.compose.runtime.Composable public static void ElevatedButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.ButtonColors colors, optional androidx.compose.material3.ButtonElevation? elevation, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content);
-    method @androidx.compose.runtime.Composable public static void FilledTonalButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.ButtonColors colors, optional androidx.compose.material3.ButtonElevation? elevation, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content);
-    method @androidx.compose.runtime.Composable public static void OutlinedButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.ButtonColors colors, optional androidx.compose.material3.ButtonElevation? elevation, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content);
-    method @androidx.compose.runtime.Composable public static void TextButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.ButtonColors colors, optional androidx.compose.material3.ButtonElevation? elevation, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void Button(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.ButtonColors colors, optional androidx.compose.material3.ButtonElevation? elevation, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.interaction.MutableInteractionSource? interactionSource, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void ElevatedButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.ButtonColors colors, optional androidx.compose.material3.ButtonElevation? elevation, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.interaction.MutableInteractionSource? interactionSource, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void FilledTonalButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.ButtonColors colors, optional androidx.compose.material3.ButtonElevation? elevation, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.interaction.MutableInteractionSource? interactionSource, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void OutlinedButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.ButtonColors colors, optional androidx.compose.material3.ButtonElevation? elevation, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.interaction.MutableInteractionSource? interactionSource, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void TextButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.ButtonColors colors, optional androidx.compose.material3.ButtonElevation? elevation, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.interaction.MutableInteractionSource? interactionSource, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content);
   }
 
   public final class CalendarModel_androidKt {
@@ -277,11 +278,11 @@
 
   public final class CardKt {
     method @androidx.compose.runtime.Composable public static void Card(optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.CardColors colors, optional androidx.compose.material3.CardElevation elevation, optional androidx.compose.foundation.BorderStroke? border, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> content);
-    method @androidx.compose.runtime.Composable public static void Card(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.CardColors colors, optional androidx.compose.material3.CardElevation elevation, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void Card(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.CardColors colors, optional androidx.compose.material3.CardElevation elevation, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.interaction.MutableInteractionSource? interactionSource, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> content);
     method @androidx.compose.runtime.Composable public static void ElevatedCard(optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.CardColors colors, optional androidx.compose.material3.CardElevation elevation, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> content);
-    method @androidx.compose.runtime.Composable public static void ElevatedCard(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.CardColors colors, optional androidx.compose.material3.CardElevation elevation, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void ElevatedCard(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.CardColors colors, optional androidx.compose.material3.CardElevation elevation, optional androidx.compose.foundation.interaction.MutableInteractionSource? interactionSource, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> content);
     method @androidx.compose.runtime.Composable public static void OutlinedCard(optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.CardColors colors, optional androidx.compose.material3.CardElevation elevation, optional androidx.compose.foundation.BorderStroke border, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> content);
-    method @androidx.compose.runtime.Composable public static void OutlinedCard(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.CardColors colors, optional androidx.compose.material3.CardElevation elevation, optional androidx.compose.foundation.BorderStroke border, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void OutlinedCard(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.CardColors colors, optional androidx.compose.material3.CardElevation elevation, optional androidx.compose.foundation.BorderStroke border, optional androidx.compose.foundation.interaction.MutableInteractionSource? interactionSource, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> content);
   }
 
   @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Stable public final class CaretProperties {
@@ -335,8 +336,8 @@
   }
 
   public final class CheckboxKt {
-    method @androidx.compose.runtime.Composable public static void Checkbox(boolean checked, kotlin.jvm.functions.Function1<? super java.lang.Boolean,kotlin.Unit>? onCheckedChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.material3.CheckboxColors colors, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource);
-    method @androidx.compose.runtime.Composable public static void TriStateCheckbox(androidx.compose.ui.state.ToggleableState state, kotlin.jvm.functions.Function0<kotlin.Unit>? onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.material3.CheckboxColors colors, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource);
+    method @androidx.compose.runtime.Composable public static void Checkbox(boolean checked, kotlin.jvm.functions.Function1<? super java.lang.Boolean,kotlin.Unit>? onCheckedChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.material3.CheckboxColors colors, optional androidx.compose.foundation.interaction.MutableInteractionSource? interactionSource);
+    method @androidx.compose.runtime.Composable public static void TriStateCheckbox(androidx.compose.ui.state.ToggleableState state, kotlin.jvm.functions.Function0<kotlin.Unit>? onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.material3.CheckboxColors colors, optional androidx.compose.foundation.interaction.MutableInteractionSource? interactionSource);
   }
 
   @Deprecated @androidx.compose.runtime.Immutable public final class ChipBorder {
@@ -380,16 +381,16 @@
   }
 
   public final class ChipKt {
-    method @androidx.compose.runtime.Composable public static void AssistChip(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, kotlin.jvm.functions.Function0<kotlin.Unit> label, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.ChipColors colors, optional androidx.compose.material3.ChipElevation? elevation, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource);
+    method @androidx.compose.runtime.Composable public static void AssistChip(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, kotlin.jvm.functions.Function0<kotlin.Unit> label, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.ChipColors colors, optional androidx.compose.material3.ChipElevation? elevation, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.interaction.MutableInteractionSource? interactionSource);
     method @Deprecated @androidx.compose.runtime.Composable public static void AssistChip(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, kotlin.jvm.functions.Function0<kotlin.Unit> label, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.ChipColors colors, optional androidx.compose.material3.ChipElevation? elevation, optional androidx.compose.material3.ChipBorder? border, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource);
-    method @androidx.compose.runtime.Composable public static void ElevatedAssistChip(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, kotlin.jvm.functions.Function0<kotlin.Unit> label, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.ChipColors colors, optional androidx.compose.material3.ChipElevation? elevation, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource);
+    method @androidx.compose.runtime.Composable public static void ElevatedAssistChip(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, kotlin.jvm.functions.Function0<kotlin.Unit> label, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.ChipColors colors, optional androidx.compose.material3.ChipElevation? elevation, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.interaction.MutableInteractionSource? interactionSource);
     method @Deprecated @androidx.compose.runtime.Composable public static void ElevatedAssistChip(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, kotlin.jvm.functions.Function0<kotlin.Unit> label, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.ChipColors colors, optional androidx.compose.material3.ChipElevation? elevation, optional androidx.compose.material3.ChipBorder? border, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource);
-    method @androidx.compose.runtime.Composable public static void ElevatedFilterChip(boolean selected, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, kotlin.jvm.functions.Function0<kotlin.Unit> label, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.SelectableChipColors colors, optional androidx.compose.material3.SelectableChipElevation? elevation, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource);
-    method @androidx.compose.runtime.Composable public static void ElevatedSuggestionChip(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, kotlin.jvm.functions.Function0<kotlin.Unit> label, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.jvm.functions.Function0<kotlin.Unit>? icon, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.ChipColors colors, optional androidx.compose.material3.ChipElevation? elevation, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource);
+    method @androidx.compose.runtime.Composable public static void ElevatedFilterChip(boolean selected, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, kotlin.jvm.functions.Function0<kotlin.Unit> label, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.SelectableChipColors colors, optional androidx.compose.material3.SelectableChipElevation? elevation, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.interaction.MutableInteractionSource? interactionSource);
+    method @androidx.compose.runtime.Composable public static void ElevatedSuggestionChip(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, kotlin.jvm.functions.Function0<kotlin.Unit> label, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.jvm.functions.Function0<kotlin.Unit>? icon, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.ChipColors colors, optional androidx.compose.material3.ChipElevation? elevation, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.interaction.MutableInteractionSource? interactionSource);
     method @Deprecated @androidx.compose.runtime.Composable public static void ElevatedSuggestionChip(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, kotlin.jvm.functions.Function0<kotlin.Unit> label, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.jvm.functions.Function0<kotlin.Unit>? icon, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.ChipColors colors, optional androidx.compose.material3.ChipElevation? elevation, optional androidx.compose.material3.ChipBorder? border, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource);
-    method @androidx.compose.runtime.Composable public static void FilterChip(boolean selected, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, kotlin.jvm.functions.Function0<kotlin.Unit> label, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.SelectableChipColors colors, optional androidx.compose.material3.SelectableChipElevation? elevation, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource);
-    method @androidx.compose.runtime.Composable public static void InputChip(boolean selected, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, kotlin.jvm.functions.Function0<kotlin.Unit> label, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? avatar, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.SelectableChipColors colors, optional androidx.compose.material3.SelectableChipElevation? elevation, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource);
-    method @androidx.compose.runtime.Composable public static void SuggestionChip(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, kotlin.jvm.functions.Function0<kotlin.Unit> label, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.jvm.functions.Function0<kotlin.Unit>? icon, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.ChipColors colors, optional androidx.compose.material3.ChipElevation? elevation, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource);
+    method @androidx.compose.runtime.Composable public static void FilterChip(boolean selected, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, kotlin.jvm.functions.Function0<kotlin.Unit> label, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.SelectableChipColors colors, optional androidx.compose.material3.SelectableChipElevation? elevation, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.interaction.MutableInteractionSource? interactionSource);
+    method @androidx.compose.runtime.Composable public static void InputChip(boolean selected, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, kotlin.jvm.functions.Function0<kotlin.Unit> label, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? avatar, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.SelectableChipColors colors, optional androidx.compose.material3.SelectableChipElevation? elevation, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.interaction.MutableInteractionSource? interactionSource);
+    method @androidx.compose.runtime.Composable public static void SuggestionChip(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, kotlin.jvm.functions.Function0<kotlin.Unit> label, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.jvm.functions.Function0<kotlin.Unit>? icon, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.ChipColors colors, optional androidx.compose.material3.ChipElevation? elevation, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.interaction.MutableInteractionSource? interactionSource);
     method @Deprecated @androidx.compose.runtime.Composable public static void SuggestionChip(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, kotlin.jvm.functions.Function0<kotlin.Unit> label, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.jvm.functions.Function0<kotlin.Unit>? icon, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.ChipColors colors, optional androidx.compose.material3.ChipElevation? elevation, optional androidx.compose.material3.ChipBorder? border, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource);
   }
 
@@ -806,11 +807,11 @@
   }
 
   public final class FloatingActionButtonKt {
-    method @androidx.compose.runtime.Composable public static void ExtendedFloatingActionButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.graphics.Shape shape, optional long containerColor, optional long contentColor, optional androidx.compose.material3.FloatingActionButtonElevation elevation, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content);
-    method @androidx.compose.runtime.Composable public static void ExtendedFloatingActionButton(kotlin.jvm.functions.Function0<kotlin.Unit> text, kotlin.jvm.functions.Function0<kotlin.Unit> icon, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean expanded, optional androidx.compose.ui.graphics.Shape shape, optional long containerColor, optional long contentColor, optional androidx.compose.material3.FloatingActionButtonElevation elevation, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource);
-    method @androidx.compose.runtime.Composable public static void FloatingActionButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.graphics.Shape shape, optional long containerColor, optional long contentColor, optional androidx.compose.material3.FloatingActionButtonElevation elevation, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function0<kotlin.Unit> content);
-    method @androidx.compose.runtime.Composable public static void LargeFloatingActionButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.graphics.Shape shape, optional long containerColor, optional long contentColor, optional androidx.compose.material3.FloatingActionButtonElevation elevation, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function0<kotlin.Unit> content);
-    method @androidx.compose.runtime.Composable public static void SmallFloatingActionButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.graphics.Shape shape, optional long containerColor, optional long contentColor, optional androidx.compose.material3.FloatingActionButtonElevation elevation, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void ExtendedFloatingActionButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.graphics.Shape shape, optional long containerColor, optional long contentColor, optional androidx.compose.material3.FloatingActionButtonElevation elevation, optional androidx.compose.foundation.interaction.MutableInteractionSource? interactionSource, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void ExtendedFloatingActionButton(kotlin.jvm.functions.Function0<kotlin.Unit> text, kotlin.jvm.functions.Function0<kotlin.Unit> icon, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean expanded, optional androidx.compose.ui.graphics.Shape shape, optional long containerColor, optional long contentColor, optional androidx.compose.material3.FloatingActionButtonElevation elevation, optional androidx.compose.foundation.interaction.MutableInteractionSource? interactionSource);
+    method @androidx.compose.runtime.Composable public static void FloatingActionButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.graphics.Shape shape, optional long containerColor, optional long contentColor, optional androidx.compose.material3.FloatingActionButtonElevation elevation, optional androidx.compose.foundation.interaction.MutableInteractionSource? interactionSource, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void LargeFloatingActionButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.graphics.Shape shape, optional long containerColor, optional long contentColor, optional androidx.compose.material3.FloatingActionButtonElevation elevation, optional androidx.compose.foundation.interaction.MutableInteractionSource? interactionSource, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void SmallFloatingActionButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.graphics.Shape shape, optional long containerColor, optional long contentColor, optional androidx.compose.material3.FloatingActionButtonElevation elevation, optional androidx.compose.foundation.interaction.MutableInteractionSource? interactionSource, kotlin.jvm.functions.Function0<kotlin.Unit> content);
   }
 
   @androidx.compose.runtime.Immutable public final class IconButtonColors {
@@ -846,14 +847,14 @@
   }
 
   public final class IconButtonKt {
-    method @androidx.compose.runtime.Composable public static void FilledIconButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.IconButtonColors colors, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function0<kotlin.Unit> content);
-    method @androidx.compose.runtime.Composable public static void FilledIconToggleButton(boolean checked, kotlin.jvm.functions.Function1<? super java.lang.Boolean,kotlin.Unit> onCheckedChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.IconToggleButtonColors colors, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function0<kotlin.Unit> content);
-    method @androidx.compose.runtime.Composable public static void FilledTonalIconButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.IconButtonColors colors, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function0<kotlin.Unit> content);
-    method @androidx.compose.runtime.Composable public static void FilledTonalIconToggleButton(boolean checked, kotlin.jvm.functions.Function1<? super java.lang.Boolean,kotlin.Unit> onCheckedChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.IconToggleButtonColors colors, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function0<kotlin.Unit> content);
-    method @androidx.compose.runtime.Composable public static void IconButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.material3.IconButtonColors colors, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function0<kotlin.Unit> content);
-    method @androidx.compose.runtime.Composable public static void IconToggleButton(boolean checked, kotlin.jvm.functions.Function1<? super java.lang.Boolean,kotlin.Unit> onCheckedChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.material3.IconToggleButtonColors colors, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function0<kotlin.Unit> content);
-    method @androidx.compose.runtime.Composable public static void OutlinedIconButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.IconButtonColors colors, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function0<kotlin.Unit> content);
-    method @androidx.compose.runtime.Composable public static void OutlinedIconToggleButton(boolean checked, kotlin.jvm.functions.Function1<? super java.lang.Boolean,kotlin.Unit> onCheckedChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.IconToggleButtonColors colors, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void FilledIconButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.IconButtonColors colors, optional androidx.compose.foundation.interaction.MutableInteractionSource? interactionSource, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void FilledIconToggleButton(boolean checked, kotlin.jvm.functions.Function1<? super java.lang.Boolean,kotlin.Unit> onCheckedChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.IconToggleButtonColors colors, optional androidx.compose.foundation.interaction.MutableInteractionSource? interactionSource, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void FilledTonalIconButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.IconButtonColors colors, optional androidx.compose.foundation.interaction.MutableInteractionSource? interactionSource, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void FilledTonalIconToggleButton(boolean checked, kotlin.jvm.functions.Function1<? super java.lang.Boolean,kotlin.Unit> onCheckedChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.IconToggleButtonColors colors, optional androidx.compose.foundation.interaction.MutableInteractionSource? interactionSource, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void IconButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.material3.IconButtonColors colors, optional androidx.compose.foundation.interaction.MutableInteractionSource? interactionSource, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void IconToggleButton(boolean checked, kotlin.jvm.functions.Function1<? super java.lang.Boolean,kotlin.Unit> onCheckedChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.material3.IconToggleButtonColors colors, optional androidx.compose.foundation.interaction.MutableInteractionSource? interactionSource, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void OutlinedIconButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.IconButtonColors colors, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.interaction.MutableInteractionSource? interactionSource, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void OutlinedIconToggleButton(boolean checked, kotlin.jvm.functions.Function1<? super java.lang.Boolean,kotlin.Unit> onCheckedChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.IconToggleButtonColors colors, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.interaction.MutableInteractionSource? interactionSource, kotlin.jvm.functions.Function0<kotlin.Unit> content);
   }
 
   public final class IconKt {
@@ -903,7 +904,7 @@
   }
 
   public final class LabelKt {
-    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void Label(kotlin.jvm.functions.Function1<? super androidx.compose.material3.CaretScope,kotlin.Unit> label, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional boolean isPersistent, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void Label(kotlin.jvm.functions.Function1<? super androidx.compose.material3.CaretScope,kotlin.Unit> label, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.foundation.interaction.MutableInteractionSource? interactionSource, optional boolean isPersistent, kotlin.jvm.functions.Function0<kotlin.Unit> content);
   }
 
   @androidx.compose.runtime.Immutable public final class ListItemColors {
@@ -960,10 +961,18 @@
   }
 
   public final class MenuDefaults {
+    method @androidx.compose.runtime.Composable public long getContainerColor();
     method public androidx.compose.foundation.layout.PaddingValues getDropdownMenuItemContentPadding();
+    method public float getShadowElevation();
+    method @androidx.compose.runtime.Composable public androidx.compose.ui.graphics.Shape getShape();
+    method public float getTonalElevation();
     method @androidx.compose.runtime.Composable public androidx.compose.material3.MenuItemColors itemColors();
     method @androidx.compose.runtime.Composable public androidx.compose.material3.MenuItemColors itemColors(optional long textColor, optional long leadingIconColor, optional long trailingIconColor, optional long disabledTextColor, optional long disabledLeadingIconColor, optional long disabledTrailingIconColor);
     property public final androidx.compose.foundation.layout.PaddingValues DropdownMenuItemContentPadding;
+    property public final float ShadowElevation;
+    property public final float TonalElevation;
+    property @androidx.compose.runtime.Composable public final long containerColor;
+    property @androidx.compose.runtime.Composable public final androidx.compose.ui.graphics.Shape shape;
     field public static final androidx.compose.material3.MenuDefaults INSTANCE;
   }
 
@@ -1045,7 +1054,7 @@
 
   public final class NavigationBarKt {
     method @androidx.compose.runtime.Composable public static void NavigationBar(optional androidx.compose.ui.Modifier modifier, optional long containerColor, optional long contentColor, optional float tonalElevation, optional androidx.compose.foundation.layout.WindowInsets windowInsets, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content);
-    method @androidx.compose.runtime.Composable public static void NavigationBarItem(androidx.compose.foundation.layout.RowScope, boolean selected, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, kotlin.jvm.functions.Function0<kotlin.Unit> icon, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.jvm.functions.Function0<kotlin.Unit>? label, optional boolean alwaysShowLabel, optional androidx.compose.material3.NavigationBarItemColors colors, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource);
+    method @androidx.compose.runtime.Composable public static void NavigationBarItem(androidx.compose.foundation.layout.RowScope, boolean selected, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, kotlin.jvm.functions.Function0<kotlin.Unit> icon, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.jvm.functions.Function0<kotlin.Unit>? label, optional boolean alwaysShowLabel, optional androidx.compose.material3.NavigationBarItemColors colors, optional androidx.compose.foundation.interaction.MutableInteractionSource? interactionSource);
   }
 
   @androidx.compose.runtime.Stable public interface NavigationDrawerItemColors {
@@ -1067,7 +1076,7 @@
     method @androidx.compose.runtime.Composable public static void DismissibleNavigationDrawer(kotlin.jvm.functions.Function0<kotlin.Unit> drawerContent, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.material3.DrawerState drawerState, optional boolean gesturesEnabled, kotlin.jvm.functions.Function0<kotlin.Unit> content);
     method @androidx.compose.runtime.Composable public static void ModalDrawerSheet(optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.graphics.Shape drawerShape, optional long drawerContainerColor, optional long drawerContentColor, optional float drawerTonalElevation, optional androidx.compose.foundation.layout.WindowInsets windowInsets, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> content);
     method @androidx.compose.runtime.Composable public static void ModalNavigationDrawer(kotlin.jvm.functions.Function0<kotlin.Unit> drawerContent, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.material3.DrawerState drawerState, optional boolean gesturesEnabled, optional long scrimColor, kotlin.jvm.functions.Function0<kotlin.Unit> content);
-    method @androidx.compose.runtime.Composable public static void NavigationDrawerItem(kotlin.jvm.functions.Function0<kotlin.Unit> label, boolean selected, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function0<kotlin.Unit>? icon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? badge, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.NavigationDrawerItemColors colors, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource);
+    method @androidx.compose.runtime.Composable public static void NavigationDrawerItem(kotlin.jvm.functions.Function0<kotlin.Unit> label, boolean selected, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function0<kotlin.Unit>? icon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? badge, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.NavigationDrawerItemColors colors, optional androidx.compose.foundation.interaction.MutableInteractionSource? interactionSource);
     method @androidx.compose.runtime.Composable public static void PermanentDrawerSheet(optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.graphics.Shape drawerShape, optional long drawerContainerColor, optional long drawerContentColor, optional float drawerTonalElevation, optional androidx.compose.foundation.layout.WindowInsets windowInsets, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> content);
     method @androidx.compose.runtime.Composable public static void PermanentNavigationDrawer(kotlin.jvm.functions.Function0<kotlin.Unit> drawerContent, optional androidx.compose.ui.Modifier modifier, kotlin.jvm.functions.Function0<kotlin.Unit> content);
     method @androidx.compose.runtime.Composable public static androidx.compose.material3.DrawerState rememberDrawerState(androidx.compose.material3.DrawerValue initialValue, optional kotlin.jvm.functions.Function1<? super androidx.compose.material3.DrawerValue,java.lang.Boolean> confirmStateChange);
@@ -1109,7 +1118,7 @@
 
   public final class NavigationRailKt {
     method @androidx.compose.runtime.Composable public static void NavigationRail(optional androidx.compose.ui.Modifier modifier, optional long containerColor, optional long contentColor, optional kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit>? header, optional androidx.compose.foundation.layout.WindowInsets windowInsets, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> content);
-    method @androidx.compose.runtime.Composable public static void NavigationRailItem(boolean selected, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, kotlin.jvm.functions.Function0<kotlin.Unit> icon, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.jvm.functions.Function0<kotlin.Unit>? label, optional boolean alwaysShowLabel, optional androidx.compose.material3.NavigationRailItemColors colors, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource);
+    method @androidx.compose.runtime.Composable public static void NavigationRailItem(boolean selected, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, kotlin.jvm.functions.Function0<kotlin.Unit> icon, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.jvm.functions.Function0<kotlin.Unit>? label, optional boolean alwaysShowLabel, optional androidx.compose.material3.NavigationRailItemColors colors, optional androidx.compose.foundation.interaction.MutableInteractionSource? interactionSource);
   }
 
   @androidx.compose.runtime.Immutable public final class OutlinedTextFieldDefaults {
@@ -1133,9 +1142,9 @@
 
   public final class OutlinedTextFieldKt {
     method @Deprecated @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void OutlinedTextField(androidx.compose.ui.text.input.TextFieldValue value, kotlin.jvm.functions.Function1<? super androidx.compose.ui.text.input.TextFieldValue,kotlin.Unit> onValueChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional boolean readOnly, optional androidx.compose.ui.text.TextStyle textStyle, optional kotlin.jvm.functions.Function0<kotlin.Unit>? label, optional kotlin.jvm.functions.Function0<kotlin.Unit>? placeholder, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? supportingText, optional boolean isError, optional androidx.compose.ui.text.input.VisualTransformation visualTransformation, optional androidx.compose.foundation.text.KeyboardOptions keyboardOptions, optional androidx.compose.foundation.text.KeyboardActions keyboardActions, optional boolean singleLine, optional int maxLines, optional int minLines, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.TextFieldColors colors);
-    method @androidx.compose.runtime.Composable public static void OutlinedTextField(androidx.compose.ui.text.input.TextFieldValue value, kotlin.jvm.functions.Function1<? super androidx.compose.ui.text.input.TextFieldValue,kotlin.Unit> onValueChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional boolean readOnly, optional androidx.compose.ui.text.TextStyle textStyle, optional kotlin.jvm.functions.Function0<kotlin.Unit>? label, optional kotlin.jvm.functions.Function0<kotlin.Unit>? placeholder, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? prefix, optional kotlin.jvm.functions.Function0<kotlin.Unit>? suffix, optional kotlin.jvm.functions.Function0<kotlin.Unit>? supportingText, optional boolean isError, optional androidx.compose.ui.text.input.VisualTransformation visualTransformation, optional androidx.compose.foundation.text.KeyboardOptions keyboardOptions, optional androidx.compose.foundation.text.KeyboardActions keyboardActions, optional boolean singleLine, optional int maxLines, optional int minLines, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.TextFieldColors colors);
+    method @androidx.compose.runtime.Composable public static void OutlinedTextField(androidx.compose.ui.text.input.TextFieldValue value, kotlin.jvm.functions.Function1<? super androidx.compose.ui.text.input.TextFieldValue,kotlin.Unit> onValueChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional boolean readOnly, optional androidx.compose.ui.text.TextStyle textStyle, optional kotlin.jvm.functions.Function0<kotlin.Unit>? label, optional kotlin.jvm.functions.Function0<kotlin.Unit>? placeholder, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? prefix, optional kotlin.jvm.functions.Function0<kotlin.Unit>? suffix, optional kotlin.jvm.functions.Function0<kotlin.Unit>? supportingText, optional boolean isError, optional androidx.compose.ui.text.input.VisualTransformation visualTransformation, optional androidx.compose.foundation.text.KeyboardOptions keyboardOptions, optional androidx.compose.foundation.text.KeyboardActions keyboardActions, optional boolean singleLine, optional int maxLines, optional int minLines, optional androidx.compose.foundation.interaction.MutableInteractionSource? interactionSource, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.TextFieldColors colors);
     method @Deprecated @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void OutlinedTextField(String value, kotlin.jvm.functions.Function1<? super java.lang.String,kotlin.Unit> onValueChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional boolean readOnly, optional androidx.compose.ui.text.TextStyle textStyle, optional kotlin.jvm.functions.Function0<kotlin.Unit>? label, optional kotlin.jvm.functions.Function0<kotlin.Unit>? placeholder, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? supportingText, optional boolean isError, optional androidx.compose.ui.text.input.VisualTransformation visualTransformation, optional androidx.compose.foundation.text.KeyboardOptions keyboardOptions, optional androidx.compose.foundation.text.KeyboardActions keyboardActions, optional boolean singleLine, optional int maxLines, optional int minLines, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.TextFieldColors colors);
-    method @androidx.compose.runtime.Composable public static void OutlinedTextField(String value, kotlin.jvm.functions.Function1<? super java.lang.String,kotlin.Unit> onValueChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional boolean readOnly, optional androidx.compose.ui.text.TextStyle textStyle, optional kotlin.jvm.functions.Function0<kotlin.Unit>? label, optional kotlin.jvm.functions.Function0<kotlin.Unit>? placeholder, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? prefix, optional kotlin.jvm.functions.Function0<kotlin.Unit>? suffix, optional kotlin.jvm.functions.Function0<kotlin.Unit>? supportingText, optional boolean isError, optional androidx.compose.ui.text.input.VisualTransformation visualTransformation, optional androidx.compose.foundation.text.KeyboardOptions keyboardOptions, optional androidx.compose.foundation.text.KeyboardActions keyboardActions, optional boolean singleLine, optional int maxLines, optional int minLines, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.TextFieldColors colors);
+    method @androidx.compose.runtime.Composable public static void OutlinedTextField(String value, kotlin.jvm.functions.Function1<? super java.lang.String,kotlin.Unit> onValueChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional boolean readOnly, optional androidx.compose.ui.text.TextStyle textStyle, optional kotlin.jvm.functions.Function0<kotlin.Unit>? label, optional kotlin.jvm.functions.Function0<kotlin.Unit>? placeholder, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? prefix, optional kotlin.jvm.functions.Function0<kotlin.Unit>? suffix, optional kotlin.jvm.functions.Function0<kotlin.Unit>? supportingText, optional boolean isError, optional androidx.compose.ui.text.input.VisualTransformation visualTransformation, optional androidx.compose.foundation.text.KeyboardOptions keyboardOptions, optional androidx.compose.foundation.text.KeyboardActions keyboardActions, optional boolean singleLine, optional int maxLines, optional int minLines, optional androidx.compose.foundation.interaction.MutableInteractionSource? interactionSource, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.TextFieldColors colors);
   }
 
   public final class ProgressIndicatorDefaults {
@@ -1193,7 +1202,7 @@
   }
 
   public final class RadioButtonKt {
-    method @androidx.compose.runtime.Composable public static void RadioButton(boolean selected, kotlin.jvm.functions.Function0<kotlin.Unit>? onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.material3.RadioButtonColors colors, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource);
+    method @androidx.compose.runtime.Composable public static void RadioButton(boolean selected, kotlin.jvm.functions.Function0<kotlin.Unit>? onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.material3.RadioButtonColors colors, optional androidx.compose.foundation.interaction.MutableInteractionSource? interactionSource);
   }
 
   @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Stable public final class RangeSliderState {
@@ -1296,8 +1305,8 @@
   }
 
   public final class SearchBar_androidKt {
-    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void DockedSearchBar(String query, kotlin.jvm.functions.Function1<? super java.lang.String,kotlin.Unit> onQueryChange, kotlin.jvm.functions.Function1<? super java.lang.String,kotlin.Unit> onSearch, boolean active, kotlin.jvm.functions.Function1<? super java.lang.Boolean,kotlin.Unit> onActiveChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.jvm.functions.Function0<kotlin.Unit>? placeholder, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.SearchBarColors colors, optional float tonalElevation, optional float shadowElevation, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> content);
-    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void SearchBar(String query, kotlin.jvm.functions.Function1<? super java.lang.String,kotlin.Unit> onQueryChange, kotlin.jvm.functions.Function1<? super java.lang.String,kotlin.Unit> onSearch, boolean active, kotlin.jvm.functions.Function1<? super java.lang.Boolean,kotlin.Unit> onActiveChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.jvm.functions.Function0<kotlin.Unit>? placeholder, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.SearchBarColors colors, optional float tonalElevation, optional float shadowElevation, optional androidx.compose.foundation.layout.WindowInsets windowInsets, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> content);
+    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void DockedSearchBar(String query, kotlin.jvm.functions.Function1<? super java.lang.String,kotlin.Unit> onQueryChange, kotlin.jvm.functions.Function1<? super java.lang.String,kotlin.Unit> onSearch, boolean active, kotlin.jvm.functions.Function1<? super java.lang.Boolean,kotlin.Unit> onActiveChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.jvm.functions.Function0<kotlin.Unit>? placeholder, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.SearchBarColors colors, optional float tonalElevation, optional float shadowElevation, optional androidx.compose.foundation.interaction.MutableInteractionSource? interactionSource, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> content);
+    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void SearchBar(String query, kotlin.jvm.functions.Function1<? super java.lang.String,kotlin.Unit> onQueryChange, kotlin.jvm.functions.Function1<? super java.lang.String,kotlin.Unit> onSearch, boolean active, kotlin.jvm.functions.Function1<? super java.lang.Boolean,kotlin.Unit> onActiveChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.jvm.functions.Function0<kotlin.Unit>? placeholder, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.SearchBarColors colors, optional float tonalElevation, optional float shadowElevation, optional androidx.compose.foundation.layout.WindowInsets windowInsets, optional androidx.compose.foundation.interaction.MutableInteractionSource? interactionSource, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> content);
   }
 
   @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Immutable public final class SegmentedButtonColors {
@@ -1347,8 +1356,8 @@
 
   public final class SegmentedButtonKt {
     method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void MultiChoiceSegmentedButtonRow(optional androidx.compose.ui.Modifier modifier, optional float space, kotlin.jvm.functions.Function1<? super androidx.compose.material3.MultiChoiceSegmentedButtonRowScope,kotlin.Unit> content);
-    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void SegmentedButton(androidx.compose.material3.MultiChoiceSegmentedButtonRowScope, boolean checked, kotlin.jvm.functions.Function1<? super java.lang.Boolean,kotlin.Unit> onCheckedChange, androidx.compose.ui.graphics.Shape shape, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.material3.SegmentedButtonColors colors, optional androidx.compose.foundation.BorderStroke border, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional kotlin.jvm.functions.Function0<kotlin.Unit> icon, kotlin.jvm.functions.Function0<kotlin.Unit> label);
-    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void SegmentedButton(androidx.compose.material3.SingleChoiceSegmentedButtonRowScope, boolean selected, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, androidx.compose.ui.graphics.Shape shape, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.material3.SegmentedButtonColors colors, optional androidx.compose.foundation.BorderStroke border, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional kotlin.jvm.functions.Function0<kotlin.Unit> icon, kotlin.jvm.functions.Function0<kotlin.Unit> label);
+    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void SegmentedButton(androidx.compose.material3.MultiChoiceSegmentedButtonRowScope, boolean checked, kotlin.jvm.functions.Function1<? super java.lang.Boolean,kotlin.Unit> onCheckedChange, androidx.compose.ui.graphics.Shape shape, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.material3.SegmentedButtonColors colors, optional androidx.compose.foundation.BorderStroke border, optional androidx.compose.foundation.interaction.MutableInteractionSource? interactionSource, optional kotlin.jvm.functions.Function0<kotlin.Unit> icon, kotlin.jvm.functions.Function0<kotlin.Unit> label);
+    method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void SegmentedButton(androidx.compose.material3.SingleChoiceSegmentedButtonRowScope, boolean selected, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, androidx.compose.ui.graphics.Shape shape, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.material3.SegmentedButtonColors colors, optional androidx.compose.foundation.BorderStroke border, optional androidx.compose.foundation.interaction.MutableInteractionSource? interactionSource, optional kotlin.jvm.functions.Function0<kotlin.Unit> icon, kotlin.jvm.functions.Function0<kotlin.Unit> label);
     method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void SingleChoiceSegmentedButtonRow(optional androidx.compose.ui.Modifier modifier, optional float space, kotlin.jvm.functions.Function1<? super androidx.compose.material3.SingleChoiceSegmentedButtonRowScope,kotlin.Unit> content);
   }
 
@@ -1597,9 +1606,9 @@
 
   public final class SurfaceKt {
     method @androidx.compose.runtime.Composable @androidx.compose.runtime.NonRestartableComposable public static void Surface(optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.graphics.Shape shape, optional long color, optional long contentColor, optional float tonalElevation, optional float shadowElevation, optional androidx.compose.foundation.BorderStroke? border, kotlin.jvm.functions.Function0<kotlin.Unit> content);
-    method @androidx.compose.runtime.Composable @androidx.compose.runtime.NonRestartableComposable public static void Surface(boolean selected, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional long color, optional long contentColor, optional float tonalElevation, optional float shadowElevation, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function0<kotlin.Unit> content);
-    method @androidx.compose.runtime.Composable @androidx.compose.runtime.NonRestartableComposable public static void Surface(boolean checked, kotlin.jvm.functions.Function1<? super java.lang.Boolean,kotlin.Unit> onCheckedChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional long color, optional long contentColor, optional float tonalElevation, optional float shadowElevation, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function0<kotlin.Unit> content);
-    method @androidx.compose.runtime.Composable @androidx.compose.runtime.NonRestartableComposable public static void Surface(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional long color, optional long contentColor, optional float tonalElevation, optional float shadowElevation, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable @androidx.compose.runtime.NonRestartableComposable public static void Surface(boolean selected, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional long color, optional long contentColor, optional float tonalElevation, optional float shadowElevation, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.interaction.MutableInteractionSource? interactionSource, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable @androidx.compose.runtime.NonRestartableComposable public static void Surface(boolean checked, kotlin.jvm.functions.Function1<? super java.lang.Boolean,kotlin.Unit> onCheckedChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional long color, optional long contentColor, optional float tonalElevation, optional float shadowElevation, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.interaction.MutableInteractionSource? interactionSource, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable @androidx.compose.runtime.NonRestartableComposable public static void Surface(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional long color, optional long contentColor, optional float tonalElevation, optional float shadowElevation, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.interaction.MutableInteractionSource? interactionSource, kotlin.jvm.functions.Function0<kotlin.Unit> content);
     method public static androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.unit.Dp> getLocalAbsoluteTonalElevation();
     property public static final androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.unit.Dp> LocalAbsoluteTonalElevation;
   }
@@ -1692,7 +1701,7 @@
   }
 
   public final class SwitchKt {
-    method @androidx.compose.runtime.Composable public static void Switch(boolean checked, kotlin.jvm.functions.Function1<? super java.lang.Boolean,kotlin.Unit>? onCheckedChange, optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function0<kotlin.Unit>? thumbContent, optional boolean enabled, optional androidx.compose.material3.SwitchColors colors, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource);
+    method @androidx.compose.runtime.Composable public static void Switch(boolean checked, kotlin.jvm.functions.Function1<? super java.lang.Boolean,kotlin.Unit>? onCheckedChange, optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function0<kotlin.Unit>? thumbContent, optional boolean enabled, optional androidx.compose.material3.SwitchColors colors, optional androidx.compose.foundation.interaction.MutableInteractionSource? interactionSource);
   }
 
   @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api public interface TabIndicatorScope {
@@ -1701,9 +1710,9 @@
   }
 
   public final class TabKt {
-    method @androidx.compose.runtime.Composable public static void LeadingIconTab(boolean selected, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, kotlin.jvm.functions.Function0<kotlin.Unit> text, kotlin.jvm.functions.Function0<kotlin.Unit> icon, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional long selectedContentColor, optional long unselectedContentColor, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource);
-    method @androidx.compose.runtime.Composable public static void Tab(boolean selected, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.jvm.functions.Function0<kotlin.Unit>? text, optional kotlin.jvm.functions.Function0<kotlin.Unit>? icon, optional long selectedContentColor, optional long unselectedContentColor, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource);
-    method @androidx.compose.runtime.Composable public static void Tab(boolean selected, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional long selectedContentColor, optional long unselectedContentColor, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void LeadingIconTab(boolean selected, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, kotlin.jvm.functions.Function0<kotlin.Unit> text, kotlin.jvm.functions.Function0<kotlin.Unit> icon, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional long selectedContentColor, optional long unselectedContentColor, optional androidx.compose.foundation.interaction.MutableInteractionSource? interactionSource);
+    method @androidx.compose.runtime.Composable public static void Tab(boolean selected, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.jvm.functions.Function0<kotlin.Unit>? text, optional kotlin.jvm.functions.Function0<kotlin.Unit>? icon, optional long selectedContentColor, optional long unselectedContentColor, optional androidx.compose.foundation.interaction.MutableInteractionSource? interactionSource);
+    method @androidx.compose.runtime.Composable public static void Tab(boolean selected, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional long selectedContentColor, optional long unselectedContentColor, optional androidx.compose.foundation.interaction.MutableInteractionSource? interactionSource, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> content);
   }
 
   @androidx.compose.runtime.Immutable public final class TabPosition {
@@ -1883,9 +1892,9 @@
 
   public final class TextFieldKt {
     method @Deprecated @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void TextField(androidx.compose.ui.text.input.TextFieldValue value, kotlin.jvm.functions.Function1<? super androidx.compose.ui.text.input.TextFieldValue,kotlin.Unit> onValueChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional boolean readOnly, optional androidx.compose.ui.text.TextStyle textStyle, optional kotlin.jvm.functions.Function0<kotlin.Unit>? label, optional kotlin.jvm.functions.Function0<kotlin.Unit>? placeholder, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? supportingText, optional boolean isError, optional androidx.compose.ui.text.input.VisualTransformation visualTransformation, optional androidx.compose.foundation.text.KeyboardOptions keyboardOptions, optional androidx.compose.foundation.text.KeyboardActions keyboardActions, optional boolean singleLine, optional int maxLines, optional int minLines, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.TextFieldColors colors);
-    method @androidx.compose.runtime.Composable public static void TextField(androidx.compose.ui.text.input.TextFieldValue value, kotlin.jvm.functions.Function1<? super androidx.compose.ui.text.input.TextFieldValue,kotlin.Unit> onValueChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional boolean readOnly, optional androidx.compose.ui.text.TextStyle textStyle, optional kotlin.jvm.functions.Function0<kotlin.Unit>? label, optional kotlin.jvm.functions.Function0<kotlin.Unit>? placeholder, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? prefix, optional kotlin.jvm.functions.Function0<kotlin.Unit>? suffix, optional kotlin.jvm.functions.Function0<kotlin.Unit>? supportingText, optional boolean isError, optional androidx.compose.ui.text.input.VisualTransformation visualTransformation, optional androidx.compose.foundation.text.KeyboardOptions keyboardOptions, optional androidx.compose.foundation.text.KeyboardActions keyboardActions, optional boolean singleLine, optional int maxLines, optional int minLines, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.TextFieldColors colors);
+    method @androidx.compose.runtime.Composable public static void TextField(androidx.compose.ui.text.input.TextFieldValue value, kotlin.jvm.functions.Function1<? super androidx.compose.ui.text.input.TextFieldValue,kotlin.Unit> onValueChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional boolean readOnly, optional androidx.compose.ui.text.TextStyle textStyle, optional kotlin.jvm.functions.Function0<kotlin.Unit>? label, optional kotlin.jvm.functions.Function0<kotlin.Unit>? placeholder, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? prefix, optional kotlin.jvm.functions.Function0<kotlin.Unit>? suffix, optional kotlin.jvm.functions.Function0<kotlin.Unit>? supportingText, optional boolean isError, optional androidx.compose.ui.text.input.VisualTransformation visualTransformation, optional androidx.compose.foundation.text.KeyboardOptions keyboardOptions, optional androidx.compose.foundation.text.KeyboardActions keyboardActions, optional boolean singleLine, optional int maxLines, optional int minLines, optional androidx.compose.foundation.interaction.MutableInteractionSource? interactionSource, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.TextFieldColors colors);
     method @Deprecated @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void TextField(String value, kotlin.jvm.functions.Function1<? super java.lang.String,kotlin.Unit> onValueChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional boolean readOnly, optional androidx.compose.ui.text.TextStyle textStyle, optional kotlin.jvm.functions.Function0<kotlin.Unit>? label, optional kotlin.jvm.functions.Function0<kotlin.Unit>? placeholder, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? supportingText, optional boolean isError, optional androidx.compose.ui.text.input.VisualTransformation visualTransformation, optional androidx.compose.foundation.text.KeyboardOptions keyboardOptions, optional androidx.compose.foundation.text.KeyboardActions keyboardActions, optional boolean singleLine, optional int maxLines, optional int minLines, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.TextFieldColors colors);
-    method @androidx.compose.runtime.Composable public static void TextField(String value, kotlin.jvm.functions.Function1<? super java.lang.String,kotlin.Unit> onValueChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional boolean readOnly, optional androidx.compose.ui.text.TextStyle textStyle, optional kotlin.jvm.functions.Function0<kotlin.Unit>? label, optional kotlin.jvm.functions.Function0<kotlin.Unit>? placeholder, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? prefix, optional kotlin.jvm.functions.Function0<kotlin.Unit>? suffix, optional kotlin.jvm.functions.Function0<kotlin.Unit>? supportingText, optional boolean isError, optional androidx.compose.ui.text.input.VisualTransformation visualTransformation, optional androidx.compose.foundation.text.KeyboardOptions keyboardOptions, optional androidx.compose.foundation.text.KeyboardActions keyboardActions, optional boolean singleLine, optional int maxLines, optional int minLines, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.TextFieldColors colors);
+    method @androidx.compose.runtime.Composable public static void TextField(String value, kotlin.jvm.functions.Function1<? super java.lang.String,kotlin.Unit> onValueChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional boolean readOnly, optional androidx.compose.ui.text.TextStyle textStyle, optional kotlin.jvm.functions.Function0<kotlin.Unit>? label, optional kotlin.jvm.functions.Function0<kotlin.Unit>? placeholder, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? prefix, optional kotlin.jvm.functions.Function0<kotlin.Unit>? suffix, optional kotlin.jvm.functions.Function0<kotlin.Unit>? supportingText, optional boolean isError, optional androidx.compose.ui.text.input.VisualTransformation visualTransformation, optional androidx.compose.foundation.text.KeyboardOptions keyboardOptions, optional androidx.compose.foundation.text.KeyboardActions keyboardActions, optional boolean singleLine, optional int maxLines, optional int minLines, optional androidx.compose.foundation.interaction.MutableInteractionSource? interactionSource, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.TextFieldColors colors);
   }
 
   public final class TextKt {
diff --git a/compose/material3/material3/samples/src/main/java/androidx/compose/material3/samples/TabSamples.kt b/compose/material3/material3/samples/src/main/java/androidx/compose/material3/samples/TabSamples.kt
index 50aa382..a0968c5 100644
--- a/compose/material3/material3/samples/src/main/java/androidx/compose/material3/samples/TabSamples.kt
+++ b/compose/material3/material3/samples/src/main/java/androidx/compose/material3/samples/TabSamples.kt
@@ -74,6 +74,7 @@
 import androidx.compose.ui.tooling.preview.Preview
 import androidx.compose.ui.unit.Constraints
 import androidx.compose.ui.unit.Dp
+import androidx.compose.ui.unit.IntOffset
 import androidx.compose.ui.unit.dp
 import kotlinx.coroutines.launch
 
@@ -674,7 +675,7 @@
             .fillMaxSize()
             .wrapContentSize(align = Alignment.BottomStart)
             // Apply an offset from the start to correctly position the indicator around the tab
-            .offset(x = indicatorStart)
+            .offset { IntOffset(x = indicatorStart.roundToPx(), y = 0) }
             // Make the width of the indicator follow the animated width as we move between tabs
             .width(indicatorEnd - indicatorStart)
     )
diff --git a/compose/material3/material3/src/androidInstrumentedTest/kotlin/androidx/compose/material3/BottomSheetScaffoldTest.kt b/compose/material3/material3/src/androidInstrumentedTest/kotlin/androidx/compose/material3/BottomSheetScaffoldTest.kt
index abc29a9..a5390d8 100644
--- a/compose/material3/material3/src/androidInstrumentedTest/kotlin/androidx/compose/material3/BottomSheetScaffoldTest.kt
+++ b/compose/material3/material3/src/androidInstrumentedTest/kotlin/androidx/compose/material3/BottomSheetScaffoldTest.kt
@@ -351,7 +351,7 @@
     }
 
     @Test
-    fun backdropScaffold_revealAndConceal_manually(): Unit = runBlocking(AutoTestFrameClock()) {
+    fun bottomSheetScaffold_revealAndConceal_manually(): Unit = runBlocking(AutoTestFrameClock()) {
         lateinit var bottomSheetState: SheetState
         rule.setContent {
             bottomSheetState = rememberStandardBottomSheetState(
diff --git a/compose/material3/material3/src/androidInstrumentedTest/kotlin/androidx/compose/material3/MenuScreenshotTest.kt b/compose/material3/material3/src/androidInstrumentedTest/kotlin/androidx/compose/material3/MenuScreenshotTest.kt
index 12a3b39..6b92ad6 100644
--- a/compose/material3/material3/src/androidInstrumentedTest/kotlin/androidx/compose/material3/MenuScreenshotTest.kt
+++ b/compose/material3/material3/src/androidInstrumentedTest/kotlin/androidx/compose/material3/MenuScreenshotTest.kt
@@ -18,9 +18,11 @@
 
 import android.os.Build
 import androidx.compose.animation.core.MutableTransitionState
+import androidx.compose.foundation.BorderStroke
 import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.padding
 import androidx.compose.foundation.rememberScrollState
+import androidx.compose.foundation.shape.CutCornerShape
 import androidx.compose.material.icons.Icons
 import androidx.compose.material.icons.outlined.Edit
 import androidx.compose.material.icons.outlined.Email
@@ -32,12 +34,15 @@
 import androidx.compose.testutils.assertAgainstGolden
 import androidx.compose.ui.Alignment
 import androidx.compose.ui.Modifier
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.graphics.Shape
 import androidx.compose.ui.graphics.TransformOrigin
 import androidx.compose.ui.platform.testTag
 import androidx.compose.ui.test.captureToImage
 import androidx.compose.ui.test.junit4.createComposeRule
 import androidx.compose.ui.test.onNodeWithTag
 import androidx.compose.ui.text.style.TextAlign
+import androidx.compose.ui.unit.Dp
 import androidx.compose.ui.unit.dp
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.MediumTest
@@ -99,16 +104,44 @@
         assertAgainstGolden(goldenIdentifier = "dropdownMenu_disabled_darkTheme")
     }
 
+    @Test
+    fun dropdownMenu_customAppearance() {
+        composeTestRule.setMaterialContent(lightColorScheme()) {
+            TestMenu(
+                enabledItems = true,
+                shape = CutCornerShape(12.dp),
+                containerColor = Color.Yellow,
+                tonalElevation = 0.dp,
+                shadowElevation = 0.dp,
+                border = BorderStroke(1.dp, Color.Black),
+            )
+        }
+        assertAgainstGolden(goldenIdentifier = "dropdownMenu_customAppearance")
+    }
+
     @Composable
-    private fun TestMenu(enabledItems: Boolean) {
+    private fun TestMenu(
+        enabledItems: Boolean,
+        shape: Shape = MenuDefaults.shape,
+        containerColor: Color = MenuDefaults.containerColor,
+        tonalElevation: Dp = MenuDefaults.TonalElevation,
+        shadowElevation: Dp = MenuDefaults.ShadowElevation,
+        border: BorderStroke? = null,
+    ) {
         Box(
             Modifier
                 .testTag(testTag)
                 .padding(20.dp), contentAlignment = Alignment.Center) {
             DropdownMenuContent(
+                modifier = Modifier,
                 expandedState = MutableTransitionState(initialState = true),
                 transformOriginState = remember { mutableStateOf(TransformOrigin.Center) },
-                scrollState = rememberScrollState()
+                scrollState = rememberScrollState(),
+                shape = shape,
+                containerColor = containerColor,
+                tonalElevation = tonalElevation,
+                shadowElevation = shadowElevation,
+                border = border,
             ) {
                 DropdownMenuItem(
                     text = { Text("Edit") },
diff --git a/compose/material3/material3/src/androidInstrumentedTest/kotlin/androidx/compose/material3/carousel/CarouselTest.kt b/compose/material3/material3/src/androidInstrumentedTest/kotlin/androidx/compose/material3/carousel/CarouselTest.kt
new file mode 100644
index 0000000..58c41be
--- /dev/null
+++ b/compose/material3/material3/src/androidInstrumentedTest/kotlin/androidx/compose/material3/carousel/CarouselTest.kt
@@ -0,0 +1,146 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.compose.material3.carousel
+
+import androidx.compose.foundation.ExperimentalFoundationApi
+import androidx.compose.foundation.background
+import androidx.compose.foundation.focusable
+import androidx.compose.foundation.gestures.Orientation
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.text.BasicText
+import androidx.compose.material3.ExperimentalMaterial3Api
+import androidx.compose.material3.lightColorScheme
+import androidx.compose.material3.setMaterialContent
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.platform.testTag
+import androidx.compose.ui.test.junit4.createComposeRule
+import androidx.compose.ui.test.onNodeWithTag
+import androidx.compose.ui.test.performTouchInput
+import androidx.compose.ui.test.swipeWithVelocity
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.MediumTest
+import com.google.common.truth.Truth.assertThat
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@MediumTest
+@RunWith(AndroidJUnit4::class)
+@OptIn(ExperimentalMaterial3Api::class, ExperimentalFoundationApi::class)
+class CarouselTest {
+
+    private lateinit var carouselState: CarouselState
+
+    @get:Rule
+    val rule = createComposeRule()
+
+    @Test
+    fun carousel_horizontalScrollUpdatesState() {
+        // Arrange
+        createCarousel(orientation = Orientation.Horizontal)
+        assertThat(carouselState.pagerState.currentPage).isEqualTo(0)
+
+        // Act
+        rule.onNodeWithTag(CarouselTestTag)
+            .performTouchInput { swipeWithVelocity(centerRight, centerLeft, 1000f) }
+
+        // Assert
+        rule.runOnIdle {
+            assertThat(carouselState.pagerState.currentPage).isNotEqualTo(0)
+        }
+    }
+
+    @Test
+    fun carousel_verticalScrollUpdatesState() {
+        // Arrange
+        createCarousel(orientation = Orientation.Vertical)
+        assertThat(carouselState.pagerState.currentPage).isEqualTo(0)
+
+        // Act
+        rule.onNodeWithTag(CarouselTestTag)
+            .performTouchInput {
+                swipeWithVelocity(bottomCenter, topCenter, 1000f)
+            }
+
+        // Assert
+        rule.runOnIdle {
+            assertThat(carouselState.pagerState.currentPage).isNotEqualTo(0)
+        }
+    }
+
+    @Test
+    fun carousel_testInitialItem() {
+        // Arrange
+        createCarousel(initialItem = 5, orientation = Orientation.Horizontal)
+
+        // Assert
+        rule.runOnIdle {
+            assertThat(carouselState.pagerState.currentPage).isEqualTo(5)
+        }
+    }
+
+    @Composable
+    internal fun Item(index: Int) {
+        Box(
+            modifier = Modifier
+            .fillMaxSize()
+            .background(Color.Blue)
+            .testTag("$index")
+            .focusable(),
+            contentAlignment = Alignment.Center
+        ) {
+            BasicText(text = index.toString())
+        }
+    }
+
+    private fun createCarousel(
+        initialItem: Int = 0,
+        itemCount: () -> Int = { DefaultItemCount },
+        modifier: Modifier = Modifier,
+        orientation: Orientation = Orientation.Horizontal,
+        content: @Composable CarouselScope.(item: Int) -> Unit = { Item(index = it) }
+    ) {
+        rule.setMaterialContent(lightColorScheme()) {
+            val state = rememberCarouselState(
+                initialItem = initialItem,
+                itemCount = itemCount,
+            ).also {
+                carouselState = it
+            }
+            if (orientation == Orientation.Horizontal) {
+                HorizontalCarousel(
+                    state = state,
+                    modifier = modifier.testTag(CarouselTestTag),
+                    content = content,
+                )
+            } else {
+                VerticalCarousel(
+                    state = state,
+                    modifier = modifier.testTag(CarouselTestTag),
+                    content = content,
+                )
+            }
+        }
+    }
+}
+
+internal const val DefaultItemCount = 10
+internal const val CarouselTestTag = "carousel"
diff --git a/compose/material3/material3/src/androidMain/kotlin/androidx/compose/material3/AndroidMenu.android.kt b/compose/material3/material3/src/androidMain/kotlin/androidx/compose/material3/AndroidMenu.android.kt
index 3e102ff..addb8b6 100644
--- a/compose/material3/material3/src/androidMain/kotlin/androidx/compose/material3/AndroidMenu.android.kt
+++ b/compose/material3/material3/src/androidMain/kotlin/androidx/compose/material3/AndroidMenu.android.kt
@@ -17,6 +17,7 @@
 package androidx.compose.material3
 
 import androidx.compose.animation.core.MutableTransitionState
+import androidx.compose.foundation.BorderStroke
 import androidx.compose.foundation.ScrollState
 import androidx.compose.foundation.interaction.Interaction
 import androidx.compose.foundation.interaction.MutableInteractionSource
@@ -27,8 +28,11 @@
 import androidx.compose.runtime.mutableStateOf
 import androidx.compose.runtime.remember
 import androidx.compose.ui.Modifier
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.graphics.Shape
 import androidx.compose.ui.graphics.TransformOrigin
 import androidx.compose.ui.platform.LocalDensity
+import androidx.compose.ui.unit.Dp
 import androidx.compose.ui.unit.DpOffset
 import androidx.compose.ui.unit.dp
 import androidx.compose.ui.window.Popup
@@ -78,6 +82,13 @@
  * [LayoutDirection], so the offset's x position will be added in LTR and subtracted in RTL.
  * @param scrollState a [ScrollState] to used by the menu's content for items vertical scrolling
  * @param properties [PopupProperties] for further customization of this popup's behavior
+ * @param shape the shape of the menu
+ * @param containerColor the container color of the menu
+ * @param tonalElevation when [containerColor] is [ColorScheme.surface], a translucent primary color
+ * overlay is applied on top of the container. A higher tonal elevation value will result in a
+ * darker color in light theme and lighter color in dark theme. See also: [Surface].
+ * @param shadowElevation the elevation for the shadow below the menu
+ * @param border the border to draw around the container of the menu. Pass `null` for no border.
  * @param content the content of this dropdown menu, typically a [DropdownMenuItem]
  */
 @Composable
@@ -88,6 +99,11 @@
     offset: DpOffset = DpOffset(0.dp, 0.dp),
     scrollState: ScrollState = rememberScrollState(),
     properties: PopupProperties = PopupProperties(focusable = true),
+    shape: Shape = MenuDefaults.shape,
+    containerColor: Color = MenuDefaults.containerColor,
+    tonalElevation: Dp = MenuDefaults.TonalElevation,
+    shadowElevation: Dp = MenuDefaults.ShadowElevation,
+    border: BorderStroke? = null,
     content: @Composable ColumnScope.() -> Unit
 ) {
     val expandedState = remember { MutableTransitionState(false) }
@@ -114,14 +130,63 @@
                 expandedState = expandedState,
                 transformOriginState = transformOriginState,
                 scrollState = scrollState,
+                shape = shape,
+                containerColor = containerColor,
+                tonalElevation = tonalElevation,
+                shadowElevation = shadowElevation,
+                border = border,
                 modifier = modifier,
-                content = content
+                content = content,
             )
         }
     }
 }
 
-@OptIn(ExperimentalMaterial3Api::class)
+@Deprecated(
+    level = DeprecationLevel.HIDDEN,
+    replaceWith = ReplaceWith(
+        expression = "DropdownMenu(\n" +
+            "    expanded = expanded,\n" +
+            "    onDismissRequest = onDismissRequest,\n" +
+            "    modifier = modifier,\n" +
+            "    offset = offset,\n" +
+            "    scrollState = scrollState,\n" +
+            "    properties = properties,\n" +
+            "    shape = MenuDefaults.shape,\n" +
+            "    containerColor = MenuDefaults.containerColor,\n" +
+            "    tonalElevation = MenuDefaults.TonalElevation,\n" +
+            "    shadowElevation = MenuDefaults.ShadowElevation,\n" +
+            "    border = null,\n" +
+            "    content = content,\n" +
+            ")",
+    ),
+    message = "Maintained for binary compatibility. Use overload with parameters for shape, " +
+        "color, elevation, and border."
+)
+@Composable
+fun DropdownMenu(
+    expanded: Boolean,
+    onDismissRequest: () -> Unit,
+    modifier: Modifier = Modifier,
+    offset: DpOffset = DpOffset(0.dp, 0.dp),
+    scrollState: ScrollState = rememberScrollState(),
+    properties: PopupProperties = PopupProperties(focusable = true),
+    content: @Composable ColumnScope.() -> Unit
+) = DropdownMenu(
+    expanded = expanded,
+    onDismissRequest = onDismissRequest,
+    modifier = modifier,
+    offset = offset,
+    scrollState = scrollState,
+    properties = properties,
+    shape = MenuDefaults.shape,
+    containerColor = MenuDefaults.containerColor,
+    tonalElevation = MenuDefaults.TonalElevation,
+    shadowElevation = MenuDefaults.ShadowElevation,
+    border = null,
+    content = content,
+)
+
 @Deprecated(
     level = DeprecationLevel.HIDDEN,
     replaceWith = ReplaceWith(
@@ -172,9 +237,10 @@
  * @param colors [MenuItemColors] that will be used to resolve the colors used for this menu item in
  * different states. See [MenuDefaults.itemColors].
  * @param contentPadding the padding applied to the content of this menu item
- * @param interactionSource the [MutableInteractionSource] representing the stream of [Interaction]s
- * for this menu item. You can create and pass in your own `remember`ed instance to observe
- * [Interaction]s and customize the appearance / behavior of this menu item in different states.
+ * @param interactionSource an optional hoisted [MutableInteractionSource] for observing and
+ * emitting [Interaction]s for this menu item. You can use this to change the menu item's appearance
+ * or preview the menu item in different states. Note that if `null` is provided, interactions will
+ * still happen internally.
  */
 @Composable
 fun DropdownMenuItem(
@@ -186,7 +252,7 @@
     enabled: Boolean = true,
     colors: MenuItemColors = MenuDefaults.itemColors(),
     contentPadding: PaddingValues = MenuDefaults.DropdownMenuItemContentPadding,
-    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
+    interactionSource: MutableInteractionSource? = null,
 ) {
     DropdownMenuItemContent(
         text = text,
diff --git a/compose/material3/material3/src/androidMain/kotlin/androidx/compose/material3/ExposedDropdownMenu.android.kt b/compose/material3/material3/src/androidMain/kotlin/androidx/compose/material3/ExposedDropdownMenu.android.kt
index 6f8a271..cb83585 100644
--- a/compose/material3/material3/src/androidMain/kotlin/androidx/compose/material3/ExposedDropdownMenu.android.kt
+++ b/compose/material3/material3/src/androidMain/kotlin/androidx/compose/material3/ExposedDropdownMenu.android.kt
@@ -299,8 +299,13 @@
                     expandedState = expandedState,
                     transformOriginState = transformOriginState,
                     scrollState = scrollState,
+                    shape = MenuDefaults.shape,
+                    containerColor = MenuDefaults.containerColor,
+                    tonalElevation = MenuDefaults.TonalElevation,
+                    shadowElevation = MenuDefaults.ShadowElevation,
+                    border = null,
                     modifier = modifier.exposedDropdownSize(),
-                    content = content
+                    content = content,
                 )
             }
         }
diff --git a/compose/material3/material3/src/androidMain/kotlin/androidx/compose/material3/SearchBar.android.kt b/compose/material3/material3/src/androidMain/kotlin/androidx/compose/material3/SearchBar.android.kt
index c4afd00..f613463 100644
--- a/compose/material3/material3/src/androidMain/kotlin/androidx/compose/material3/SearchBar.android.kt
+++ b/compose/material3/material3/src/androidMain/kotlin/androidx/compose/material3/SearchBar.android.kt
@@ -150,9 +150,10 @@
  * [Surface].
  * @param shadowElevation the elevation for the shadow below the search bar
  * @param windowInsets the window insets that the search bar will respect
- * @param interactionSource the [MutableInteractionSource] representing the stream of [Interaction]s
- * for this search bar. You can create and pass in your own `remember`ed instance to observe
- * [Interaction]s and customize the appearance / behavior of this search bar in different states.
+ * @param interactionSource an optional hoisted [MutableInteractionSource] for observing and
+ * emitting [Interaction]s for this search bar. You can use this to change the search bar's
+ * appearance or preview the search bar in different states. Note that if `null` is provided,
+ * interactions will still happen internally.
  * @param content the content of this search bar that will be displayed below the input field
  */
 @ExperimentalMaterial3Api
@@ -173,9 +174,11 @@
     tonalElevation: Dp = SearchBarDefaults.TonalElevation,
     shadowElevation: Dp = SearchBarDefaults.ShadowElevation,
     windowInsets: WindowInsets = SearchBarDefaults.windowInsets,
-    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
+    interactionSource: MutableInteractionSource? = null,
     content: @Composable ColumnScope.() -> Unit,
 ) {
+    @Suppress("NAME_SHADOWING")
+    val interactionSource = interactionSource ?: remember { MutableInteractionSource() }
     val animationProgress: State<Float> = animateFloatAsState(
         targetValue = if (active) 1f else 0f,
         animationSpec = if (active) AnimationEnterFloatSpec else AnimationExitFloatSpec
@@ -338,9 +341,10 @@
  * value will result in a darker color in light theme and lighter color in dark theme. See also:
  * [Surface].
  * @param shadowElevation the elevation for the shadow below the search bar
- * @param interactionSource the [MutableInteractionSource] representing the stream of [Interaction]s
- * for this search bar. You can create and pass in your own `remember`ed instance to observe
- * [Interaction]s and customize the appearance / behavior of this search bar in different states.
+ * @param interactionSource an optional hoisted [MutableInteractionSource] for observing and
+ * emitting [Interaction]s for this search bar. You can use this to change the search bar's
+ * appearance or preview the search bar in different states. Note that if `null` is provided,
+ * interactions will still happen internally.
  * @param content the content of this search bar that will be displayed below the input field
  */
 @ExperimentalMaterial3Api
@@ -360,9 +364,11 @@
     colors: SearchBarColors = SearchBarDefaults.colors(),
     tonalElevation: Dp = SearchBarDefaults.TonalElevation,
     shadowElevation: Dp = SearchBarDefaults.ShadowElevation,
-    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
+    interactionSource: MutableInteractionSource? = null,
     content: @Composable ColumnScope.() -> Unit,
 ) {
+    @Suppress("NAME_SHADOWING")
+    val interactionSource = interactionSource ?: remember { MutableInteractionSource() }
     val focusManager = LocalFocusManager.current
 
     Surface(
@@ -441,8 +447,10 @@
     leadingIcon: @Composable (() -> Unit)? = null,
     trailingIcon: @Composable (() -> Unit)? = null,
     colors: TextFieldColors = SearchBarDefaults.inputFieldColors(),
-    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
+    interactionSource: MutableInteractionSource? = null,
 ) {
+    @Suppress("NAME_SHADOWING")
+    val interactionSource = interactionSource ?: remember { MutableInteractionSource() }
     val focusRequester = remember { FocusRequester() }
     val searchSemantics = getString(Strings.SearchBarSearch)
     val suggestionsAvailableSemantics = getString(Strings.SuggestionsAvailable)
diff --git a/compose/material3/material3/src/androidUnitTest/kotlin/androidx/compose/material3/carousel/ArrangementTest.kt b/compose/material3/material3/src/androidUnitTest/kotlin/androidx/compose/material3/carousel/ArrangementTest.kt
index fbdc98b..59d6971 100644
--- a/compose/material3/material3/src/androidUnitTest/kotlin/androidx/compose/material3/carousel/ArrangementTest.kt
+++ b/compose/material3/material3/src/androidUnitTest/kotlin/androidx/compose/material3/carousel/ArrangementTest.kt
@@ -16,7 +16,6 @@
 
 package androidx.compose.material3.carousel
 
-import androidx.annotation.FloatRange
 import com.google.common.truth.Truth.assertThat
 import kotlin.math.roundToInt
 import org.junit.Test
@@ -35,7 +34,8 @@
         val arrangement = Arrangement.findLowestCostArrangement(
             availableSpace = targetLargeSize + targetMediumSize + targetSmallSize,
             targetSmallSize = targetSmallSize,
-            smallSizeRange = FloatRange(40.0, 56.0),
+            minSmallSize = 40f,
+            maxSmallSize = 56f,
             smallCounts = intArrayOf(1),
             targetMediumSize = targetMediumSize,
             mediumCounts = intArrayOf(1),
@@ -55,7 +55,8 @@
         val arrangement = Arrangement.findLowestCostArrangement(
             availableSpace = targetLargeSize + targetMediumSize + targetSmallSize - 10f,
             targetSmallSize = targetSmallSize,
-            smallSizeRange = FloatRange(40.0, 56.0),
+            minSmallSize = 40f,
+            maxSmallSize = 56f,
             smallCounts = intArrayOf(1),
             targetMediumSize = targetMediumSize,
             mediumCounts = intArrayOf(1),
@@ -75,7 +76,8 @@
         val arrangement = Arrangement.findLowestCostArrangement(
             availableSpace = targetLargeSize + targetMediumSize + targetSmallSize + 10f,
             targetSmallSize = targetSmallSize,
-            smallSizeRange = FloatRange(40.0, 56.0),
+            minSmallSize = 40f,
+            maxSmallSize = 56f,
             smallCounts = intArrayOf(1),
             targetMediumSize = targetMediumSize,
             mediumCounts = intArrayOf(1),
@@ -98,7 +100,8 @@
                 targetMediumSize +
                 targetSmallSize - mediumAdjustment,
             targetSmallSize = targetSmallSize,
-            smallSizeRange = FloatRange(40.0, 56.0),
+            minSmallSize = 40f,
+            maxSmallSize = 56f,
             smallCounts = intArrayOf(1),
             targetMediumSize = targetMediumSize,
             mediumCounts = intArrayOf(1),
@@ -122,7 +125,8 @@
                 targetMediumSize +
                 targetSmallSize + mediumAdjustment,
             targetSmallSize = targetSmallSize,
-            smallSizeRange = FloatRange(40.0, 56.0),
+            minSmallSize = 40f,
+            maxSmallSize = 56f,
             smallCounts = intArrayOf(1),
             targetMediumSize = targetMediumSize,
             mediumCounts = intArrayOf(1),
@@ -147,7 +151,8 @@
                 (targetSmallSize * 2) +
                 (smallAdjustment * 2),
             targetSmallSize = targetSmallSize,
-            smallSizeRange = FloatRange(40.0, 56.0),
+            minSmallSize = 40f,
+            maxSmallSize = 56f,
             smallCounts = intArrayOf(2),
             targetMediumSize = targetMediumSize,
             mediumCounts = intArrayOf(1),
@@ -171,7 +176,8 @@
                 targetMediumSize +
                 (targetSmallSize * 2) - (smallAdjustment * 2),
             targetSmallSize = targetSmallSize,
-            smallSizeRange = FloatRange(40.0, 56.0),
+            minSmallSize = 40f,
+            maxSmallSize = 56f,
             smallCounts = intArrayOf(2),
             targetMediumSize = targetMediumSize,
             mediumCounts = intArrayOf(1),
@@ -195,7 +201,8 @@
                 (targetSmallSize * 2) +
                 (mediumAdjustment * 2),
             targetSmallSize = targetSmallSize,
-            smallSizeRange = FloatRange(40.0, 56.0),
+            minSmallSize = 40f,
+            maxSmallSize = 56f,
             smallCounts = intArrayOf(2),
             targetMediumSize = targetMediumSize,
             mediumCounts = intArrayOf(2),
@@ -219,7 +226,8 @@
                 (targetMediumSize * 2) +
                 (targetSmallSize * 2) - (mediumAdjustment * 2),
             targetSmallSize = targetSmallSize,
-            smallSizeRange = FloatRange(40.0, 56.0),
+            minSmallSize = 40f,
+            maxSmallSize = 56f,
             smallCounts = intArrayOf(2),
             targetMediumSize = targetMediumSize,
             mediumCounts = intArrayOf(2),
diff --git a/compose/material3/material3/src/androidUnitTest/kotlin/androidx/compose/material3/carousel/MultiBrowseStrategyTest.kt b/compose/material3/material3/src/androidUnitTest/kotlin/androidx/compose/material3/carousel/MultiBrowseStrategyTest.kt
new file mode 100644
index 0000000..8e0f286
--- /dev/null
+++ b/compose/material3/material3/src/androidUnitTest/kotlin/androidx/compose/material3/carousel/MultiBrowseStrategyTest.kt
@@ -0,0 +1,113 @@
+/*
+ * 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.compose.material3.carousel
+
+import androidx.compose.ui.unit.Density
+import androidx.compose.ui.unit.dp
+import com.google.common.truth.Truth.assertThat
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+
+@RunWith(JUnit4::class)
+class MultiBrowseStrategyTest {
+
+    private val Density = Density(1f)
+
+    @Test
+    fun testStrategy_doesntResizeLargeWhenEnoughRoom() {
+
+        val itemSize = 120.dp // minSmallItemSize = 40.dp * 3
+        val strategyProvider = MultiBrowseStrategyProvider(itemSize)
+        val strategy = strategyProvider.createStrategy(
+            density = Density,
+            carouselMainAxisSize = 500f,
+            itemSpacing = 0)
+
+        assertThat(strategy?.itemMainAxisSize).isEqualTo(with(Density) { itemSize.toPx() })
+    }
+
+    @Test
+    fun testStrategy_resizesItemLargerThanContainerToFit1Small() {
+        val itemSize = 200f
+        val strategyProvider = MultiBrowseStrategyProvider(with(Density) { itemSize.toDp() })
+        val strategy = strategyProvider.createStrategy(
+            density = Density,
+            carouselMainAxisSize = 100f,
+            itemSpacing = 0)
+
+        val minSmallItemSize: Float = with(Density) { StrategyDefaults.minSmallSize.toPx() }
+        val keylines = strategy?.getDefaultKeylines()
+
+        // If the item size given is larger than the container, the adjusted keyline list from
+        // the MultibrowseStrategy should be [xSmall-Large-Small-xSmall]
+        assertThat(strategy?.itemMainAxisSize).isAtMost(100f)
+        assertThat(keylines).hasSize(4)
+        assertThat(keylines?.get(0)?.unadjustedOffset).isLessThan(0f)
+        assertThat(keylines?.get(keylines.lastIndex)?.unadjustedOffset).isGreaterThan(100f)
+        assertThat(keylines?.get(1)?.isFocal).isTrue()
+        assertThat(keylines?.get(2)?.size).isEqualTo(minSmallItemSize)
+    }
+
+    @Test
+    fun testStrategy_hasNoSmallItemsIfNotEnoughRoom() {
+        val minSmallItemSize: Float = with(Density) { StrategyDefaults.minSmallSize.toPx() }
+        val strategyProvider = MultiBrowseStrategyProvider(with(Density) { 200f.toDp() })
+        val strategy = strategyProvider.createStrategy(
+            density = Density,
+            carouselMainAxisSize = minSmallItemSize,
+            itemSpacing = 0)
+        val keylines = strategy?.getDefaultKeylines()
+
+        assertThat(strategy?.itemMainAxisSize).isEqualTo(minSmallItemSize)
+        assertThat(keylines?.firstFocal == keylines?.firstNonAnchor)
+        assertThat(keylines?.lastFocal == keylines?.lastNonAnchor)
+    }
+
+    @Test
+    fun testStrategy_isNullIfAvailableSpaceIsZero() {
+        val strategyProvider = MultiBrowseStrategyProvider(with(Density) { 200f.toDp() })
+        val strategy = strategyProvider.createStrategy(
+            density = Density,
+            carouselMainAxisSize = 0F,
+            itemSpacing = 0)
+
+        assertThat(strategy).isNull()
+    }
+
+    @Test
+    fun testStrategy_adjustsMediumSizeToBeProportional() {
+        val maxSmallItemSize: Float = with(Density) { StrategyDefaults.maxSmallSize.toPx() }
+        val targetItemSize = 200f
+        val carouselSize = targetItemSize * 2 + maxSmallItemSize * 2
+        val strategyProvider = MultiBrowseStrategyProvider(with(Density) { targetItemSize.toDp() })
+        val strategy = strategyProvider.createStrategy(
+            density = Density,
+            carouselMainAxisSize = carouselSize,
+            itemSpacing = 0)
+        val keylines = strategy?.getDefaultKeylines()
+
+        // Assert that there's only one small item, and a medium item that has a size between
+        // the large and small items
+        // We expect a keyline list of [xSmall-Large-Large-Medium-Small-xSmall]
+        assertThat(keylines).hasSize(6)
+        assertThat(keylines?.get(1)?.isFocal).isTrue()
+        assertThat(keylines?.get(2)?.isFocal).isTrue()
+        assertThat(keylines?.get(3)?.size).isLessThan(keylines?.get(2)?.size)
+        assertThat(keylines?.get(4)?.size).isLessThan(keylines?.get(3)?.size)
+    }
+}
diff --git a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Button.kt b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Button.kt
index 3f19f2d..293b3d7 100644
--- a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Button.kt
+++ b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Button.kt
@@ -96,9 +96,10 @@
  * @param border the border to draw around the container of this button
  * @param contentPadding the spacing values to apply internally between the container and the
  * content
- * @param interactionSource the [MutableInteractionSource] representing the stream of [Interaction]s
- * for this button. You can create and pass in your own `remember`ed instance to observe
- * [Interaction]s and customize the appearance / behavior of this button in different states.
+ * @param interactionSource an optional hoisted [MutableInteractionSource] for observing and
+ * emitting [Interaction]s for this button. You can use this to change the button's appearance
+ * or preview the button in different states. Note that if `null` is provided, interactions will
+ * still happen internally.
  */
 @Composable
 fun Button(
@@ -110,9 +111,11 @@
     elevation: ButtonElevation? = ButtonDefaults.buttonElevation(),
     border: BorderStroke? = null,
     contentPadding: PaddingValues = ButtonDefaults.ContentPadding,
-    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
+    interactionSource: MutableInteractionSource? = null,
     content: @Composable RowScope.() -> Unit
 ) {
+    @Suppress("NAME_SHADOWING")
+    val interactionSource = interactionSource ?: remember { MutableInteractionSource() }
     val containerColor = colors.containerColor(enabled)
     val contentColor = colors.contentColor(enabled)
     val shadowElevation = elevation?.shadowElevation(enabled, interactionSource)?.value ?: 0.dp
@@ -187,9 +190,10 @@
  * @param border the border to draw around the container of this button
  * @param contentPadding the spacing values to apply internally between the container and the
  * content
- * @param interactionSource the [MutableInteractionSource] representing the stream of [Interaction]s
- * for this button. You can create and pass in your own `remember`ed instance to observe
- * [Interaction]s and customize the appearance / behavior of this button in different states.
+ * @param interactionSource an optional hoisted [MutableInteractionSource] for observing and
+ * emitting [Interaction]s for this button. You can use this to change the button's appearance
+ * or preview the button in different states. Note that if `null` is provided, interactions will
+ * still happen internally.
  */
 @Composable
 fun ElevatedButton(
@@ -201,7 +205,7 @@
     elevation: ButtonElevation? = ButtonDefaults.elevatedButtonElevation(),
     border: BorderStroke? = null,
     contentPadding: PaddingValues = ButtonDefaults.ContentPadding,
-    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
+    interactionSource: MutableInteractionSource? = null,
     content: @Composable RowScope.() -> Unit
 ) =
     Button(
@@ -257,9 +261,10 @@
  * @param border the border to draw around the container of this button
  * @param contentPadding the spacing values to apply internally between the container and the
  * content
- * @param interactionSource the [MutableInteractionSource] representing the stream of [Interaction]s
- * for this button. You can create and pass in your own `remember`ed instance to observe
- * [Interaction]s and customize the appearance / behavior of this button in different states.
+ * @param interactionSource an optional hoisted [MutableInteractionSource] for observing and
+ * emitting [Interaction]s for this button. You can use this to change the button's appearance
+ * or preview the button in different states. Note that if `null` is provided, interactions will
+ * still happen internally.
  */
 @Composable
 fun FilledTonalButton(
@@ -271,7 +276,7 @@
     elevation: ButtonElevation? = ButtonDefaults.filledTonalButtonElevation(),
     border: BorderStroke? = null,
     contentPadding: PaddingValues = ButtonDefaults.ContentPadding,
-    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
+    interactionSource: MutableInteractionSource? = null,
     content: @Composable RowScope.() -> Unit
 ) =
     Button(
@@ -326,9 +331,10 @@
  * @param border the border to draw around the container of this button. Pass `null` for no border.
  * @param contentPadding the spacing values to apply internally between the container and the
  * content
- * @param interactionSource the [MutableInteractionSource] representing the stream of [Interaction]s
- * for this button. You can create and pass in your own `remember`ed instance to observe
- * [Interaction]s and customize the appearance / behavior of this button in different states.
+ * @param interactionSource an optional hoisted [MutableInteractionSource] for observing and
+ * emitting [Interaction]s for this button. You can use this to change the button's appearance
+ * or preview the button in different states. Note that if `null` is provided, interactions will
+ * still happen internally.
  */
 @Composable
 fun OutlinedButton(
@@ -340,7 +346,7 @@
     elevation: ButtonElevation? = null,
     border: BorderStroke? = ButtonDefaults.outlinedButtonBorder,
     contentPadding: PaddingValues = ButtonDefaults.ContentPadding,
-    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
+    interactionSource: MutableInteractionSource? = null,
     content: @Composable RowScope.() -> Unit
 ) =
     Button(
@@ -397,9 +403,10 @@
  * @param border the border to draw around the container of this button
  * @param contentPadding the spacing values to apply internally between the container and the
  * content
- * @param interactionSource the [MutableInteractionSource] representing the stream of [Interaction]s
- * for this button. You can create and pass in your own `remember`ed instance to observe
- * [Interaction]s and customize the appearance / behavior of this button in different states.
+ * @param interactionSource an optional hoisted [MutableInteractionSource] for observing and
+ * emitting [Interaction]s for this button. You can use this to change the button's appearance
+ * or preview the button in different states. Note that if `null` is provided, interactions will
+ * still happen internally.
  */
 @Composable
 fun TextButton(
@@ -411,7 +418,7 @@
     elevation: ButtonElevation? = null,
     border: BorderStroke? = null,
     contentPadding: PaddingValues = ButtonDefaults.TextButtonContentPadding,
-    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
+    interactionSource: MutableInteractionSource? = null,
     content: @Composable RowScope.() -> Unit
 ) =
     Button(
diff --git a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Card.kt b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Card.kt
index c06fe8b..b5ffb09 100644
--- a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Card.kt
+++ b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Card.kt
@@ -123,10 +123,10 @@
  * [ColorScheme.surface], this controls the amount of primary color applied as an overlay. See also:
  * [Surface].
  * @param border the border to draw around the container of this card
- * @param interactionSource the [MutableInteractionSource] representing the stream of [Interaction]s
- * for this card. You can create and pass in your own `remember`ed instance to observe
- * [Interaction]s and customize the appearance / behavior of this card in different states.
- *
+ * @param interactionSource an optional hoisted [MutableInteractionSource] for observing and
+ * emitting [Interaction]s for this card. You can use this to change the card's appearance
+ * or preview the card in different states. Note that if `null` is provided, interactions will
+ * still happen internally.
  */
 @Composable
 fun Card(
@@ -137,9 +137,11 @@
     colors: CardColors = CardDefaults.cardColors(),
     elevation: CardElevation = CardDefaults.cardElevation(),
     border: BorderStroke? = null,
-    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
+    interactionSource: MutableInteractionSource? = null,
     content: @Composable ColumnScope.() -> Unit
 ) {
+    @Suppress("NAME_SHADOWING")
+    val interactionSource = interactionSource ?: remember { MutableInteractionSource() }
     Surface(
         onClick = onClick,
         modifier = modifier,
@@ -222,9 +224,10 @@
  * This controls the size of the shadow below the card. Additionally, when the container color is
  * [ColorScheme.surface], this controls the amount of primary color applied as an overlay. See also:
  * [Surface].
- * @param interactionSource the [MutableInteractionSource] representing the stream of [Interaction]s
- * for this card. You can create and pass in your own `remember`ed instance to observe
- * [Interaction]s and customize the appearance / behavior of this card in different states.
+ * @param interactionSource an optional hoisted [MutableInteractionSource] for observing and
+ * emitting [Interaction]s for this card. You can use this to change the card's appearance
+ * or preview the card in different states. Note that if `null` is provided, interactions will
+ * still happen internally.
  */
 @Composable
 fun ElevatedCard(
@@ -234,7 +237,7 @@
     shape: Shape = CardDefaults.elevatedShape,
     colors: CardColors = CardDefaults.elevatedCardColors(),
     elevation: CardElevation = CardDefaults.elevatedCardElevation(),
-    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
+    interactionSource: MutableInteractionSource? = null,
     content: @Composable ColumnScope.() -> Unit
 ) = Card(
     onClick = onClick,
@@ -317,9 +320,10 @@
  * [ColorScheme.surface], this controls the amount of primary color applied as an overlay. See also:
  * [Surface].
  * @param border the border to draw around the container of this card
- * @param interactionSource the [MutableInteractionSource] representing the stream of [Interaction]s
- * for this card. You can create and pass in your own `remember`ed instance to observe
- * [Interaction]s and customize the appearance / behavior of this card in different states.
+ * @param interactionSource an optional hoisted [MutableInteractionSource] for observing and
+ * emitting [Interaction]s for this card. You can use this to change the card's appearance
+ * or preview the card in different states. Note that if `null` is provided, interactions will
+ * still happen internally.
  */
 @Composable
 fun OutlinedCard(
@@ -330,7 +334,7 @@
     colors: CardColors = CardDefaults.outlinedCardColors(),
     elevation: CardElevation = CardDefaults.outlinedCardElevation(),
     border: BorderStroke = CardDefaults.outlinedCardBorder(enabled),
-    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
+    interactionSource: MutableInteractionSource? = null,
     content: @Composable ColumnScope.() -> Unit
 ) = Card(
     onClick = onClick,
diff --git a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Checkbox.kt b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Checkbox.kt
index 9683192..83508d6 100644
--- a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Checkbox.kt
+++ b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Checkbox.kt
@@ -80,9 +80,10 @@
  * services.
  * @param colors [CheckboxColors] that will be used to resolve the colors used for this checkbox in
  * different states. See [CheckboxDefaults.colors].
- * @param interactionSource the [MutableInteractionSource] representing the stream of [Interaction]s
- * for this checkbox. You can create and pass in your own `remember`ed instance to observe
- * [Interaction]s and customize the appearance / behavior of this checkbox in different states.
+ * @param interactionSource an optional hoisted [MutableInteractionSource] for observing and
+ * emitting [Interaction]s for this checkbox. You can use this to change the checkbox's appearance
+ * or preview the checkbox in different states. Note that if `null` is provided, interactions will
+ * still happen internally.
  */
 @Composable
 fun Checkbox(
@@ -91,7 +92,7 @@
     modifier: Modifier = Modifier,
     enabled: Boolean = true,
     colors: CheckboxColors = CheckboxDefaults.colors(),
-    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() }
+    interactionSource: MutableInteractionSource? = null
 ) {
     TriStateCheckbox(
         state = ToggleableState(checked),
@@ -130,9 +131,10 @@
  * services.
  * @param colors [CheckboxColors] that will be used to resolve the colors used for this checkbox in
  * different states. See [CheckboxDefaults.colors].
- * @param interactionSource the [MutableInteractionSource] representing the stream of [Interaction]s
- * for this checkbox. You can create and pass in your own `remember`ed instance to observe
- * [Interaction]s and customize the appearance / behavior of this checkbox in different states.
+ * @param interactionSource an optional hoisted [MutableInteractionSource] for observing and
+ * emitting [Interaction]s for this checkbox. You can use this to change the checkbox's appearance
+ * or preview the checkbox in different states. Note that if `null` is provided, interactions will
+ * still happen internally.
  */
 @Composable
 fun TriStateCheckbox(
@@ -141,7 +143,7 @@
     modifier: Modifier = Modifier,
     enabled: Boolean = true,
     colors: CheckboxColors = CheckboxDefaults.colors(),
-    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() }
+    interactionSource: MutableInteractionSource? = null
 ) {
     val toggleableModifier =
         if (onClick != null) {
diff --git a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Chip.kt b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Chip.kt
index b4d1e5a..87367dd 100644
--- a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Chip.kt
+++ b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Chip.kt
@@ -105,9 +105,10 @@
  * [AssistChipDefaults.assistChipElevation].
  * @param border the border to draw around the container of this chip. Pass `null` for no border.
  * See [AssistChipDefaults.assistChipBorder].
- * @param interactionSource the [MutableInteractionSource] representing the stream of [Interaction]s
- * for this chip. You can create and pass in your own `remember`ed instance to observe
- * [Interaction]s and customize the appearance / behavior of this chip in different states.
+ * @param interactionSource an optional hoisted [MutableInteractionSource] for observing and
+ * emitting [Interaction]s for this chip. You can use this to change the chip's appearance
+ * or preview the chip in different states. Note that if `null` is provided, interactions will
+ * still happen internally.
  */
 @Composable
 fun AssistChip(
@@ -121,7 +122,7 @@
     colors: ChipColors = AssistChipDefaults.assistChipColors(),
     elevation: ChipElevation? = AssistChipDefaults.assistChipElevation(),
     border: BorderStroke? = AssistChipDefaults.assistChipBorder(enabled),
-    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
+    interactionSource: MutableInteractionSource? = null,
 ) = Chip(
     modifier = modifier,
     onClick = onClick,
@@ -256,9 +257,10 @@
  * [ColorScheme.surface], this controls the amount of primary color applied as an overlay. See
  * [AssistChipDefaults.elevatedAssistChipElevation].
  * @param border the border to draw around the container of this chip
- * @param interactionSource the [MutableInteractionSource] representing the stream of [Interaction]s
- * for this chip. You can create and pass in your own `remember`ed instance to observe
- * [Interaction]s and customize the appearance / behavior of this chip in different states.
+ * @param interactionSource an optional hoisted [MutableInteractionSource] for observing and
+ * emitting [Interaction]s for this chip. You can use this to change the chip's appearance
+ * or preview the chip in different states. Note that if `null` is provided, interactions will
+ * still happen internally.
  */
 @Composable
 fun ElevatedAssistChip(
@@ -272,7 +274,7 @@
     colors: ChipColors = AssistChipDefaults.elevatedAssistChipColors(),
     elevation: ChipElevation? = AssistChipDefaults.elevatedAssistChipElevation(),
     border: BorderStroke? = null,
-    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() }
+    interactionSource: MutableInteractionSource? = null
 ) = Chip(
     modifier = modifier,
     onClick = onClick,
@@ -415,9 +417,10 @@
  * overlay. See [FilterChipDefaults.filterChipElevation].
  * @param border the border to draw around the container of this chip. Pass `null` for no border.
  * See [FilterChipDefaults.filterChipBorder].
- * @param interactionSource the [MutableInteractionSource] representing the stream of [Interaction]s
- * for this chip. You can create and pass in your own `remember`ed instance to observe
- * [Interaction]s and customize the appearance / behavior of this chip in different states.
+ * @param interactionSource an optional hoisted [MutableInteractionSource] for observing and
+ * emitting [Interaction]s for this chip. You can use this to change the chip's appearance
+ * or preview the chip in different states. Note that if `null` is provided, interactions will
+ * still happen internally.
  */
 @Composable
 fun FilterChip(
@@ -432,7 +435,7 @@
     colors: SelectableChipColors = FilterChipDefaults.filterChipColors(),
     elevation: SelectableChipElevation? = FilterChipDefaults.filterChipElevation(),
     border: BorderStroke? = FilterChipDefaults.filterChipBorder(enabled, selected),
-    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() }
+    interactionSource: MutableInteractionSource? = null
 ) = SelectableChip(
     selected = selected,
     modifier = modifier,
@@ -494,9 +497,10 @@
  * overlay. See [FilterChipDefaults.filterChipElevation].
  * @param border the border to draw around the container of this chip. Pass `null` for no border.
  * See [FilterChipDefaults.filterChipBorder].
- * @param interactionSource the [MutableInteractionSource] representing the stream of [Interaction]s
- * for this chip. You can create and pass in your own `remember`ed instance to observe
- * [Interaction]s and customize the appearance / behavior of this chip in different states.
+ * @param interactionSource an optional hoisted [MutableInteractionSource] for observing and
+ * emitting [Interaction]s for this chip. You can use this to change the chip's appearance
+ * or preview the chip in different states. Note that if `null` is provided, interactions will
+ * still happen internally.
  */
 @Composable
 fun ElevatedFilterChip(
@@ -511,7 +515,7 @@
     colors: SelectableChipColors = FilterChipDefaults.elevatedFilterChipColors(),
     elevation: SelectableChipElevation? = FilterChipDefaults.elevatedFilterChipElevation(),
     border: BorderStroke? = null,
-    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() }
+    interactionSource: MutableInteractionSource? = null
 ) = SelectableChip(
     selected = selected,
     modifier = modifier,
@@ -577,9 +581,10 @@
  * [InputChipDefaults.inputChipElevation].
  * @param border the border to draw around the container of this chip. Pass `null` for no border.
  * See [InputChipDefaults.inputChipBorder].
- * @param interactionSource the [MutableInteractionSource] representing the stream of [Interaction]s
- * for this chip. You can create and pass in your own `remember`ed instance to observe
- * [Interaction]s and customize the appearance / behavior of this chip in different states.
+ * @param interactionSource an optional hoisted [MutableInteractionSource] for observing and
+ * emitting [Interaction]s for this chip. You can use this to change the chip's appearance
+ * or preview the chip in different states. Note that if `null` is provided, interactions will
+ * still happen internally.
  */
 @Composable
 fun InputChip(
@@ -595,7 +600,7 @@
     colors: SelectableChipColors = InputChipDefaults.inputChipColors(),
     elevation: SelectableChipElevation? = InputChipDefaults.inputChipElevation(),
     border: BorderStroke? = InputChipDefaults.inputChipBorder(enabled, selected),
-    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
+    interactionSource: MutableInteractionSource? = null,
 ) {
     // If given, place the avatar in an InputChipTokens.AvatarShape shape before passing it into the
     // Chip function.
@@ -675,9 +680,10 @@
  * [SuggestionChipDefaults.suggestionChipElevation].
  * @param border the border to draw around the container of this chip. Pass `null` for no border.
  * See [SuggestionChipDefaults.suggestionChipBorder].
- * @param interactionSource the [MutableInteractionSource] representing the stream of [Interaction]s
- * for this chip. You can create and pass in your own `remember`ed instance to observe
- * [Interaction]s and customize the appearance / behavior of this chip in different states.
+ * @param interactionSource an optional hoisted [MutableInteractionSource] for observing and
+ * emitting [Interaction]s for this chip. You can use this to change the chip's appearance
+ * or preview the chip in different states. Note that if `null` is provided, interactions will
+ * still happen internally.
  */
 @Composable
 fun SuggestionChip(
@@ -690,7 +696,7 @@
     colors: ChipColors = SuggestionChipDefaults.suggestionChipColors(),
     elevation: ChipElevation? = SuggestionChipDefaults.suggestionChipElevation(),
     border: BorderStroke? = SuggestionChipDefaults.suggestionChipBorder(enabled),
-    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
+    interactionSource: MutableInteractionSource? = null,
 ) = Chip(
     modifier = modifier,
     onClick = onClick,
@@ -820,9 +826,10 @@
  * [Surface] and [SuggestionChipDefaults.elevatedSuggestionChipElevation].
  * @param border the border to draw around the container of this chip
  * different states. See [SuggestionChipDefaults.elevatedSuggestionChipColors].
- * @param interactionSource the [MutableInteractionSource] representing the stream of [Interaction]s
- * for this chip. You can create and pass in your own `remember`ed instance to observe
- * [Interaction]s and customize the appearance / behavior of this chip in different states.
+ * @param interactionSource an optional hoisted [MutableInteractionSource] for observing and
+ * emitting [Interaction]s for this chip. You can use this to change the chip's appearance
+ * or preview the chip in different states. Note that if `null` is provided, interactions will
+ * still happen internally.
  */
 @Composable
 fun ElevatedSuggestionChip(
@@ -835,7 +842,7 @@
     colors: ChipColors = SuggestionChipDefaults.elevatedSuggestionChipColors(),
     elevation: ChipElevation? = SuggestionChipDefaults.elevatedSuggestionChipElevation(),
     border: BorderStroke? = null,
-    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
+    interactionSource: MutableInteractionSource? = null,
 ) = Chip(
     modifier = modifier,
     onClick = onClick,
@@ -1856,8 +1863,10 @@
     border: BorderStroke?,
     minHeight: Dp,
     paddingValues: PaddingValues,
-    interactionSource: MutableInteractionSource,
+    interactionSource: MutableInteractionSource?,
 ) {
+    @Suppress("NAME_SHADOWING")
+    val interactionSource = interactionSource ?: remember { MutableInteractionSource() }
     Surface(
         onClick = onClick,
         modifier = modifier.semantics { role = Role.Button },
@@ -1867,7 +1876,7 @@
         tonalElevation = elevation?.tonalElevation(enabled) ?: 0.dp,
         shadowElevation = elevation?.shadowElevation(enabled, interactionSource)?.value ?: 0.dp,
         border = border,
-        interactionSource = interactionSource,
+        interactionSource = interactionSource
     ) {
         ChipContent(
             label = label,
@@ -1901,8 +1910,10 @@
     border: BorderStroke?,
     minHeight: Dp,
     paddingValues: PaddingValues,
-    interactionSource: MutableInteractionSource
+    interactionSource: MutableInteractionSource?
 ) {
+    @Suppress("NAME_SHADOWING")
+    val interactionSource = interactionSource ?: remember { MutableInteractionSource() }
     // TODO(b/229794614): Animate transition between unselected and selected.
     Surface(
         selected = selected,
@@ -1914,7 +1925,7 @@
         tonalElevation = elevation?.tonalElevation(enabled) ?: 0.dp,
         shadowElevation = elevation?.shadowElevation(enabled, interactionSource)?.value ?: 0.dp,
         border = border,
-        interactionSource = interactionSource,
+        interactionSource = interactionSource
     ) {
         ChipContent(
             label = label,
diff --git a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/FloatingActionButton.kt b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/FloatingActionButton.kt
index 351a3ba..2cb8ef65 100644
--- a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/FloatingActionButton.kt
+++ b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/FloatingActionButton.kt
@@ -85,9 +85,10 @@
  * different states. This controls the size of the shadow below the FAB. Additionally, when the
  * container color is [ColorScheme.surface], this controls the amount of primary color applied as an
  * overlay. See also: [Surface].
- * @param interactionSource the [MutableInteractionSource] representing the stream of [Interaction]s
- * for this FAB. You can create and pass in your own `remember`ed instance to observe [Interaction]s
- * and customize the appearance / behavior of this FAB in different states.
+ * @param interactionSource an optional hoisted [MutableInteractionSource] for observing and
+ * emitting [Interaction]s for this FAB. You can use this to change the FAB's appearance
+ * or preview the FAB in different states. Note that if `null` is provided, interactions will
+ * still happen internally.
  * @param content the content of this FAB, typically an [Icon]
  */
 @Composable
@@ -98,9 +99,11 @@
     containerColor: Color = FloatingActionButtonDefaults.containerColor,
     contentColor: Color = contentColorFor(containerColor),
     elevation: FloatingActionButtonElevation = FloatingActionButtonDefaults.elevation(),
-    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
+    interactionSource: MutableInteractionSource? = null,
     content: @Composable () -> Unit,
 ) {
+    @Suppress("NAME_SHADOWING")
+    val interactionSource = interactionSource ?: remember { MutableInteractionSource() }
     Surface(
         onClick = onClick,
         modifier = modifier.semantics { role = Role.Button },
@@ -109,7 +112,7 @@
         contentColor = contentColor,
         tonalElevation = elevation.tonalElevation(),
         shadowElevation = elevation.shadowElevation(interactionSource = interactionSource).value,
-        interactionSource = interactionSource,
+        interactionSource = interactionSource
     ) {
         ProvideContentColorTextStyle(
             contentColor = contentColor,
@@ -148,9 +151,10 @@
  * different states. This controls the size of the shadow below the FAB. Additionally, when the
  * container color is [ColorScheme.surface], this controls the amount of primary color applied as an
  * overlay. See also: [Surface].
- * @param interactionSource the [MutableInteractionSource] representing the stream of [Interaction]s
- * for this FAB. You can create and pass in your own `remember`ed instance to observe [Interaction]s
- * and customize the appearance / behavior of this FAB in different states.
+ * @param interactionSource an optional hoisted [MutableInteractionSource] for observing and
+ * emitting [Interaction]s for this FAB. You can use this to change the FAB's appearance
+ * or preview the FAB in different states. Note that if `null` is provided, interactions will
+ * still happen internally.
  * @param content the content of this FAB, typically an [Icon]
  */
 @Composable
@@ -161,7 +165,7 @@
     containerColor: Color = FloatingActionButtonDefaults.containerColor,
     contentColor: Color = contentColorFor(containerColor),
     elevation: FloatingActionButtonElevation = FloatingActionButtonDefaults.elevation(),
-    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
+    interactionSource: MutableInteractionSource? = null,
     content: @Composable () -> Unit,
 ) {
     FloatingActionButton(
@@ -200,9 +204,10 @@
  * different states. This controls the size of the shadow below the FAB. Additionally, when the
  * container color is [ColorScheme.surface], this controls the amount of primary color applied as an
  * overlay. See also: [Surface].
- * @param interactionSource the [MutableInteractionSource] representing the stream of [Interaction]s
- * for this FAB. You can create and pass in your own `remember`ed instance to observe [Interaction]s
- * and customize the appearance / behavior of this FAB in different states.
+ * @param interactionSource an optional hoisted [MutableInteractionSource] for observing and
+ * emitting [Interaction]s for this FAB. You can use this to change the FAB's appearance
+ * or preview the FAB in different states. Note that if `null` is provided, interactions will
+ * still happen internally.
  * @param content the content of this FAB, typically an [Icon]
  */
 @Composable
@@ -213,7 +218,7 @@
     containerColor: Color = FloatingActionButtonDefaults.containerColor,
     contentColor: Color = contentColorFor(containerColor),
     elevation: FloatingActionButtonElevation = FloatingActionButtonDefaults.elevation(),
-    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
+    interactionSource: MutableInteractionSource? = null,
     content: @Composable () -> Unit,
 ) {
     FloatingActionButton(
@@ -255,9 +260,10 @@
  * different states. This controls the size of the shadow below the FAB. Additionally, when the
  * container color is [ColorScheme.surface], this controls the amount of primary color applied as an
  * overlay. See also: [Surface].
- * @param interactionSource the [MutableInteractionSource] representing the stream of [Interaction]s
- * for this FAB. You can create and pass in your own `remember`ed instance to observe [Interaction]s
- * and customize the appearance / behavior of this FAB in different states.
+ * @param interactionSource an optional hoisted [MutableInteractionSource] for observing and
+ * emitting [Interaction]s for this FAB. You can use this to change the FAB's appearance
+ * or preview the FAB in different states. Note that if `null` is provided, interactions will
+ * still happen internally.
  * @param content the content of this FAB, typically a [Text] label
  */
 @Composable
@@ -268,7 +274,7 @@
     containerColor: Color = FloatingActionButtonDefaults.containerColor,
     contentColor: Color = contentColorFor(containerColor),
     elevation: FloatingActionButtonElevation = FloatingActionButtonDefaults.elevation(),
-    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
+    interactionSource: MutableInteractionSource? = null,
     content: @Composable RowScope.() -> Unit,
 ) {
     FloatingActionButton(
@@ -323,9 +329,10 @@
  * different states. This controls the size of the shadow below the FAB. Additionally, when the
  * container color is [ColorScheme.surface], this controls the amount of primary color applied as an
  * overlay. See also: [Surface].
- * @param interactionSource the [MutableInteractionSource] representing the stream of [Interaction]s
- * for this FAB. You can create and pass in your own `remember`ed instance to observe [Interaction]s
- * and customize the appearance / behavior of this FAB in different states.
+ * @param interactionSource an optional hoisted [MutableInteractionSource] for observing and
+ * emitting [Interaction]s for this FAB. You can use this to change the FAB's appearance
+ * or preview the FAB in different states. Note that if `null` is provided, interactions will
+ * still happen internally.
  */
 @Composable
 fun ExtendedFloatingActionButton(
@@ -338,7 +345,7 @@
     containerColor: Color = FloatingActionButtonDefaults.containerColor,
     contentColor: Color = contentColorFor(containerColor),
     elevation: FloatingActionButtonElevation = FloatingActionButtonDefaults.elevation(),
-    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
+    interactionSource: MutableInteractionSource? = null,
 ) {
     FloatingActionButton(
         onClick = onClick,
diff --git a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/IconButton.kt b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/IconButton.kt
index 0c04943..6a1a426 100644
--- a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/IconButton.kt
+++ b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/IconButton.kt
@@ -66,9 +66,10 @@
  * services.
  * @param colors [IconButtonColors] that will be used to resolve the colors used for this icon
  * button in different states. See [IconButtonDefaults.iconButtonColors].
- * @param interactionSource the [MutableInteractionSource] representing the stream of [Interaction]s
- * for this icon button. You can create and pass in your own `remember`ed instance to observe
- * [Interaction]s and customize the appearance / behavior of this icon button in different states.
+ * @param interactionSource an optional hoisted [MutableInteractionSource] for observing and
+ * emitting [Interaction]s for this icon button. You can use this to change the icon button's
+ * appearance or preview the icon button in different states. Note that if `null` is provided,
+ * interactions will still happen internally.
  * @param content the content of this icon button, typically an [Icon]
  */
 @Composable
@@ -77,7 +78,7 @@
     modifier: Modifier = Modifier,
     enabled: Boolean = true,
     colors: IconButtonColors = IconButtonDefaults.iconButtonColors(),
-    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
+    interactionSource: MutableInteractionSource? = null,
     content: @Composable () -> Unit
 ) {
     Box(
@@ -126,9 +127,10 @@
  * services.
  * @param colors [IconToggleButtonColors] that will be used to resolve the colors used for this icon
  * button in different states. See [IconButtonDefaults.iconToggleButtonColors].
- * @param interactionSource the [MutableInteractionSource] representing the stream of [Interaction]s
- * for this icon button. You can create and pass in your own `remember`ed instance to observe
- * [Interaction]s and customize the appearance / behavior of this icon button in different states.
+ * @param interactionSource an optional hoisted [MutableInteractionSource] for observing and
+ * emitting [Interaction]s for this icon button. You can use this to change the icon button's
+ * appearance or preview the icon button in different states. Note that if `null` is provided,
+ * interactions will still happen internally.
  * @param content the content of this icon button, typically an [Icon]
  */
 @Composable
@@ -138,7 +140,7 @@
     modifier: Modifier = Modifier,
     enabled: Boolean = true,
     colors: IconToggleButtonColors = IconButtonDefaults.iconToggleButtonColors(),
-    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
+    interactionSource: MutableInteractionSource? = null,
     content: @Composable () -> Unit
 ) {
     Box(
@@ -189,9 +191,10 @@
  * @param shape defines the shape of this icon button's container
  * @param colors [IconButtonColors] that will be used to resolve the colors used for this icon
  * button in different states. See [IconButtonDefaults.filledIconButtonColors].
- * @param interactionSource the [MutableInteractionSource] representing the stream of [Interaction]s
- * for this icon button. You can create and pass in your own `remember`ed instance to observe
- * [Interaction]s and customize the appearance / behavior of this icon button in different states.
+ * @param interactionSource an optional hoisted [MutableInteractionSource] for observing and
+ * emitting [Interaction]s for this icon button. You can use this to change the icon button's
+ * appearance or preview the icon button in different states. Note that if `null` is provided,
+ * interactions will still happen internally.
  * @param content the content of this icon button, typically an [Icon]
  */
 @Composable
@@ -201,7 +204,7 @@
     enabled: Boolean = true,
     shape: Shape = IconButtonDefaults.filledShape,
     colors: IconButtonColors = IconButtonDefaults.filledIconButtonColors(),
-    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
+    interactionSource: MutableInteractionSource? = null,
     content: @Composable () -> Unit
 ) = Surface(
     onClick = onClick,
@@ -249,9 +252,10 @@
  * @param shape defines the shape of this icon button's container
  * @param colors [IconButtonColors] that will be used to resolve the colors used for this icon
  * button in different states. See [IconButtonDefaults.filledIconButtonColors].
- * @param interactionSource the [MutableInteractionSource] representing the stream of [Interaction]s
- * for this icon button. You can create and pass in your own `remember`ed instance to observe
- * [Interaction]s and customize the appearance / behavior of this icon button in different states.
+ * @param interactionSource an optional hoisted [MutableInteractionSource] for observing and
+ * emitting [Interaction]s for this icon button. You can use this to change the icon button's
+ * appearance or preview the icon button in different states. Note that if `null` is provided,
+ * interactions will still happen internally.
  * @param content the content of this icon button, typically an [Icon]
  */
 @Composable
@@ -261,7 +265,7 @@
     enabled: Boolean = true,
     shape: Shape = IconButtonDefaults.filledShape,
     colors: IconButtonColors = IconButtonDefaults.filledTonalIconButtonColors(),
-    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
+    interactionSource: MutableInteractionSource? = null,
     content: @Composable () -> Unit
 ) = Surface(
     onClick = onClick,
@@ -305,9 +309,10 @@
  * @param shape defines the shape of this icon button's container
  * @param colors [IconToggleButtonColors] that will be used to resolve the colors used for this icon
  * button in different states. See [IconButtonDefaults.filledIconToggleButtonColors].
- * @param interactionSource the [MutableInteractionSource] representing the stream of [Interaction]s
- * for this icon button. You can create and pass in your own `remember`ed instance to observe
- * [Interaction]s and customize the appearance / behavior of this icon button in different states.
+ * @param interactionSource an optional hoisted [MutableInteractionSource] for observing and
+ * emitting [Interaction]s for this icon button. You can use this to change the icon button's
+ * appearance or preview the icon button in different states. Note that if `null` is provided,
+ * interactions will still happen internally.
  * @param content the content of this icon button, typically an [Icon]
  */
 @OptIn(ExperimentalMaterial3Api::class)
@@ -319,7 +324,7 @@
     enabled: Boolean = true,
     shape: Shape = IconButtonDefaults.filledShape,
     colors: IconToggleButtonColors = IconButtonDefaults.filledIconToggleButtonColors(),
-    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
+    interactionSource: MutableInteractionSource? = null,
     content: @Composable () -> Unit
 ) = Surface(
     checked = checked,
@@ -369,9 +374,10 @@
  * @param shape defines the shape of this icon button's container
  * @param colors [IconToggleButtonColors] that will be used to resolve the colors used for this icon
  * button in different states. See [IconButtonDefaults.filledIconToggleButtonColors].
- * @param interactionSource the [MutableInteractionSource] representing the stream of [Interaction]s
- * for this icon button. You can create and pass in your own `remember`ed instance to observe
- * [Interaction]s and customize the appearance / behavior of this icon button in different states.
+ * @param interactionSource an optional hoisted [MutableInteractionSource] for observing and
+ * emitting [Interaction]s for this icon button. You can use this to change the icon button's
+ * appearance or preview the icon button in different states. Note that if `null` is provided,
+ * interactions will still happen internally.
  * @param content the content of this icon button, typically an [Icon]
  */
 @OptIn(ExperimentalMaterial3Api::class)
@@ -383,7 +389,7 @@
     enabled: Boolean = true,
     shape: Shape = IconButtonDefaults.filledShape,
     colors: IconToggleButtonColors = IconButtonDefaults.filledTonalIconToggleButtonColors(),
-    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
+    interactionSource: MutableInteractionSource? = null,
     content: @Composable () -> Unit
 ) = Surface(
     checked = checked,
@@ -435,9 +441,10 @@
  * button in different states. See [IconButtonDefaults.outlinedIconButtonColors].
  * @param border the border to draw around the container of this icon button. Pass `null` for no
  * border. See [IconButtonDefaults.outlinedIconButtonBorder].
- * @param interactionSource the [MutableInteractionSource] representing the stream of [Interaction]s
- * for this icon button. You can create and pass in your own `remember`ed instance to observe
- * [Interaction]s and customize the appearance / behavior of this icon button in different states.
+ * @param interactionSource an optional hoisted [MutableInteractionSource] for observing and
+ * emitting [Interaction]s for this icon button. You can use this to change the icon button's
+ * appearance or preview the icon button in different states. Note that if `null` is provided,
+ * interactions will still happen internally.
  * @param content the content of this icon button, typically an [Icon]
  */
 @Composable
@@ -448,7 +455,7 @@
     shape: Shape = IconButtonDefaults.outlinedShape,
     colors: IconButtonColors = IconButtonDefaults.outlinedIconButtonColors(),
     border: BorderStroke? = IconButtonDefaults.outlinedIconButtonBorder(enabled),
-    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
+    interactionSource: MutableInteractionSource? = null,
     content: @Composable () -> Unit
 ) = Surface(
     onClick = onClick,
@@ -495,9 +502,10 @@
  * button in different states. See [IconButtonDefaults.outlinedIconToggleButtonColors].
  * @param border the border to draw around the container of this icon button. Pass `null` for no
  * border. See [IconButtonDefaults.outlinedIconToggleButtonBorder].
- * @param interactionSource the [MutableInteractionSource] representing the stream of [Interaction]s
- * for this icon button. You can create and pass in your own `remember`ed instance to observe
- * [Interaction]s and customize the appearance / behavior of this icon button in different states.
+ * @param interactionSource an optional hoisted [MutableInteractionSource] for observing and
+ * emitting [Interaction]s for this icon button. You can use this to change the icon button's
+ * appearance or preview the icon button in different states. Note that if `null` is provided,
+ * interactions will still happen internally.
  * @param content the content of this icon button, typically an [Icon]
  */
 @OptIn(ExperimentalMaterial3Api::class)
@@ -510,7 +518,7 @@
     shape: Shape = IconButtonDefaults.outlinedShape,
     colors: IconToggleButtonColors = IconButtonDefaults.outlinedIconToggleButtonColors(),
     border: BorderStroke? = IconButtonDefaults.outlinedIconToggleButtonBorder(enabled, checked),
-    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
+    interactionSource: MutableInteractionSource? = null,
     content: @Composable () -> Unit
 ) = Surface(
     checked = checked,
diff --git a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Label.kt b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Label.kt
index c035456..6e11ca4 100644
--- a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Label.kt
+++ b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Label.kt
@@ -64,10 +64,12 @@
 fun Label(
     label: @Composable CaretScope.() -> Unit,
     modifier: Modifier = Modifier,
-    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
+    interactionSource: MutableInteractionSource? = null,
     isPersistent: Boolean = false,
     content: @Composable () -> Unit
 ) {
+    @Suppress("NAME_SHADOWING")
+    val interactionSource = interactionSource ?: remember { MutableInteractionSource() }
     // Has the same positioning logic as PlainTooltips
     val positionProvider = TooltipDefaults.rememberPlainTooltipPositionProvider()
     val state = if (isPersistent)
diff --git a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Menu.kt b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Menu.kt
index 26c3861..4a9810e 100644
--- a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Menu.kt
+++ b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Menu.kt
@@ -21,6 +21,7 @@
 import androidx.compose.animation.core.animateFloat
 import androidx.compose.animation.core.tween
 import androidx.compose.animation.core.updateTransition
+import androidx.compose.foundation.BorderStroke
 import androidx.compose.foundation.ScrollState
 import androidx.compose.foundation.clickable
 import androidx.compose.foundation.interaction.MutableInteractionSource
@@ -47,25 +48,38 @@
 import androidx.compose.ui.Alignment
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.graphics.Shape
 import androidx.compose.ui.graphics.TransformOrigin
 import androidx.compose.ui.graphics.graphicsLayer
 import androidx.compose.ui.graphics.takeOrElse
+import androidx.compose.ui.unit.Dp
 import androidx.compose.ui.unit.IntRect
 import androidx.compose.ui.unit.dp
 import kotlin.math.max
 import kotlin.math.min
 
 /**
- * Contains default values used for [DropdownMenuItem].
+ * Contains default values used for [DropdownMenu] and [DropdownMenuItem].
  */
 object MenuDefaults {
+    /** The default tonal elevation for a menu. */
+    val TonalElevation = MenuTokens.ContainerElevation
 
-/**
- * Creates a [MenuItemColors] that represents the default text and icon colors used in a
- * [DropdownMenuItemContent].
- */
-@Composable
-fun itemColors() = MaterialTheme.colorScheme.defaultMenuItemColors
+    /** The default shadow elevation for a menu. */
+    val ShadowElevation = MenuTokens.ContainerElevation
+
+    /** The default shape for a menu. */
+    val shape @Composable get() = MenuTokens.ContainerShape.value
+
+    /** The default container color for a menu. */
+    val containerColor @Composable get() = MenuTokens.ContainerColor.value
+
+    /**
+     * Creates a [MenuItemColors] that represents the default text and icon colors used in a
+     * [DropdownMenuItemContent].
+     */
+    @Composable
+    fun itemColors() = MaterialTheme.colorScheme.defaultMenuItemColors
 
     /**
      * Creates a [MenuItemColors] that represents the default text and icon colors used in a
@@ -102,13 +116,13 @@
         get() {
             return defaultMenuItemColorsCached ?: MenuItemColors(
                 textColor = fromToken(MenuTokens.ListItemLabelTextColor),
-            leadingIconColor = fromToken(MenuTokens.ListItemLeadingIconColor),
-            trailingIconColor = fromToken(MenuTokens.ListItemTrailingIconColor),
-            disabledTextColor = fromToken(MenuTokens.ListItemDisabledLabelTextColor),
-            disabledLeadingIconColor = fromToken(MenuTokens.ListItemDisabledLeadingIconColor)
-            .copy(alpha = MenuTokens.ListItemDisabledLeadingIconOpacity),
-            disabledTrailingIconColor = fromToken(MenuTokens.ListItemDisabledTrailingIconColor)
-            .copy(alpha = MenuTokens.ListItemDisabledTrailingIconOpacity),
+                leadingIconColor = fromToken(MenuTokens.ListItemLeadingIconColor),
+                trailingIconColor = fromToken(MenuTokens.ListItemTrailingIconColor),
+                disabledTextColor = fromToken(MenuTokens.ListItemDisabledLabelTextColor),
+                disabledLeadingIconColor = fromToken(MenuTokens.ListItemDisabledLeadingIconColor)
+                    .copy(alpha = MenuTokens.ListItemDisabledLeadingIconOpacity),
+                disabledTrailingIconColor = fromToken(MenuTokens.ListItemDisabledTrailingIconColor)
+                    .copy(alpha = MenuTokens.ListItemDisabledTrailingIconOpacity),
             ).also {
                 defaultMenuItemColorsCached = it
             }
@@ -224,10 +238,15 @@
 
 @Composable
 internal fun DropdownMenuContent(
+    modifier: Modifier,
     expandedState: MutableTransitionState<Boolean>,
     transformOriginState: MutableState<TransformOrigin>,
     scrollState: ScrollState,
-    modifier: Modifier = Modifier,
+    shape: Shape,
+    containerColor: Color,
+    tonalElevation: Dp,
+    shadowElevation: Dp,
+    border: BorderStroke?,
     content: @Composable ColumnScope.() -> Unit
 ) {
     // Menu open/close animation.
@@ -275,10 +294,11 @@
             this.alpha = alpha
             transformOrigin = transformOriginState.value
         },
-        shape = MenuTokens.ContainerShape.value,
-        color = MaterialTheme.colorScheme.fromToken(MenuTokens.ContainerColor),
-        tonalElevation = MenuTokens.ContainerElevation,
-        shadowElevation = MenuTokens.ContainerElevation
+        shape = shape,
+        color = containerColor,
+        tonalElevation = tonalElevation,
+        shadowElevation = shadowElevation,
+        border = border,
     ) {
         Column(
             modifier = modifier
@@ -300,7 +320,7 @@
     enabled: Boolean,
     colors: MenuItemColors,
     contentPadding: PaddingValues,
-    interactionSource: MutableInteractionSource
+    interactionSource: MutableInteractionSource?
 ) {
     Row(
         modifier = modifier
diff --git a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/NavigationBar.kt b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/NavigationBar.kt
index e9cbcaf..03c629f 100644
--- a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/NavigationBar.kt
+++ b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/NavigationBar.kt
@@ -156,9 +156,10 @@
  * only be shown when this item is selected.
  * @param colors [NavigationBarItemColors] that will be used to resolve the colors used for this
  * item in different states. See [NavigationBarItemDefaults.colors].
- * @param interactionSource the [MutableInteractionSource] representing the stream of [Interaction]s
- * for this item. You can create and pass in your own `remember`ed instance to observe
- * [Interaction]s and customize the appearance / behavior of this item in different states.
+ * @param interactionSource an optional hoisted [MutableInteractionSource] for observing and
+ * emitting [Interaction]s for this item. You can use this to change the item's appearance
+ * or preview the item in different states. Note that if `null` is provided, interactions will
+ * still happen internally.
  */
 @Composable
 fun RowScope.NavigationBarItem(
@@ -170,8 +171,10 @@
     label: @Composable (() -> Unit)? = null,
     alwaysShowLabel: Boolean = true,
     colors: NavigationBarItemColors = NavigationBarItemDefaults.colors(),
-    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() }
+    interactionSource: MutableInteractionSource? = null
 ) {
+    @Suppress("NAME_SHADOWING")
+    val interactionSource = interactionSource ?: remember { MutableInteractionSource() }
     val styledIcon = @Composable {
         val iconColor by colors.iconColor(selected = selected, enabled = enabled)
         // If there's a label, don't have a11y services repeat the icon description.
diff --git a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/NavigationDrawer.kt b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/NavigationDrawer.kt
index 2108ea1..e9b873c 100644
--- a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/NavigationDrawer.kt
+++ b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/NavigationDrawer.kt
@@ -715,9 +715,10 @@
  * @param badge optional badge to show on this item from the end side
  * @param colors [NavigationDrawerItemColors] that will be used to resolve the colors used for this
  * item in different states. See [NavigationDrawerItemDefaults.colors].
- * @param interactionSource the [MutableInteractionSource] representing the stream of [Interaction]s
- * for this item. You can create and pass in your own `remember`ed instance to observe
- * [Interaction]s and customize the appearance / behavior of this item in different states.
+ * @param interactionSource an optional hoisted [MutableInteractionSource] for observing and
+ * emitting [Interaction]s for this item. You can use this to change the item's appearance
+ * or preview the item in different states. Note that if `null` is provided, interactions will
+ * still happen internally.
  */
 @Composable
 fun NavigationDrawerItem(
@@ -729,7 +730,7 @@
     badge: (@Composable () -> Unit)? = null,
     shape: Shape = NavigationDrawerTokens.ActiveIndicatorShape.value,
     colors: NavigationDrawerItemColors = NavigationDrawerItemDefaults.colors(),
-    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() }
+    interactionSource: MutableInteractionSource? = null
 ) {
     Surface(
         selected = selected,
diff --git a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/NavigationRail.kt b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/NavigationRail.kt
index 0c8bfef..ae6e941 100644
--- a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/NavigationRail.kt
+++ b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/NavigationRail.kt
@@ -157,9 +157,10 @@
  * only be shown when this item is selected.
  * @param colors [NavigationRailItemColors] that will be used to resolve the colors used for this
  * item in different states. See [NavigationRailItemDefaults.colors].
- * @param interactionSource the [MutableInteractionSource] representing the stream of [Interaction]s
- * for this item. You can create and pass in your own `remember`ed instance to observe
- * [Interaction]s and customize the appearance / behavior of this item in different states.
+ * @param interactionSource an optional hoisted [MutableInteractionSource] for observing and
+ * emitting [Interaction]s for this item. You can use this to change the item's appearance
+ * or preview the item in different states. Note that if `null` is provided, interactions will
+ * still happen internally.
  */
 @Composable
 fun NavigationRailItem(
@@ -171,8 +172,10 @@
     label: @Composable (() -> Unit)? = null,
     alwaysShowLabel: Boolean = true,
     colors: NavigationRailItemColors = NavigationRailItemDefaults.colors(),
-    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
+    interactionSource: MutableInteractionSource? = null,
 ) {
+    @Suppress("NAME_SHADOWING")
+    val interactionSource = interactionSource ?: remember { MutableInteractionSource() }
     val styledIcon = @Composable {
         val iconColor by colors.iconColor(selected = selected, enabled = enabled)
         // If there's a label, don't have a11y services repeat the icon description.
diff --git a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/OutlinedTextField.kt b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/OutlinedTextField.kt
index 20208e2..465ffd2 100644
--- a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/OutlinedTextField.kt
+++ b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/OutlinedTextField.kt
@@ -130,9 +130,10 @@
  * that 1 <= [minLines] <= [maxLines]. This parameter is ignored when [singleLine] is true.
  * @param minLines the minimum height in terms of minimum number of visible lines. It is required
  * that 1 <= [minLines] <= [maxLines]. This parameter is ignored when [singleLine] is true.
- * @param interactionSource the [MutableInteractionSource] representing the stream of [Interaction]s
- * for this text field. You can create and pass in your own `remember`ed instance to observe
- * [Interaction]s and customize the appearance / behavior of this text field in different states.
+ * @param interactionSource an optional hoisted [MutableInteractionSource] for observing and
+ * emitting [Interaction]s for this text field. You can use this to change the text field's
+ * appearance or preview the text field in different states. Note that if `null` is provided,
+ * interactions will still happen internally.
  * @param shape defines the shape of this text field's border
  * @param colors [TextFieldColors] that will be used to resolve the colors used for this text field
  * in different states. See [OutlinedTextFieldDefaults.colors].
@@ -160,10 +161,12 @@
     singleLine: Boolean = false,
     maxLines: Int = if (singleLine) 1 else Int.MAX_VALUE,
     minLines: Int = 1,
-    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
+    interactionSource: MutableInteractionSource? = null,
     shape: Shape = OutlinedTextFieldDefaults.shape,
     colors: TextFieldColors = OutlinedTextFieldDefaults.colors()
 ) {
+    @Suppress("NAME_SHADOWING")
+    val interactionSource = interactionSource ?: remember { MutableInteractionSource() }
     // If color is not provided via the text style, use content color as a default
     val textColor = textStyle.color.takeOrElse {
         colors.textColor(enabled, isError, interactionSource).value
@@ -290,9 +293,10 @@
  * that 1 <= [minLines] <= [maxLines]. This parameter is ignored when [singleLine] is true.
  * @param minLines the minimum height in terms of minimum number of visible lines. It is required
  * that 1 <= [minLines] <= [maxLines]. This parameter is ignored when [singleLine] is true.
- * @param interactionSource the [MutableInteractionSource] representing the stream of [Interaction]s
- * for this text field. You can create and pass in your own `remember`ed instance to observe
- * [Interaction]s and customize the appearance / behavior of this text field in different states.
+ * @param interactionSource an optional hoisted [MutableInteractionSource] for observing and
+ * emitting [Interaction]s for this text field. You can use this to change the text field's
+ * appearance or preview the text field in different states. Note that if `null` is provided,
+ * interactions will still happen internally.
  * @param shape defines the shape of this text field's border
  * @param colors [TextFieldColors] that will be used to resolve the colors used for this text field
  * in different states. See [OutlinedTextFieldDefaults.colors].
@@ -320,10 +324,12 @@
     singleLine: Boolean = false,
     maxLines: Int = if (singleLine) 1 else Int.MAX_VALUE,
     minLines: Int = 1,
-    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
+    interactionSource: MutableInteractionSource? = null,
     shape: Shape = OutlinedTextFieldDefaults.shape,
     colors: TextFieldColors = OutlinedTextFieldDefaults.colors()
 ) {
+    @Suppress("NAME_SHADOWING")
+    val interactionSource = interactionSource ?: remember { MutableInteractionSource() }
     // If color is not provided via the text style, use content color as a default
     val textColor = textStyle.color.takeOrElse {
         colors.textColor(enabled, isError, interactionSource).value
diff --git a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/RadioButton.kt b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/RadioButton.kt
index 4d7a9e8..51601eb 100644
--- a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/RadioButton.kt
+++ b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/RadioButton.kt
@@ -32,7 +32,6 @@
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.Immutable
 import androidx.compose.runtime.State
-import androidx.compose.runtime.remember
 import androidx.compose.runtime.rememberUpdatedState
 import androidx.compose.ui.Alignment
 import androidx.compose.ui.Modifier
@@ -65,9 +64,10 @@
  * services.
  * @param colors [RadioButtonColors] that will be used to resolve the color used for this radio
  * button in different states. See [RadioButtonDefaults.colors].
- * @param interactionSource the [MutableInteractionSource] representing the stream of [Interaction]s
- * for this radio button. You can create and pass in your own `remember`ed instance to observe
- * [Interaction]s and customize the appearance / behavior of this radio button in different states.
+ * @param interactionSource an optional hoisted [MutableInteractionSource] for observing and
+ * emitting [Interaction]s for this radio button. You can use this to change the radio button's
+ * appearance or preview the radio button in different states. Note that if `null` is provided,
+ * interactions will still happen internally.
  */
 @Composable
 fun RadioButton(
@@ -76,7 +76,7 @@
     modifier: Modifier = Modifier,
     enabled: Boolean = true,
     colors: RadioButtonColors = RadioButtonDefaults.colors(),
-    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() }
+    interactionSource: MutableInteractionSource? = null
 ) {
     val dotRadius = animateDpAsState(
         targetValue = if (selected) RadioButtonDotSize / 2 else 0.dp,
diff --git a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/SegmentedButton.kt b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/SegmentedButton.kt
index b2b7a63..0aaf210 100644
--- a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/SegmentedButton.kt
+++ b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/SegmentedButton.kt
@@ -116,9 +116,10 @@
  * @param colors [SegmentedButtonColors] that will be used to resolve the colors used for this
  * @param border the border for this button, see [SegmentedButtonColors]
  * Button in different states
- * @param interactionSource the [MutableInteractionSource] representing the stream of [Interaction]s
- * for this button. You can create and pass in your own `remember`ed instance to observe
- * [Interaction]s and customize the appearance / behavior of this button in different states.
+ * @param interactionSource an optional hoisted [MutableInteractionSource] for observing and
+ * emitting [Interaction]s for this button. You can use this to change the button's
+ * appearance or preview the button in different states. Note that if `null` is provided,
+ * interactions will still happen internally.
  * @param icon the icon slot for this button, you can pass null in unchecked, in which case
  * the content will displace to show the checked icon, or pass different icon lambdas for
  * unchecked and checked in which case the icons will crossfade.
@@ -136,10 +137,12 @@
     border: BorderStroke = SegmentedButtonDefaults.borderStroke(
         colors.borderColor(enabled, checked)
     ),
-    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
+    interactionSource: MutableInteractionSource? = null,
     icon: @Composable () -> Unit = { SegmentedButtonDefaults.Icon(checked) },
     label: @Composable () -> Unit,
 ) {
+    @Suppress("NAME_SHADOWING")
+    val interactionSource = interactionSource ?: remember { MutableInteractionSource() }
     val containerColor = colors.containerColor(enabled, checked)
     val contentColor = colors.contentColor(enabled, checked)
     val interactionCount = interactionSource.interactionCountAsState()
@@ -191,9 +194,10 @@
  * @param colors [SegmentedButtonColors] that will be used to resolve the colors used for this
  * @param border the border for this button, see [SegmentedButtonColors]
  * Button in different states
- * @param interactionSource the [MutableInteractionSource] representing the stream of [Interaction]s
- * for this button. You can create and pass in your own `remember`ed instance to observe
- * [Interaction]s and customize the appearance / behavior of this button in different states.
+ * @param interactionSource an optional hoisted [MutableInteractionSource] for observing and
+ * emitting [Interaction]s for this button. You can use this to change the button's
+ * appearance or preview the button in different states. Note that if `null` is provided,
+ * interactions will still happen internally.
  * @param icon the icon slot for this button, you can pass null in unchecked, in which case
  * the content will displace to show the checked icon, or pass different icon lambdas for
  * unchecked and checked in which case the icons will crossfade.
@@ -211,10 +215,12 @@
     border: BorderStroke = SegmentedButtonDefaults.borderStroke(
         colors.borderColor(enabled, selected)
     ),
-    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
+    interactionSource: MutableInteractionSource? = null,
     icon: @Composable () -> Unit = { SegmentedButtonDefaults.Icon(selected) },
     label: @Composable () -> Unit,
 ) {
+    @Suppress("NAME_SHADOWING")
+    val interactionSource = interactionSource ?: remember { MutableInteractionSource() }
     val containerColor = colors.containerColor(enabled, selected)
     val contentColor = colors.contentColor(enabled, selected)
     val interactionCount = interactionSource.interactionCountAsState()
diff --git a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Surface.kt b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Surface.kt
index 32e9256..f846bd7 100644
--- a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Surface.kt
+++ b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Surface.kt
@@ -31,7 +31,6 @@
 import androidx.compose.runtime.NonRestartableComposable
 import androidx.compose.runtime.Stable
 import androidx.compose.runtime.compositionLocalOf
-import androidx.compose.runtime.remember
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.draw.clip
 import androidx.compose.ui.graphics.Color
@@ -194,10 +193,10 @@
  * in a darker color in light theme and lighter color in dark theme.
  * @param shadowElevation The size of the shadow below the surface. Note that It will not affect z
  * index of the Surface. If you want to change the drawing order you can use `Modifier.zIndex`.
- * @param interactionSource the [MutableInteractionSource] representing the stream of [Interaction]s
- * for this Surface. You can create and pass in your own remembered [MutableInteractionSource] if
- * you want to observe [Interaction]s and customize the appearance / behavior of this Surface in
- * different [Interaction]s.
+ * @param interactionSource an optional hoisted [MutableInteractionSource] for observing and
+ * emitting [Interaction]s for this surface. You can use this to change the surface's
+ * appearance or preview the surface in different states. Note that if `null` is provided,
+ * interactions will still happen internally.
  */
 @Composable
 @NonRestartableComposable
@@ -211,7 +210,7 @@
     tonalElevation: Dp = 0.dp,
     shadowElevation: Dp = 0.dp,
     border: BorderStroke? = null,
-    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
+    interactionSource: MutableInteractionSource? = null,
     content: @Composable () -> Unit
 ) {
     val absoluteElevation = LocalAbsoluteTonalElevation.current + tonalElevation
@@ -302,10 +301,10 @@
  * in a darker color in light theme and lighter color in dark theme.
  * @param shadowElevation The size of the shadow below the surface. Note that It will not affect z
  * index of the Surface. If you want to change the drawing order you can use `Modifier.zIndex`.
- * @param interactionSource the [MutableInteractionSource] representing the stream of [Interaction]s
- * for this Surface. You can create and pass in your own remembered [MutableInteractionSource] if
- * you want to observe [Interaction]s and customize the appearance / behavior of this Surface in
- * different [Interaction]s.
+ * @param interactionSource an optional hoisted [MutableInteractionSource] for observing and
+ * emitting [Interaction]s for this surface. You can use this to change the surface's
+ * appearance or preview the surface in different states. Note that if `null` is provided,
+ * interactions will still happen internally.
  */
 @Composable
 @NonRestartableComposable
@@ -320,7 +319,7 @@
     tonalElevation: Dp = 0.dp,
     shadowElevation: Dp = 0.dp,
     border: BorderStroke? = null,
-    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
+    interactionSource: MutableInteractionSource? = null,
     content: @Composable () -> Unit
 ) {
     val absoluteElevation = LocalAbsoluteTonalElevation.current + tonalElevation
@@ -412,10 +411,10 @@
  * in a darker color in light theme and lighter color in dark theme.
  * @param shadowElevation The size of the shadow below the surface. Note that It will not affect z
  * index of the Surface. If you want to change the drawing order you can use `Modifier.zIndex`.
- * @param interactionSource the [MutableInteractionSource] representing the stream of [Interaction]s
- * for this Surface. You can create and pass in your own remembered [MutableInteractionSource] if
- * you want to observe [Interaction]s and customize the appearance / behavior of this Surface in
- * different [Interaction]s.
+ * @param interactionSource an optional hoisted [MutableInteractionSource] for observing and
+ * emitting [Interaction]s for this surface. You can use this to change the surface's
+ * appearance or preview the surface in different states. Note that if `null` is provided,
+ * interactions will still happen internally.
  */
 @Composable
 @NonRestartableComposable
@@ -430,7 +429,7 @@
     tonalElevation: Dp = 0.dp,
     shadowElevation: Dp = 0.dp,
     border: BorderStroke? = null,
-    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
+    interactionSource: MutableInteractionSource? = null,
     content: @Composable () -> Unit
 ) {
     val absoluteElevation = LocalAbsoluteTonalElevation.current + tonalElevation
diff --git a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Switch.kt b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Switch.kt
index 9dfc2e8..7e17cb0 100644
--- a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Switch.kt
+++ b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Switch.kt
@@ -82,9 +82,10 @@
  * services.
  * @param colors [SwitchColors] that will be used to resolve the colors used for this switch in
  * different states. See [SwitchDefaults.colors].
- * @param interactionSource the [MutableInteractionSource] representing the stream of [Interaction]s
- * for this switch. You can create and pass in your own `remember`ed instance to observe
- * [Interaction]s and customize the appearance / behavior of this switch in different states.
+ * @param interactionSource an optional hoisted [MutableInteractionSource] for observing and
+ * emitting [Interaction]s for this switch. You can use this to change the switch's
+ * appearance or preview the switch in different states. Note that if `null` is provided,
+ * interactions will still happen internally.
  */
 @Composable
 @Suppress("ComposableLambdaParameterNaming", "ComposableLambdaParameterPosition")
@@ -95,8 +96,10 @@
     thumbContent: (@Composable () -> Unit)? = null,
     enabled: Boolean = true,
     colors: SwitchColors = SwitchDefaults.colors(),
-    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
+    interactionSource: MutableInteractionSource? = null,
 ) {
+    @Suppress("NAME_SHADOWING")
+    val interactionSource = interactionSource ?: remember { MutableInteractionSource() }
     val uncheckedThumbDiameter = if (thumbContent == null) {
         UncheckedThumbDiameter
     } else {
diff --git a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Tab.kt b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Tab.kt
index 6e72956..727b98f 100644
--- a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Tab.kt
+++ b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Tab.kt
@@ -37,7 +37,6 @@
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.CompositionLocalProvider
 import androidx.compose.runtime.getValue
-import androidx.compose.runtime.remember
 import androidx.compose.ui.Alignment
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.graphics.Color
@@ -82,9 +81,10 @@
  * @param selectedContentColor the color for the content of this tab when selected, and the color
  * of the ripple.
  * @param unselectedContentColor the color for the content of this tab when not selected
- * @param interactionSource the [MutableInteractionSource] representing the stream of [Interaction]s
- * for this tab. You can create and pass in your own `remember`ed instance to observe [Interaction]s
- * and customize the appearance / behavior of this tab in different states.
+ * @param interactionSource an optional hoisted [MutableInteractionSource] for observing and
+ * emitting [Interaction]s for this tab. You can use this to change the tab's
+ * appearance or preview the tab in different states. Note that if `null` is provided,
+ * interactions will still happen internally.
  *
  * @see LeadingIconTab
  */
@@ -98,7 +98,7 @@
     icon: @Composable (() -> Unit)? = null,
     selectedContentColor: Color = LocalContentColor.current,
     unselectedContentColor: Color = selectedContentColor,
-    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() }
+    interactionSource: MutableInteractionSource? = null
 ) {
     val styledText: @Composable (() -> Unit)? = text?.let {
         @Composable {
@@ -144,9 +144,10 @@
  * @param selectedContentColor the color for the content of this tab when selected, and the color
  * of the ripple.
  * @param unselectedContentColor the color for the content of this tab when not selected
- * @param interactionSource the [MutableInteractionSource] representing the stream of [Interaction]s
- * for this tab. You can create and pass in your own `remember`ed instance to observe [Interaction]s
- * and customize the appearance / behavior of this tab in different states.
+ * @param interactionSource an optional hoisted [MutableInteractionSource] for observing and
+ * emitting [Interaction]s for this tab. You can use this to change the tab's
+ * appearance or preview the tab in different states. Note that if `null` is provided,
+ * interactions will still happen internally.
  *
  * @see Tab
  */
@@ -160,7 +161,7 @@
     enabled: Boolean = true,
     selectedContentColor: Color = LocalContentColor.current,
     unselectedContentColor: Color = selectedContentColor,
-    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() }
+    interactionSource: MutableInteractionSource? = null
 ) {
     // The color of the Ripple should always the be selected color, as we want to show the color
     // before the item is considered selected, and hence before the new contentColor is
@@ -217,9 +218,10 @@
  * @param selectedContentColor the color for the content of this tab when selected, and the color
  * of the ripple.
  * @param unselectedContentColor the color for the content of this tab when not selected
- * @param interactionSource the [MutableInteractionSource] representing the stream of [Interaction]s
- * for this tab. You can create and pass in your own `remember`ed instance to observe [Interaction]s
- * and customize the appearance / behavior of this tab in different states.
+ * @param interactionSource an optional hoisted [MutableInteractionSource] for observing and
+ * emitting [Interaction]s for this tab. You can use this to change the tab's
+ * appearance or preview the tab in different states. Note that if `null` is provided,
+ * interactions will still happen internally.
  * @param content the content of this tab
  */
 @Composable
@@ -230,7 +232,7 @@
     enabled: Boolean = true,
     selectedContentColor: Color = LocalContentColor.current,
     unselectedContentColor: Color = selectedContentColor,
-    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
+    interactionSource: MutableInteractionSource? = null,
     content: @Composable ColumnScope.() -> Unit
 ) {
     // The color of the Ripple should always the selected color, as we want to show the color
diff --git a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/TabRow.kt b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/TabRow.kt
index a251a76..94d8ed7 100644
--- a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/TabRow.kt
+++ b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/TabRow.kt
@@ -67,6 +67,7 @@
 import androidx.compose.ui.unit.Constraints
 import androidx.compose.ui.unit.Density
 import androidx.compose.ui.unit.Dp
+import androidx.compose.ui.unit.IntOffset
 import androidx.compose.ui.unit.dp
 import androidx.compose.ui.util.fastFold
 import androidx.compose.ui.util.fastForEach
@@ -1142,7 +1143,7 @@
         )
         fillMaxWidth()
             .wrapContentSize(Alignment.BottomStart)
-            .offset(x = indicatorOffset)
+            .offset { IntOffset(x = indicatorOffset.roundToPx(), y = 0) }
             .width(currentTabWidth)
     }
 }
diff --git a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/TextField.kt b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/TextField.kt
index 3781c5e..ef2be6c 100644
--- a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/TextField.kt
+++ b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/TextField.kt
@@ -157,9 +157,10 @@
  * that 1 <= [minLines] <= [maxLines]. This parameter is ignored when [singleLine] is true.
  * @param minLines the minimum height in terms of minimum number of visible lines. It is required
  * that 1 <= [minLines] <= [maxLines]. This parameter is ignored when [singleLine] is true.
- * @param interactionSource the [MutableInteractionSource] representing the stream of [Interaction]s
- * for this text field. You can create and pass in your own `remember`ed instance to observe
- * [Interaction]s and customize the appearance / behavior of this text field in different states.
+ * @param interactionSource an optional hoisted [MutableInteractionSource] for observing and
+ * emitting [Interaction]s for this text field. You can use this to change the text field's
+ * appearance or preview the text field in different states. Note that if `null` is provided,
+ * interactions will still happen internally.
  * @param shape defines the shape of this text field's container
  * @param colors [TextFieldColors] that will be used to resolve the colors used for this text field
  * in different states. See [TextFieldDefaults.colors].
@@ -187,10 +188,12 @@
     singleLine: Boolean = false,
     maxLines: Int = if (singleLine) 1 else Int.MAX_VALUE,
     minLines: Int = 1,
-    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
+    interactionSource: MutableInteractionSource? = null,
     shape: Shape = TextFieldDefaults.shape,
     colors: TextFieldColors = TextFieldDefaults.colors()
 ) {
+    @Suppress("NAME_SHADOWING")
+    val interactionSource = interactionSource ?: remember { MutableInteractionSource() }
     // If color is not provided via the text style, use content color as a default
     val textColor = textStyle.color.takeOrElse {
         colors.textColor(enabled, isError, interactionSource).value
@@ -303,9 +306,10 @@
  * that 1 <= [minLines] <= [maxLines]. This parameter is ignored when [singleLine] is true.
  * @param minLines the minimum height in terms of minimum number of visible lines. It is required
  * that 1 <= [minLines] <= [maxLines]. This parameter is ignored when [singleLine] is true.
- * @param interactionSource the [MutableInteractionSource] representing the stream of [Interaction]s
- * for this text field. You can create and pass in your own `remember`ed instance to observe
- * [Interaction]s and customize the appearance / behavior of this text field in different states.
+ * @param interactionSource an optional hoisted [MutableInteractionSource] for observing and
+ * emitting [Interaction]s for this text field. You can use this to change the text field's
+ * appearance or preview the text field in different states. Note that if `null` is provided,
+ * interactions will still happen internally.
  * @param shape defines the shape of this text field's container
  * @param colors [TextFieldColors] that will be used to resolve the colors used for this text field
  * in different states. See [TextFieldDefaults.colors].
@@ -333,10 +337,12 @@
     singleLine: Boolean = false,
     maxLines: Int = if (singleLine) 1 else Int.MAX_VALUE,
     minLines: Int = 1,
-    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
+    interactionSource: MutableInteractionSource? = null,
     shape: Shape = TextFieldDefaults.shape,
     colors: TextFieldColors = TextFieldDefaults.colors()
 ) {
+    @Suppress("NAME_SHADOWING")
+    val interactionSource = interactionSource ?: remember { MutableInteractionSource() }
     // If color is not provided via the text style, use content color as a default
     val textColor = textStyle.color.takeOrElse {
         colors.textColor(enabled, isError, interactionSource).value
diff --git a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/carousel/Arrangement.kt b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/carousel/Arrangement.kt
index 342854cc..5a46dae 100644
--- a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/carousel/Arrangement.kt
+++ b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/carousel/Arrangement.kt
@@ -16,7 +16,6 @@
 
 package androidx.compose.material3.carousel
 
-import androidx.annotation.FloatRange
 import kotlin.math.abs
 import kotlin.math.max
 import kotlin.math.min
@@ -29,11 +28,11 @@
 internal class Arrangement(
     private val priority: Int,
     val smallSize: Float,
-    private val smallCount: Int,
+    val smallCount: Int,
     val mediumSize: Float,
-    private val mediumCount: Int,
+    val mediumCount: Int,
     val largeSize: Float,
-    private val largeCount: Int
+    val largeCount: Int
 ) {
 
     private fun isValid(): Boolean {
@@ -79,7 +78,8 @@
          *
          * @param availableSpace the space the arrangement needs to fit
          * @param targetSmallSize the size small items would like to be
-         * @param smallSizeRange the range of which small item sizes are allowed to be
+         * @param minSmallSize the minimum size of which small item sizes are allowed to be
+         * @param maxSmallSize the maximum size of which small item sizes are allowed to be
          * @param smallCounts an array of small item counts for a valid arrangement ordered by
          * priority
          * @param targetMediumSize the size medium items would like to be
@@ -94,7 +94,8 @@
         fun findLowestCostArrangement(
             availableSpace: Float,
             targetSmallSize: Float,
-            smallSizeRange: FloatRange,
+            minSmallSize: Float,
+            maxSmallSize: Float,
             smallCounts: IntArray,
             targetMediumSize: Float,
             mediumCounts: IntArray,
@@ -111,7 +112,8 @@
                             availableSpace = availableSpace,
                             smallCount = smallCount,
                             smallSize = targetSmallSize,
-                            smallSizeRange = smallSizeRange,
+                            minSmallSize = minSmallSize,
+                            maxSmallSize = maxSmallSize,
                             mediumCount = mediumCount,
                             mediumSize = targetMediumSize,
                             largeCount = largeCount,
@@ -150,6 +152,8 @@
          * @param availableSpace The space in which to fit the arrangement
          * @param smallCount the number of small items to fit
          * @param smallSize the size of each small item
+         * @param minSmallSize the minimum size a small item is allowed to be
+         * @param maxSmallSize the maximum size a small item is allowed to be
          * @param mediumCount the number of medium items to fit
          * @param mediumSize the size of each medium item
          * @param largeCount the number of large items to fit
@@ -161,15 +165,16 @@
             availableSpace: Float,
             smallCount: Int,
             smallSize: Float,
-            smallSizeRange: FloatRange,
+            minSmallSize: Float,
+            maxSmallSize: Float,
             mediumCount: Int,
             mediumSize: Float,
             largeCount: Int,
             largeSize: Float
         ): Arrangement {
             var arrangedSmallSize = smallSize.coerceIn(
-                smallSizeRange.from.toFloat(),
-                smallSizeRange.to.toFloat()
+                minSmallSize,
+                maxSmallSize
             )
             var arrangedMediumSize = mediumSize
             var arrangedLargeSize = largeSize
@@ -183,13 +188,13 @@
                 // grow the small items
                 arrangedSmallSize += min(
                     delta / smallCount,
-                    smallSizeRange.to.toFloat() - arrangedSmallSize
+                    maxSmallSize - arrangedSmallSize
                 )
             } else if (smallCount > 0 && delta < 0) {
                 // shrink the small items
                 arrangedSmallSize += max(
                     delta / smallCount,
-                    smallSizeRange.from.toFloat() - arrangedSmallSize
+                    minSmallSize - arrangedSmallSize
                 )
             }
 
diff --git a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/carousel/Carousel.kt b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/carousel/Carousel.kt
index 8500938..dd2f455 100644
--- a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/carousel/Carousel.kt
+++ b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/carousel/Carousel.kt
@@ -16,9 +16,14 @@
 
 package androidx.compose.material3.carousel
 
-import androidx.compose.foundation.gestures.Orientation
+import androidx.compose.foundation.ExperimentalFoundationApi
+import androidx.compose.foundation.pager.HorizontalPager
+import androidx.compose.foundation.pager.PageSize
+import androidx.compose.foundation.pager.VerticalPager
 import androidx.compose.foundation.shape.RoundedCornerShape
+import androidx.compose.material3.ExperimentalMaterial3Api
 import androidx.compose.material3.ShapeDefaults
+import androidx.compose.runtime.Composable
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.geometry.CornerRadius
 import androidx.compose.ui.geometry.Rect
@@ -46,6 +51,16 @@
 }
 
 /**
+ * An enumeration of orientations that determine a carousel's main axis
+ */
+internal enum class Orientation {
+    /** Vertical orientation representing Y axis */
+    Vertical,
+    /** Horizontal orientation representing X axis */
+    Horizontal
+}
+
+/**
  * A modifier that handles clipping and translating an item as it moves along the scrolling axis
  * of a Carousel.
  *
@@ -188,3 +203,101 @@
     val total = after.unadjustedOffset - before.unadjustedOffset
     return (unadjustedOffset - before.unadjustedOffset) / total
 }
+
+/**
+ * <a href=https://m3.material.io/components/carousel/overview" class="external" target="_blank">Material Design Carousel</a>
+ *
+ * A Carousel that scrolls horizontally. Carousels contain a collection of items that changes sizes
+ * according to their placement and the chosen strategy.
+ *
+ * @param state The state object to be used to control the carousel's state.
+ * @param modifier A modifier instance to be applied to this carousel outer layout
+ * @param content The carousel's content Composable.
+ * TODO: Add sample link
+ */
+@ExperimentalMaterial3Api
+@Composable
+internal fun HorizontalCarousel(
+    state: CarouselState,
+    modifier: Modifier = Modifier,
+    content: @Composable CarouselScope.(item: Int) -> Unit
+) = Carousel(
+        state = state,
+        modifier = modifier,
+        orientation = Orientation.Horizontal,
+        content = content
+)
+
+/**
+ * <a href=https://m3.material.io/components/carousel/overview" class="external" target="_blank">Material Design Carousel</a>
+ *
+ * A Carousel that scrolls vertically. Carousels contain a collection of items that changes sizes
+ * according to their placement and the chosen strategy.
+ *
+ * @param state The state object to be used to control the carousel's state.
+ * @param modifier A modifier instance to be applied to this carousel outer layout
+ * @param content The carousel's content Composable.
+ * TODO: Add sample link
+ */
+@ExperimentalMaterial3Api
+@Composable
+internal fun VerticalCarousel(
+    state: CarouselState,
+    modifier: Modifier = Modifier,
+    content: @Composable CarouselScope.(item: Int) -> Unit
+) = Carousel(
+        state = state,
+        modifier = modifier,
+        orientation = Orientation.Vertical,
+        content = content
+)
+
+/**
+ * <a href=https://m3.material.io/components/carousel/overview" class="external" target="_blank">Material Design Carousel</a>
+ *
+ * Carousels contain a collection of items that changes sizes according to their placement and the
+ * chosen strategy.
+ *
+ * @param state The state object to be used to control the carousel's state.
+ * @param modifier A modifier instance to be applied to this carousel outer layout
+ * @param orientation The layout orientation of the carousel
+ * @param content The carousel's content Composable.
+ * TODO: Add sample link
+ */
+// TODO: b/321997456 - Remove lint suppression once version checks are added in lint or library
+// moves to beta
+@Suppress("IllegalExperimentalApiUsage")
+@OptIn(ExperimentalFoundationApi::class)
+@ExperimentalMaterial3Api
+@Composable
+internal fun Carousel(
+    state: CarouselState,
+    modifier: Modifier = Modifier,
+    orientation: Orientation = Orientation.Horizontal,
+    content: @Composable CarouselScope.(item: Int) -> Unit
+) {
+    // TODO: Update page size according to strategy
+    val pageSize = PageSize.Fill
+    // TODO: Update out of bounds page count numbers
+    val outOfBoundsPageCount = 1
+    val carouselScope = CarouselScopeImpl
+    if (orientation == Orientation.Horizontal) {
+        HorizontalPager(
+            state = state.pagerState,
+            pageSize = pageSize,
+            outOfBoundsPageCount = outOfBoundsPageCount,
+            modifier = modifier
+        ) { page ->
+            carouselScope.content(page)
+        }
+    } else if (orientation == Orientation.Vertical) {
+        VerticalPager(
+            state = state.pagerState,
+            pageSize = pageSize,
+            outOfBoundsPageCount = outOfBoundsPageCount,
+            modifier = modifier
+        ) { page ->
+            carouselScope.content(page)
+        }
+    }
+}
diff --git a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/carousel/CarouselScope.kt b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/carousel/CarouselScope.kt
new file mode 100644
index 0000000..94dbda2
--- /dev/null
+++ b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/carousel/CarouselScope.kt
@@ -0,0 +1,28 @@
+/*
+ * 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.compose.material3.carousel
+
+import androidx.compose.material3.ExperimentalMaterial3Api
+
+/**
+ * Receiver scope for [Carousel].
+ */
+@ExperimentalMaterial3Api
+internal sealed interface CarouselScope
+
+@ExperimentalMaterial3Api
+internal object CarouselScopeImpl : CarouselScope
diff --git a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/carousel/CarouselState.kt b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/carousel/CarouselState.kt
new file mode 100644
index 0000000..e48ec30
--- /dev/null
+++ b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/carousel/CarouselState.kt
@@ -0,0 +1,111 @@
+/*
+ * 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.compose.material3.carousel
+
+import androidx.compose.foundation.ExperimentalFoundationApi
+import androidx.compose.foundation.MutatePriority
+import androidx.compose.foundation.gestures.ScrollScope
+import androidx.compose.foundation.gestures.ScrollableState
+import androidx.compose.foundation.pager.PagerState
+import androidx.compose.material3.ExperimentalMaterial3Api
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.saveable.Saver
+import androidx.compose.runtime.saveable.listSaver
+import androidx.compose.runtime.saveable.rememberSaveable
+
+/**
+ * The state that can be used to control [VerticalCarousel] and [HorizontalCarousel].
+ *
+ * @param currentItem the current item to be scrolled to.
+ * @param currentItemOffsetFraction the current item offset as a fraction of the item size.
+ * @param itemCount the number of items this Carousel will have.
+ */
+// TODO: b/321997456 - Remove lint suppression once version checks are added in lint or library
+// moves to beta
+@Suppress("IllegalExperimentalApiUsage")
+@OptIn(ExperimentalFoundationApi::class)
+@ExperimentalMaterial3Api
+internal class CarouselState(
+    currentItem: Int = 0,
+    currentItemOffsetFraction: Float = 0F,
+    itemCount: () -> Int
+) : ScrollableState {
+    var itemCountState = mutableStateOf(itemCount)
+
+    internal var pagerState: PagerState = PagerState(currentItem, currentItemOffsetFraction,
+        itemCountState.value)
+
+    override val isScrollInProgress: Boolean
+        get() = pagerState.isScrollInProgress
+
+    override fun dispatchRawDelta(delta: Float): Float {
+        return pagerState.dispatchRawDelta(delta)
+    }
+
+    override suspend fun scroll(
+        scrollPriority: MutatePriority,
+        block: suspend ScrollScope.() -> Unit
+    ) {
+        pagerState.scroll(scrollPriority, block)
+    }
+
+    companion object {
+        /**
+         * To keep current item and item offset saved
+         */
+        val Saver: Saver<CarouselState, *> = listSaver(
+            save = {
+                listOf(
+                    it.pagerState.currentPage,
+                    it.pagerState.currentPageOffsetFraction,
+                    it.pagerState.pageCount,
+                )
+            },
+            restore = {
+                CarouselState(
+                    currentItem = it[0] as Int,
+                    currentItemOffsetFraction = it[1] as Float,
+                    itemCount = { it[2] as Int },
+                )
+            }
+        )
+    }
+}
+
+/**
+ * Creates a [CarouselState] that is remembered across compositions.
+ *
+ * @param initialItem The initial item that should be scrolled to.
+ * @param itemCount The number of items this Carousel will have.
+ */
+@ExperimentalMaterial3Api
+@Composable
+internal fun rememberCarouselState(
+    initialItem: Int = 0,
+    itemCount: () -> Int,
+): CarouselState {
+    return rememberSaveable(saver = CarouselState.Saver) {
+        CarouselState(
+            currentItem = initialItem,
+            currentItemOffsetFraction = 0F,
+            itemCount = itemCount
+        )
+    }.apply {
+        itemCountState.value = itemCount
+    }
+}
diff --git a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/carousel/MultiBrowseStrategyProvider.kt b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/carousel/MultiBrowseStrategyProvider.kt
new file mode 100644
index 0000000..f8d4db6
--- /dev/null
+++ b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/carousel/MultiBrowseStrategyProvider.kt
@@ -0,0 +1,108 @@
+/*
+ * 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.compose.material3.carousel
+
+import androidx.compose.ui.unit.Density
+import androidx.compose.ui.unit.Dp
+import androidx.compose.ui.unit.dp
+import kotlin.math.ceil
+import kotlin.math.floor
+import kotlin.math.max
+import kotlin.math.min
+
+/**
+ * A [StrategyProvider] that provides the multi-browse strategy, which fits large, medium, and small
+ * items into a layout for quick browsing of multiple items at once.
+ *
+ * Note that this strategy may adjust the size of large items. In order to ensure large, medium,
+ * and small items fit perfectly into the available space and are numbered/arranged in a
+ * visually pleasing and opinionated way, this strategy finds the nearest number of large items that
+ * will fit into an approved arrangement that requires the least amount of size adjustment
+ * necessary.
+ *
+ * For more information, see <a href="https://material.io/components/carousel/overview">design
+ * guidelines</a>.
+ */
+internal class MultiBrowseStrategyProvider(
+    private val targetLargeItemMainAxisSize: Dp,
+    private val minSmallSize: Dp = StrategyDefaults.minSmallSize,
+    private val maxSmallSize: Dp = StrategyDefaults.maxSmallSize
+) :
+    StrategyProvider() {
+
+    override fun createStrategy(
+        density: Density,
+        carouselMainAxisSize: Float,
+        itemSpacing: Int,
+    ): Strategy? {
+        if (carouselMainAxisSize == 0f || targetLargeItemMainAxisSize == 0.dp) {
+            return null
+        }
+
+        val targetLargeItemSize = with(density) { targetLargeItemMainAxisSize.toPx() }
+        val minSmallItemSize = with(density) { minSmallSize.toPx() }
+        val maxSmallItemSize = with(density) { maxSmallSize.toPx() }
+        var smallCounts: IntArray = intArrayOf(1)
+        val mediumCounts: IntArray = intArrayOf(1, 0)
+
+        val targetLargeSize: Float = min(targetLargeItemSize + itemSpacing, carouselMainAxisSize)
+        // Ideally we would like to create a balanced arrangement where a small item is 1/3 the size
+        // of the large item and medium items are sized between large and small items. Clamp the
+        // small target size within our min-max range and as close to 1/3 of the target large item
+        // size as possible.
+        val targetSmallSize: Float = (targetLargeItemSize / 3f + itemSpacing).coerceIn(
+            minSmallItemSize + itemSpacing,
+            maxSmallItemSize + itemSpacing
+        )
+        val targetMediumSize = (targetLargeSize + targetSmallSize) / 2f
+
+        if (carouselMainAxisSize < minSmallItemSize * 2) {
+            // If the available space is too small to fit a large item and small item (where a large
+            // item is bigger than a small item), allow arrangements with
+            // no small items.
+            smallCounts = intArrayOf(0)
+        }
+
+        // Find the minimum space left for large items after filling the carousel with the most
+        // permissible medium and small items to determine a plausible minimum large count.
+        val minAvailableLargeSpace = carouselMainAxisSize - targetMediumSize * mediumCounts.max() -
+            maxSmallItemSize * smallCounts.max()
+        val minLargeCount = max(
+            1,
+            floor(minAvailableLargeSpace / targetLargeSize).toInt())
+        val maxLargeCount = ceil(carouselMainAxisSize / targetLargeSize).toInt()
+
+        val largeCounts = IntArray(maxLargeCount - minLargeCount + 1) { maxLargeCount - it }
+        val arrangement = Arrangement.findLowestCostArrangement(
+            availableSpace = carouselMainAxisSize,
+            targetSmallSize = targetSmallSize,
+            minSmallSize = minSmallItemSize,
+            maxSmallSize = maxSmallItemSize,
+            smallCounts = smallCounts,
+            targetMediumSize = targetMediumSize,
+            mediumCounts = mediumCounts,
+            targetLargeSize = targetLargeSize,
+            largeCounts = largeCounts,
+        ) ?: return null
+
+        return createStartAlignedStrategy(
+            availableSpace = carouselMainAxisSize,
+            arrangement = arrangement,
+            anchorSize = with(density) { StrategyDefaults.anchorSize.toPx() }
+        )
+    }
+}
diff --git a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/carousel/Strategy.kt b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/carousel/Strategy.kt
index 4febab9..fda1167 100644
--- a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/carousel/Strategy.kt
+++ b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/carousel/Strategy.kt
@@ -16,33 +16,73 @@
 
 package androidx.compose.material3.carousel
 
+import androidx.annotation.VisibleForTesting
 import androidx.collection.FloatList
 import androidx.collection.mutableFloatListOf
 import androidx.compose.ui.unit.Density
+import androidx.compose.ui.unit.dp
 import androidx.compose.ui.util.fastForEach
 import androidx.compose.ui.util.lerp
 import kotlin.math.roundToInt
 
 /**
- * An interface which provides [Strategy] instances to a scrollable component.
+ * Contains default values used across Strategies
+ */
+internal object StrategyDefaults {
+    val minSmallSize = 40.dp
+    val maxSmallSize = 56.dp
+    val anchorSize = 10.dp
+}
+
+/**
+ * Helper method to create a default start-aligned [Strategy] contained within the bounds of
+ * [availableSpace] and based on the given [Arrangement].
+ *
+ * @param availableSpace the available space to contain the [Strategy] within
+ * @param arrangement the arrangement containing information on the sizes and counts of the
+ * items in the [Strategy].
+ * @param anchorSize the size that the anchor keylines should be in the strategy. The smaller
+ * this is, the more the item will shrink as it moves off-screen.
+ */
+internal fun createStartAlignedStrategy(
+    availableSpace: Float,
+    arrangement: Arrangement,
+    anchorSize: Float,
+): Strategy {
+    val keylineList = keylineListOf(availableSpace, CarouselAlignment.Start) {
+        add(anchorSize, isAnchor = true)
+
+        repeat(arrangement.largeCount) { add(arrangement.largeSize) }
+        repeat(arrangement.mediumCount) { add(arrangement.mediumSize) }
+        repeat(arrangement.smallCount) { add(arrangement.smallSize) }
+
+        add(anchorSize, isAnchor = true)
+    }
+
+    return Strategy.create(availableSpace, keylineList)
+}
+
+/**
+ * A class that provides [Strategy] instances to a scrollable component.
  *
  * [StrategyProvider.createStrategy] will be called any time properties which affect a carousel's
  * arrangement change. It is the implementation's responsibility to create an arrangement for the
  * given parameters and return a [Strategy] by calling [Strategy.create].
  */
-internal interface StrategyProvider {
+internal sealed class StrategyProvider() {
+
     /**
      * Create and return a new [Strategy] for the given carousel size.
      *
-     * TODO: Add additional parameters like alignment and item count.
-     *
-     * @param density The [Density] object that provides pixel density information of the device
+     * @param density The current density value
      * @param carouselMainAxisSize the size of the carousel in the main axis in pixels
+     * @param itemSpacing The spacing in between the items that are not a part of the item size
      */
-    fun createStrategy(
+    internal abstract fun createStrategy(
         density: Density,
         carouselMainAxisSize: Float,
-    ): Strategy
+        itemSpacing: Int,
+    ): Strategy?
 }
 
 /**
@@ -152,6 +192,11 @@
         )
     }
 
+    @VisibleForTesting
+    internal fun getDefaultKeylines(): KeylineList {
+        return defaultKeylines
+    }
+
     companion object {
 
         /**
diff --git a/compose/runtime/runtime-saveable/src/commonMain/kotlin/androidx/compose/runtime/saveable/SaveableStateRegistry.kt b/compose/runtime/runtime-saveable/src/commonMain/kotlin/androidx/compose/runtime/saveable/SaveableStateRegistry.kt
index 91c4c1d..5390e11 100644
--- a/compose/runtime/runtime-saveable/src/commonMain/kotlin/androidx/compose/runtime/saveable/SaveableStateRegistry.kt
+++ b/compose/runtime/runtime-saveable/src/commonMain/kotlin/androidx/compose/runtime/saveable/SaveableStateRegistry.kt
@@ -90,6 +90,18 @@
  */
 val LocalSaveableStateRegistry = staticCompositionLocalOf<SaveableStateRegistry?> { null }
 
+// CharSequence.isBlank() allocates an iterator because it calls indices.all{}
+private fun CharSequence.fastIsBlank(): Boolean {
+    var blank = true
+    for (i in 0 until length - 1) {
+        if (!this[i].isWhitespace()) {
+            blank = false
+            break
+        }
+    }
+    return blank
+}
+
 private class SaveableStateRegistryImpl(
     restored: Map<String, List<Any?>>?,
     private val canBeSaved: (Any) -> Boolean
@@ -114,7 +126,7 @@
     }
 
     override fun registerProvider(key: String, valueProvider: () -> Any?): Entry {
-        require(key.isNotBlank()) { "Registered key is empty or blank" }
+        require(!key.fastIsBlank()) { "Registered key is empty or blank" }
         @Suppress("UNCHECKED_CAST")
         valueProviders.getOrPut(key) { mutableListOf() }.add(valueProvider)
         return object : Entry {
diff --git a/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/snapshots/SnapshotIdSet.kt b/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/snapshots/SnapshotIdSet.kt
index 0d64142..98c5c29 100644
--- a/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/snapshots/SnapshotIdSet.kt
+++ b/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/snapshots/SnapshotIdSet.kt
@@ -233,7 +233,7 @@
                 this.belowBound
             )
         } else {
-            bits.fold(this) { previous, index -> previous.clear(index) }
+            bits.fastFold(this) { previous, index -> previous.clear(index) }
         }
     }
 
@@ -254,11 +254,11 @@
                 )
         } else {
             if (this.belowBound == null)
-                this.fold(EMPTY) { previous, index ->
+                this.fastFold(EMPTY) { previous, index ->
                     if (bits.get(index)) previous.set(index) else previous
                 }
             else
-                bits.fold(EMPTY) { previous, index ->
+                bits.fastFold(EMPTY) { previous, index ->
                     if (this.get(index)) previous.set(index) else previous
                 }
         }
@@ -280,10 +280,10 @@
         } else {
             if (this.belowBound == null) {
                 // We are probably smaller than bits, or at least, small enough
-                this.fold(bits) { previous, index -> previous.set(index) }
+                this.fastFold(bits) { previous, index -> previous.set(index) }
             } else {
                 // Otherwise assume bits is smaller than this.
-                bits.fold(this) { previous, index -> previous.set(index) }
+                bits.fastFold(this) { previous, index -> previous.set(index) }
             }
         }
     }
@@ -310,6 +310,17 @@
         }
     }.iterator()
 
+    inline fun fastFold(
+        initial: SnapshotIdSet,
+        operation: (acc: SnapshotIdSet, Int) -> SnapshotIdSet
+    ): SnapshotIdSet {
+        var accumulator = initial
+        fastForEach { element ->
+            accumulator = operation(accumulator, element)
+        }
+        return accumulator
+    }
+
     inline fun fastForEach(block: (Int) -> Unit) {
         val belowBound = belowBound
         if (belowBound != null)
@@ -335,8 +346,8 @@
     fun lowest(default: Int): Int {
         val belowBound = belowBound
         if (belowBound != null) return belowBound[0]
-        if (lowerSet != 0L) return lowerBound + lowestBitOf(lowerSet)
-        if (upperSet != 0L) return lowerBound + Long.SIZE_BITS + lowestBitOf(upperSet)
+        if (lowerSet != 0L) return lowerBound + lowerSet.countTrailingZeroBits()
+        if (upperSet != 0L) return lowerBound + Long.SIZE_BITS + upperSet.countTrailingZeroBits()
         return default
     }
 
@@ -352,32 +363,6 @@
     }
 }
 
-private fun lowestBitOf(bits: Long): Int {
-    var b = bits
-    var base = 0
-    if (b and 0xFFFF_FFFFL == 0L) {
-        base += 32
-        b = b shr 32
-    }
-    if (b and 0xFFFF == 0L) {
-        base += 16
-        b = b shr 16
-    }
-    if (b and 0xFF == 0L) {
-        base += 8
-        b = b shr 8
-    }
-    if (b and 0xF == 0L) {
-        base += 4
-        b = b shr 4
-    }
-    if (b and 0x1 != 0L) return base
-    if (b and 0x2 != 0L) return base + 1
-    if (b and 0x4 != 0L) return base + 2
-    if (b and 0x8 != 0L) return base + 3
-    return -1
-}
-
 internal fun IntArray.binarySearch(value: Int): Int {
     var low = 0
     var high = size - 1
diff --git a/compose/ui/ui/api/current.txt b/compose/ui/ui/api/current.txt
index 8f2b676..ea780c4 100644
--- a/compose/ui/ui/api/current.txt
+++ b/compose/ui/ui/api/current.txt
@@ -3311,6 +3311,7 @@
     method public <T> void set(androidx.compose.ui.semantics.SemanticsPropertyKey<T> key, T value);
     method public void setClearingSemantics(boolean);
     method public void setMergingSemanticsOfDescendants(boolean);
+    method @SuppressCompatibility @androidx.compose.ui.ExperimentalComposeUiApi public <T> void unset(androidx.compose.ui.semantics.SemanticsPropertyKey<T> key);
     property public final boolean isClearingSemantics;
     property public final boolean isMergingSemanticsOfDescendants;
   }
@@ -3393,6 +3394,7 @@
     method public androidx.compose.ui.semantics.SemanticsPropertyKey<kotlin.Unit> getInvisibleToUser();
     method @Deprecated public androidx.compose.ui.semantics.SemanticsPropertyKey<java.lang.Boolean> getIsContainer();
     method public androidx.compose.ui.semantics.SemanticsPropertyKey<kotlin.Unit> getIsDialog();
+    method public androidx.compose.ui.semantics.SemanticsPropertyKey<kotlin.Unit> getIsOpaque();
     method public androidx.compose.ui.semantics.SemanticsPropertyKey<kotlin.Unit> getIsPopup();
     method public androidx.compose.ui.semantics.SemanticsPropertyKey<java.lang.Boolean> getIsShowingTextSubstitution();
     method public androidx.compose.ui.semantics.SemanticsPropertyKey<java.lang.Boolean> getIsTraversalGroup();
@@ -3426,6 +3428,7 @@
     property public final androidx.compose.ui.semantics.SemanticsPropertyKey<kotlin.Unit> InvisibleToUser;
     property @Deprecated public final androidx.compose.ui.semantics.SemanticsPropertyKey<java.lang.Boolean> IsContainer;
     property public final androidx.compose.ui.semantics.SemanticsPropertyKey<kotlin.Unit> IsDialog;
+    property public final androidx.compose.ui.semantics.SemanticsPropertyKey<kotlin.Unit> IsOpaque;
     property public final androidx.compose.ui.semantics.SemanticsPropertyKey<kotlin.Unit> IsPopup;
     property public final androidx.compose.ui.semantics.SemanticsPropertyKey<java.lang.Boolean> IsShowingTextSubstitution;
     property public final androidx.compose.ui.semantics.SemanticsPropertyKey<java.lang.Boolean> IsTraversalGroup;
@@ -3491,6 +3494,7 @@
     method public static void insertTextAtCursor(androidx.compose.ui.semantics.SemanticsPropertyReceiver, optional String? label, kotlin.jvm.functions.Function1<? super androidx.compose.ui.text.AnnotatedString,java.lang.Boolean>? action);
     method @SuppressCompatibility @androidx.compose.ui.ExperimentalComposeUiApi public static void invisibleToUser(androidx.compose.ui.semantics.SemanticsPropertyReceiver);
     method @Deprecated public static boolean isContainer(androidx.compose.ui.semantics.SemanticsPropertyReceiver);
+    method public static void isOpaque(androidx.compose.ui.semantics.SemanticsPropertyReceiver);
     method public static boolean isShowingTextSubstitution(androidx.compose.ui.semantics.SemanticsPropertyReceiver);
     method public static boolean isTraversalGroup(androidx.compose.ui.semantics.SemanticsPropertyReceiver);
     method public static void onClick(androidx.compose.ui.semantics.SemanticsPropertyReceiver, optional String? label, kotlin.jvm.functions.Function0<java.lang.Boolean>? action);
@@ -3554,6 +3558,7 @@
 
   public interface SemanticsPropertyReceiver {
     method public operator <T> void set(androidx.compose.ui.semantics.SemanticsPropertyKey<T> key, T value);
+    method @SuppressCompatibility @androidx.compose.ui.ExperimentalComposeUiApi public <T> void unset(androidx.compose.ui.semantics.SemanticsPropertyKey<T> key);
   }
 
 }
diff --git a/compose/ui/ui/api/restricted_current.txt b/compose/ui/ui/api/restricted_current.txt
index b7c980e..d9d8a86 100644
--- a/compose/ui/ui/api/restricted_current.txt
+++ b/compose/ui/ui/api/restricted_current.txt
@@ -3371,6 +3371,7 @@
     method public <T> void set(androidx.compose.ui.semantics.SemanticsPropertyKey<T> key, T value);
     method public void setClearingSemantics(boolean);
     method public void setMergingSemanticsOfDescendants(boolean);
+    method @SuppressCompatibility @androidx.compose.ui.ExperimentalComposeUiApi public <T> void unset(androidx.compose.ui.semantics.SemanticsPropertyKey<T> key);
     property public final boolean isClearingSemantics;
     property public final boolean isMergingSemanticsOfDescendants;
   }
@@ -3453,6 +3454,7 @@
     method public androidx.compose.ui.semantics.SemanticsPropertyKey<kotlin.Unit> getInvisibleToUser();
     method @Deprecated public androidx.compose.ui.semantics.SemanticsPropertyKey<java.lang.Boolean> getIsContainer();
     method public androidx.compose.ui.semantics.SemanticsPropertyKey<kotlin.Unit> getIsDialog();
+    method public androidx.compose.ui.semantics.SemanticsPropertyKey<kotlin.Unit> getIsOpaque();
     method public androidx.compose.ui.semantics.SemanticsPropertyKey<kotlin.Unit> getIsPopup();
     method public androidx.compose.ui.semantics.SemanticsPropertyKey<java.lang.Boolean> getIsShowingTextSubstitution();
     method public androidx.compose.ui.semantics.SemanticsPropertyKey<java.lang.Boolean> getIsTraversalGroup();
@@ -3486,6 +3488,7 @@
     property public final androidx.compose.ui.semantics.SemanticsPropertyKey<kotlin.Unit> InvisibleToUser;
     property @Deprecated public final androidx.compose.ui.semantics.SemanticsPropertyKey<java.lang.Boolean> IsContainer;
     property public final androidx.compose.ui.semantics.SemanticsPropertyKey<kotlin.Unit> IsDialog;
+    property public final androidx.compose.ui.semantics.SemanticsPropertyKey<kotlin.Unit> IsOpaque;
     property public final androidx.compose.ui.semantics.SemanticsPropertyKey<kotlin.Unit> IsPopup;
     property public final androidx.compose.ui.semantics.SemanticsPropertyKey<java.lang.Boolean> IsShowingTextSubstitution;
     property public final androidx.compose.ui.semantics.SemanticsPropertyKey<java.lang.Boolean> IsTraversalGroup;
@@ -3551,6 +3554,7 @@
     method public static void insertTextAtCursor(androidx.compose.ui.semantics.SemanticsPropertyReceiver, optional String? label, kotlin.jvm.functions.Function1<? super androidx.compose.ui.text.AnnotatedString,java.lang.Boolean>? action);
     method @SuppressCompatibility @androidx.compose.ui.ExperimentalComposeUiApi public static void invisibleToUser(androidx.compose.ui.semantics.SemanticsPropertyReceiver);
     method @Deprecated public static boolean isContainer(androidx.compose.ui.semantics.SemanticsPropertyReceiver);
+    method public static void isOpaque(androidx.compose.ui.semantics.SemanticsPropertyReceiver);
     method public static boolean isShowingTextSubstitution(androidx.compose.ui.semantics.SemanticsPropertyReceiver);
     method public static boolean isTraversalGroup(androidx.compose.ui.semantics.SemanticsPropertyReceiver);
     method public static void onClick(androidx.compose.ui.semantics.SemanticsPropertyReceiver, optional String? label, kotlin.jvm.functions.Function0<java.lang.Boolean>? action);
@@ -3614,6 +3618,7 @@
 
   public interface SemanticsPropertyReceiver {
     method public operator <T> void set(androidx.compose.ui.semantics.SemanticsPropertyKey<T> key, T value);
+    method @SuppressCompatibility @androidx.compose.ui.ExperimentalComposeUiApi public <T> void unset(androidx.compose.ui.semantics.SemanticsPropertyKey<T> key);
   }
 
 }
diff --git a/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/AndroidAccessibilityTest.kt b/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/AndroidAccessibilityTest.kt
index fa909d3..e9f3640 100644
--- a/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/AndroidAccessibilityTest.kt
+++ b/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/AndroidAccessibilityTest.kt
@@ -137,6 +137,8 @@
 import androidx.compose.ui.semantics.contentDescription
 import androidx.compose.ui.semantics.getOrNull
 import androidx.compose.ui.semantics.invisibleToUser
+import androidx.compose.ui.semantics.isContainer
+import androidx.compose.ui.semantics.isOpaque
 import androidx.compose.ui.semantics.isTraversalGroup
 import androidx.compose.ui.semantics.paneTitle
 import androidx.compose.ui.semantics.role
@@ -3892,6 +3894,144 @@
         }
     }
 
+    @OptIn(ExperimentalComposeUiApi::class)
+    @Test
+    fun testSemanticsHitTest_unimportantTraversalProperties() {
+        // Arrange.
+        setContent {
+            Box(
+                Modifier
+                    .size(100.dp)
+                    .testTag(tag)
+                    .semantics { isTraversalGroup = true; traversalIndex = 1f }) {
+            }
+        }
+        val bounds = with(rule.density) { rule.onNodeWithTag(tag).getBoundsInRoot().toRect() }
+
+        // Act.
+        val hitNodeId = rule.runOnIdle {
+            delegate.hitTestSemanticsAt(
+                bounds.left + bounds.width / 2,
+                bounds.top + bounds.height / 2
+            )
+        }
+
+        // Assert it doesn't hit the tagged node since it only has unimportant properties.
+        rule.runOnIdle { assertThat(hitNodeId).isEqualTo(InvalidId) }
+    }
+
+    @Test
+    @OptIn(ExperimentalComposeUiApi::class)
+    @Suppress("DEPRECATION")
+    fun testAccessibilityNodeInfoTreePruned_isContainerFalseDoesNotPrune() {
+        // Arrange.
+        val parentTag = "ParentForOverlappedChildren"
+        val childOneTag = "OverlappedChildOne"
+        val childTwoTag = "OverlappedChildTwo"
+        setContent {
+            Box(Modifier.testTag(parentTag)) {
+                with(LocalDensity.current) {
+                    Box(
+                        Modifier
+                            .zIndex(1f)
+                            .testTag(childOneTag)
+                            .semantics { isContainer = false }
+                            .semantics { isContainer = true }
+                            .requiredSize(50.toDp())
+                    )
+                    BasicText(
+                        "Child Two",
+                        Modifier
+                            .testTag(childTwoTag)
+                            .requiredSize(50.toDp())
+                    )
+                }
+            }
+        }
+        val parentNodeId = rule.onNodeWithTag(parentTag).semanticsId
+        val overlappedChildTwoNodeId = rule.onNodeWithTag(childTwoTag).semanticsId
+
+        rule.runOnIdle {
+            assertThat(createAccessibilityNodeInfo(parentNodeId).childCount).isEqualTo(2)
+            assertThat(createAccessibilityNodeInfo(overlappedChildTwoNodeId).text.toString())
+                .isEqualTo("Child Two")
+        }
+    }
+
+    @Test
+    @OptIn(ExperimentalComposeUiApi::class)
+    fun testAccessibilityNodeInfoTreePruned_invisibleDoesNotPrune() {
+        // Arrange.
+        val parentTag = "ParentForOverlappedChildren"
+        val childOneTag = "OverlappedChildOne"
+        val childTwoTag = "OverlappedChildTwo"
+        setContent {
+            Box(Modifier.testTag(parentTag)) {
+                with(LocalDensity.current) {
+                    BasicText(
+                        "Child One",
+                        Modifier
+                            .zIndex(1f)
+                            .testTag(childOneTag)
+                            .semantics { invisibleToUser() }
+                            .requiredSize(50.toDp())
+                    )
+                    BasicText(
+                        "Child Two",
+                        Modifier
+                            .testTag(childTwoTag)
+                            .requiredSize(50.toDp())
+                    )
+                }
+            }
+        }
+        val parentNodeId = rule.onNodeWithTag(parentTag).semanticsId
+        val overlappedChildTwoNodeId = rule.onNodeWithTag(childTwoTag).semanticsId
+
+        rule.runOnIdle {
+            assertThat(createAccessibilityNodeInfo(parentNodeId).childCount).isEqualTo(2)
+            assertThat(createAccessibilityNodeInfo(overlappedChildTwoNodeId).text.toString())
+                .isEqualTo("Child Two")
+        }
+    }
+
+    @Test
+    @OptIn(ExperimentalComposeUiApi::class)
+    fun testAccessibilityNodeInfoTreePruned_isOpaquePrunes() {
+        // Arrange.
+        val parentTag = "ParentForOverlappedChildren"
+        val childOneTag = "OverlappedChildOne"
+        val childTwoTag = "OverlappedChildTwo"
+        setContent {
+            Box(Modifier.testTag(parentTag)) {
+                with(LocalDensity.current) {
+                    Box(
+                        Modifier
+                            .zIndex(1f)
+                            .testTag(childOneTag)
+                            .semantics { isOpaque() }
+                            .requiredSize(50.toDp())
+                    )
+                    BasicText(
+                        "Child Two",
+                        Modifier
+                            .testTag(childTwoTag)
+                            .requiredSize(50.toDp())
+                    )
+                }
+            }
+        }
+        val parentNodeId = rule.onNodeWithTag(parentTag).semanticsId
+        val overlappedChildOneNodeId = rule.onNodeWithTag(childOneTag).semanticsId
+        val overlappedChildTwoNodeId = rule.onNodeWithTag(childTwoTag).semanticsId
+
+        rule.runOnIdle {
+            assertThat(createAccessibilityNodeInfo(parentNodeId).childCount).isEqualTo(1)
+            assertThat(provider.createAccessibilityNodeInfo(overlappedChildOneNodeId)).isNotNull()
+            assertThat(provider.createAccessibilityNodeInfo(overlappedChildTwoNodeId)).isNull()
+        }
+    }
+
     @Test
     fun testPaneAppear() {
         var isPaneVisible by mutableStateOf(false)
diff --git a/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/semantics/SemanticsTests.kt b/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/semantics/SemanticsTests.kt
index 5312b3d..d12c772 100644
--- a/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/semantics/SemanticsTests.kt
+++ b/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/semantics/SemanticsTests.kt
@@ -32,6 +32,7 @@
 import androidx.compose.runtime.mutableStateOf
 import androidx.compose.runtime.remember
 import androidx.compose.runtime.setValue
+import androidx.compose.ui.ExperimentalComposeUiApi
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.geometry.Offset
 import androidx.compose.ui.geometry.Rect
@@ -204,6 +205,68 @@
     }
 
     @Test
+    @OptIn(ExperimentalComposeUiApi::class)
+    fun unsetSimpleProperty() {
+        rule.setContent {
+            Surface {
+                Box(Modifier
+                    .semantics { unset(SemanticsProperties.Heading) }.semantics { heading() }
+                    .semantics { traversalIndex = 1f; unset(SemanticsProperties.TraversalIndex) }
+                    .testTag(TestTag)
+                ) {
+                    Text("Hello World", modifier = Modifier.padding(8.dp))
+                }
+            }
+        }
+
+        rule.onNodeWithTag(TestTag)
+            .assertDoesNotHaveProperty(SemanticsProperties.Heading)
+        rule.onNodeWithTag(TestTag)
+            .assertDoesNotHaveProperty(SemanticsProperties.TraversalIndex)
+    }
+
+    @Test
+    @OptIn(ExperimentalComposeUiApi::class)
+    fun unsetDuplicateProperty() {
+        rule.setContent {
+            Surface {
+                Box(Modifier
+                    .semantics { unset(SemanticsProperties.TraversalIndex) }
+                    .semantics { traversalIndex = 2f }
+                    .semantics { traversalIndex = 1f }
+                    .testTag(TestTag)
+                ) {
+                    Text("Hello World", modifier = Modifier.padding(8.dp))
+                }
+            }
+        }
+
+        rule.onNodeWithTag(TestTag)
+            .assertDoesNotHaveProperty(SemanticsProperties.TraversalIndex)
+    }
+
+    @Test
+    @OptIn(ExperimentalComposeUiApi::class)
+    fun unsetDuplicatePropertySandwiched() {
+        rule.setContent {
+            Surface {
+                Box(Modifier
+                    .semantics { traversalIndex = 2f }
+                    .semantics { unset(SemanticsProperties.TraversalIndex) }
+                    .semantics { traversalIndex = 1f }
+                    .testTag(TestTag)
+                ) {
+                    Text("Hello World", modifier = Modifier.padding(8.dp))
+                }
+            }
+        }
+
+        rule.onNodeWithTag(TestTag)
+            .assert(SemanticsMatcher.expectValue(
+                SemanticsProperties.TraversalIndex, 2f))
+    }
+
+    @Test
     @Suppress("DEPRECATION")
     fun isContainerPropertyDeprecated() {
         rule.setContent {
diff --git a/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/AndroidComposeViewAccessibilityDelegateCompat.android.kt b/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/AndroidComposeViewAccessibilityDelegateCompat.android.kt
index 25a78f6..1ed409d 100644
--- a/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/AndroidComposeViewAccessibilityDelegateCompat.android.kt
+++ b/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/AndroidComposeViewAccessibilityDelegateCompat.android.kt
@@ -19,7 +19,6 @@
 import android.accessibilityservice.AccessibilityServiceInfo.FEEDBACK_ALL_MASK
 import android.content.Context
 import android.graphics.RectF
-import android.graphics.Region
 import android.os.Build
 import android.os.Bundle
 import android.os.Handler
@@ -43,10 +42,14 @@
 import androidx.annotation.RequiresApi
 import androidx.annotation.VisibleForTesting
 import androidx.collection.ArraySet
+import androidx.collection.IntObjectMap
 import androidx.collection.MutableIntObjectMap
 import androidx.collection.MutableIntSet
 import androidx.collection.MutableObjectIntMap
 import androidx.collection.SparseArrayCompat
+import androidx.collection.intListOf
+import androidx.collection.intObjectMapOf
+import androidx.collection.mutableIntListOf
 import androidx.collection.mutableIntObjectMapOf
 import androidx.collection.mutableIntSetOf
 import androidx.collection.mutableObjectIntMapOf
@@ -76,7 +79,6 @@
 import androidx.compose.ui.semantics.SemanticsActions.CustomActions
 import androidx.compose.ui.semantics.SemanticsConfiguration
 import androidx.compose.ui.semantics.SemanticsNode
-import androidx.compose.ui.semantics.SemanticsOwner
 import androidx.compose.ui.semantics.SemanticsProperties
 import androidx.compose.ui.semantics.SemanticsPropertiesAndroid
 import androidx.compose.ui.semantics.getOrNull
@@ -123,8 +125,7 @@
     return null
 }
 
-// TODO(b/272068594): Fix the primitive usage after completing the semantics refactor.
-@Suppress("PrimitiveInCollection", "NullAnnotationGroup")
+@Suppress("NullAnnotationGroup")
 @OptIn(InternalTextApi::class)
 internal class AndroidComposeViewAccessibilityDelegateCompat(val view: AndroidComposeView) :
     AccessibilityDelegateCompat() {
@@ -158,7 +159,7 @@
          * traversed event could be resulted from the same traverse action.
          */
         const val TextTraversedEventTimeoutMillis: Long = 1000
-        private val AccessibilityActionsResourceIds = intArrayOf(
+        private val AccessibilityActionsResourceIds = intListOf(
             R.id.accessibility_custom_action_0,
             R.id.accessibility_custom_action_1,
             R.id.accessibility_custom_action_2,
@@ -297,11 +298,12 @@
      * semantics tree. They key is the virtual view id(the root node has a key of
      * AccessibilityNodeProviderCompat.HOST_VIEW_ID and other node has a key of its id).
      */
-    private var currentSemanticsNodes: Map<Int, SemanticsNodeWithAdjustedBounds> = mapOf()
+    private var currentSemanticsNodes:
+        IntObjectMap<SemanticsNodeWithAdjustedBounds> = intObjectMapOf()
         get() {
             if (currentSemanticsNodesInvalidated) { // first instance of retrieving all nodes
                 currentSemanticsNodesInvalidated = false
-                field = view.semanticsOwner.getAllUncoveredSemanticsNodesToMap()
+                field = view.semanticsOwner.getAllUncoveredSemanticsNodesToIntObjectMap()
                 if (isEnabled) {
                     setTraversalValues()
                 }
@@ -321,26 +323,6 @@
 
     private val urlSpanCache = URLSpanCache()
 
-    /**
-     * A snapshot of the semantics node. The children here is fixed and are taken from the time
-     * this node is constructed. While a SemanticsNode always contains the up-to-date children.
-     */
-    private class SemanticsNodeCopy(
-        val semanticsNode: SemanticsNode,
-        currentSemanticsNodes: Map<Int, SemanticsNodeWithAdjustedBounds>
-    ) {
-        val unmergedConfig = semanticsNode.unmergedConfig
-        val children: MutableSet<Int> = mutableSetOf()
-
-        init {
-            semanticsNode.replacedChildren.fastForEach { child ->
-                if (currentSemanticsNodes.contains(child.id)) {
-                    children.add(child.id)
-                }
-            }
-        }
-    }
-
     // previousSemanticsNodes holds the previous pruned semantics tree so that we can compare the
     // current and previous trees in onSemanticsChange(). We use SemanticsNodeCopy here because
     // SemanticsNode's children are dynamically generated and always reflect the current children.
@@ -348,7 +330,7 @@
     private var previousSemanticsNodes: MutableIntObjectMap<SemanticsNodeCopy> =
         mutableIntObjectMapOf()
     private var previousSemanticsRoot =
-        SemanticsNodeCopy(view.semanticsOwner.unmergedRootSemanticsNode, mapOf())
+        SemanticsNodeCopy(view.semanticsOwner.unmergedRootSemanticsNode, intObjectMapOf())
     private var checkingForSemanticsChanges = false
 
     init {
@@ -390,11 +372,11 @@
             return false
         }
 
-        return canScroll(currentSemanticsNodes.values, vertical, direction, position)
+        return canScroll(currentSemanticsNodes, vertical, direction, position)
     }
 
     private fun canScroll(
-        currentSemanticsNodes: Collection<SemanticsNodeWithAdjustedBounds>,
+        currentSemanticsNodes: IntObjectMap<SemanticsNodeWithAdjustedBounds>,
         vertical: Boolean,
         direction: Int,
         position: Offset
@@ -407,18 +389,19 @@
             false -> SemanticsProperties.HorizontalScrollAxisRange
         }
 
-        return currentSemanticsNodes.any { node ->
+        var foundNode = false
+        currentSemanticsNodes.forEachValue { node ->
             // Only consider nodes that are under the touch event. Checks the adjusted bounds to
             // avoid overlapping siblings. Because position is a float (touch event can happen in-
             // between pixels), convert the int-based Android Rect to a float-based Compose Rect
             // before doing the comparison.
             if (!node.adjustedBounds.toComposeRect().contains(position)) {
-                return@any false
+                return@forEachValue
             }
 
             // Using `unmergedConfig` here is okay since we iterate through all nodes anyway
             val scrollRange = node.semanticsNode.unmergedConfig.getOrNull(scrollRangeProperty)
-                ?: return@any false
+                ?: return@forEachValue
 
             // A node simply having scrollable semantics doesn't mean it's necessarily scrollable
             // in the given direction – it must also not be scrolled to its limit in that direction.
@@ -430,9 +413,19 @@
                 actualDirection = -1
             }
 
-            if (actualDirection < 0) scrollRange.value() > 0
-            else scrollRange.value() < scrollRange.maxValue()
+            if (actualDirection < 0) {
+                if (scrollRange.value() > 0) {
+                    foundNode = true
+                    return@forEachValue
+                }
+            } else {
+                if (scrollRange.value() < scrollRange.maxValue()) {
+                    foundNode = true
+                    return@forEachValue
+                }
+            }
         }
+        return foundNode
     }
 
     private fun createNodeInfo(virtualViewId: Int): AccessibilityNodeInfo? {
@@ -662,7 +655,7 @@
             currNode.unmergedConfig.getOrElse(SemanticsProperties.IsTraversalGroup) { false }
 
         if ((isTraversalGroup || isScreenReaderFocusable(currNode)) &&
-            currNode.id in currentSemanticsNodes.keys) {
+            currentSemanticsNodes.containsKey(currNode.id)) {
             geometryList.add(currNode)
         }
         if (isTraversalGroup) {
@@ -728,14 +721,17 @@
     private fun isScreenReaderFocusable(
         node: SemanticsNode
     ): Boolean {
+        // TODO(aelias): This may not behave correctly in combination with fake nodes, see b/283968786
         val nodeContentDescriptionOrNull =
             node.unmergedConfig.getOrNull(SemanticsProperties.ContentDescription)?.firstOrNull()
         val isSpeakingNode = nodeContentDescriptionOrNull != null ||
             getInfoText(node) != null || getInfoStateDescriptionOrNull(node) != null ||
             getInfoIsCheckable(node)
 
-        return node.unmergedConfig.isMergingSemanticsOfDescendants ||
-            node.isUnmergedLeafNode && isSpeakingNode
+        return node.isVisible &&
+            (node.unmergedConfig.isMergingSemanticsOfDescendants ||
+            node.isUnmergedLeafNode &&
+            isSpeakingNode)
     }
 
     @OptIn(ExperimentalComposeUiApi::class)
@@ -777,6 +773,7 @@
 
         // This property exists to distinguish semantically meaningful nodes from purely structural
         // or decorative UI elements.  Most nodes are considered important, except:
+        // * Invisible nodes.
         // * Non-merging nodes with only non-accessibility-speakable properties.
         //     * Of the built-in ones, the key example is testTag.
         //     * Custom SemanticsPropertyKeys defined outside the UI package
@@ -1181,7 +1178,9 @@
                 // presented to the user and actually performed.
                 if (labelToActionId.containsKey(virtualViewId)) {
                     val oldLabelToActionId = labelToActionId[virtualViewId]
-                    val availableIds = AccessibilityActionsResourceIds.toMutableList()
+                    val availableIds = mutableIntListOf().apply {
+                        AccessibilityActionsResourceIds.forEach { add(it) }
+                    }
                     val unassignedActions = mutableListOf<CustomAccessibilityAction>()
                     customActions.fastForEach { action ->
                         if (oldLabelToActionId!!.contains(action.label)) {
@@ -2073,29 +2072,40 @@
             hitSemanticsEntities = hitSemanticsEntities
         )
 
-        val layoutNode = hitSemanticsEntities.lastOrNull()?.requireLayoutNode()
+        // Iterate front-to-back until we find a node with semantics that are important-for-a11y
+        for (i in hitSemanticsEntities.lastIndex downTo 0) {
+            val layoutNode = hitSemanticsEntities[i].requireLayoutNode()
 
-        var virtualViewId = InvalidId
-        if (layoutNode?.nodes?.has(Nodes.Semantics) == true) {
+            // If this node corresponds to an AndroidView, then we should return InvalidId
+            // to let the View System handle it.
+            val androidView = view
+                .androidViewsHandler
+                .layoutNodeToHolder[layoutNode]
+            if (androidView != null) {
+                return InvalidId
+            }
+
+            if (layoutNode.nodes.has(Nodes.Semantics) == false) {
+                continue
+            }
+
+            val virtualViewId = semanticsNodeIdToAccessibilityVirtualNodeId(
+                layoutNode.semanticsId
+            )
 
             // The node below is not added to the tree; it's a wrapper around outer semantics to
             // use the methods available to the SemanticsNode
             val semanticsNode = SemanticsNode(layoutNode, false)
 
-            // Do not 'find' invisible nodes when exploring by touch. This will prevent us from
-            // sending events for invisible nodes
-            if (semanticsNode.isVisible) {
-                val androidView = view
-                    .androidViewsHandler
-                    .layoutNodeToHolder[layoutNode]
-                if (androidView == null) {
-                    virtualViewId = semanticsNodeIdToAccessibilityVirtualNodeId(
-                        layoutNode.semanticsId
-                    )
-                }
+            // Continue to the next items in the hit test if it's not considered important.
+            if (!semanticsNode.isImportantForAccessibility()) {
+                continue
             }
+
+            return virtualViewId
         }
-        return virtualViewId
+
+        return InvalidId
     }
 
     /**
@@ -2350,31 +2360,31 @@
         }
         paneDisplayed.removeAll(toRemove)
         previousSemanticsNodes.clear()
-        for (entry in currentSemanticsNodes.entries) {
-            if (entry.value.semanticsNode.unmergedConfig.contains(SemanticsProperties.PaneTitle) &&
-                paneDisplayed.add(entry.key)) {
+        currentSemanticsNodes.forEach { key, value ->
+            if (value.semanticsNode.unmergedConfig.contains(SemanticsProperties.PaneTitle) &&
+                paneDisplayed.add(key)) {
                 sendPaneChangeEvents(
-                    entry.key,
+                    key,
                     AccessibilityEventCompat.CONTENT_CHANGE_TYPE_PANE_APPEARED,
-                    entry.value.semanticsNode.unmergedConfig[SemanticsProperties.PaneTitle]
+                    value.semanticsNode.unmergedConfig[SemanticsProperties.PaneTitle]
                 )
             }
-            previousSemanticsNodes[entry.key] =
-                SemanticsNodeCopy(entry.value.semanticsNode, currentSemanticsNodes)
+            previousSemanticsNodes[key] =
+                SemanticsNodeCopy(value.semanticsNode, currentSemanticsNodes)
         }
         previousSemanticsRoot =
             SemanticsNodeCopy(view.semanticsOwner.unmergedRootSemanticsNode, currentSemanticsNodes)
     }
 
     private fun sendSemanticsPropertyChangeEvents(
-        newSemanticsNodes: Map<Int, SemanticsNodeWithAdjustedBounds>
+        newSemanticsNodes: IntObjectMap<SemanticsNodeWithAdjustedBounds>
     ) {
         val oldScrollObservationScopes = ArrayList(scrollObservationScopes)
         scrollObservationScopes.clear()
-        for (id in newSemanticsNodes.keys) {
+        newSemanticsNodes.forEachKey { id ->
             // We do doing this search because the new configuration is set as a whole, so we
             // can't indicate which property is changed when setting the new configuration.
-            val oldNode = previousSemanticsNodes[id] ?: continue
+            val oldNode = previousSemanticsNodes[id] ?: return@forEachKey
             val newNode = checkPreconditionNotNull(newSemanticsNodes[id]?.semanticsNode) {
                 "no value for specified key"
             }
@@ -3181,14 +3191,6 @@
 // shorter and more readable.
 private fun SemanticsNode.enabled() = (!config.contains(SemanticsProperties.Disabled))
 
-internal fun SemanticsNode.isImportantForAccessibility() =
-    unmergedConfig.isMergingSemanticsOfDescendants ||
-        unmergedConfig.containsImportantForAccessibility()
-
-@OptIn(ExperimentalComposeUiApi::class)
-private val SemanticsNode.isVisible: Boolean
-    get() = !isTransparent && !unmergedConfig.contains(SemanticsProperties.InvisibleToUser)
-
 private fun SemanticsNode.propertiesDeleted(oldConfig: SemanticsConfiguration): Boolean {
     for (entry in oldConfig) {
         if (!config.contains(entry.key)) {
@@ -3228,106 +3230,6 @@
 }
 
 /**
- * Semantics node with adjusted bounds for the uncovered(by siblings) part.
- */
-internal class SemanticsNodeWithAdjustedBounds(
-    val semanticsNode: SemanticsNode,
-    val adjustedBounds: android.graphics.Rect
-)
-
-internal val DefaultFakeNodeBounds = Rect(0f, 0f, 10f, 10f)
-
-// TODO(b/272068594): Fix the collection usage after completing the semantics refactor.
-@Suppress("PrimitiveInCollection")
-/**
- * Finds pruned [SemanticsNode]s in the tree owned by this [SemanticsOwner]. A semantics node
- * completely covered by siblings drawn on top of it will be pruned. Return the results in a
- * map.
- */
-internal fun SemanticsOwner.getAllUncoveredSemanticsNodesToMap():
-    Map<Int, SemanticsNodeWithAdjustedBounds> {
-    val root = unmergedRootSemanticsNode
-    val nodes = mutableMapOf<Int, SemanticsNodeWithAdjustedBounds>()
-    if (!root.layoutNode.isPlaced || !root.layoutNode.isAttached) {
-        return nodes
-    }
-
-    val unaccountedSpace = with(root.boundsInRoot) {
-        Region(
-            left.fastRoundToInt(),
-            top.fastRoundToInt(),
-            right.fastRoundToInt(),
-            bottom.fastRoundToInt()
-        )
-    }
-
-    fun findAllSemanticNodesRecursive(currentNode: SemanticsNode, region: Region) {
-        val notAttachedOrPlaced =
-            !currentNode.layoutNode.isPlaced || !currentNode.layoutNode.isAttached
-        if ((unaccountedSpace.isEmpty && currentNode.id != root.id) ||
-            (notAttachedOrPlaced && !currentNode.isFake)
-        ) {
-            return
-        }
-        val touchBoundsInRoot = currentNode.touchBoundsInRoot
-        val left = touchBoundsInRoot.left.fastRoundToInt()
-        val top = touchBoundsInRoot.top.fastRoundToInt()
-        val right = touchBoundsInRoot.right.fastRoundToInt()
-        val bottom = touchBoundsInRoot.bottom.fastRoundToInt()
-
-        region.set(left, top, right, bottom)
-
-        val virtualViewId = if (currentNode.id == root.id) {
-            AccessibilityNodeProviderCompat.HOST_VIEW_ID
-        } else {
-            currentNode.id
-        }
-        if (region.op(unaccountedSpace, Region.Op.INTERSECT)) {
-            nodes[virtualViewId] = SemanticsNodeWithAdjustedBounds(currentNode, region.bounds)
-            // Children could be drawn outside of parent, but we are using clipped bounds for
-            // accessibility now, so let's put the children recursion inside of this if. If later
-            // we decide to support children drawn outside of parent, we can move it out of the
-            // if block.
-            val children = currentNode.replacedChildren
-            for (i in children.size - 1 downTo 0) {
-                findAllSemanticNodesRecursive(children[i], region)
-            }
-            if (currentNode.isImportantForAccessibility()) {
-                unaccountedSpace.op(left, top, right, bottom, Region.Op.DIFFERENCE)
-            }
-        } else {
-            if (currentNode.isFake) {
-                val parentNode = currentNode.parent
-                // use parent bounds for fake node
-                val boundsForFakeNode = if (parentNode?.layoutInfo?.isPlaced == true) {
-                    parentNode.boundsInRoot
-                } else {
-                    DefaultFakeNodeBounds
-                }
-                nodes[virtualViewId] = SemanticsNodeWithAdjustedBounds(
-                    currentNode,
-                    android.graphics.Rect(
-                        boundsForFakeNode.left.fastRoundToInt(),
-                        boundsForFakeNode.top.fastRoundToInt(),
-                        boundsForFakeNode.right.fastRoundToInt(),
-                        boundsForFakeNode.bottom.fastRoundToInt(),
-                    )
-                )
-            } else if (virtualViewId == AccessibilityNodeProviderCompat.HOST_VIEW_ID) {
-                // Root view might have WRAP_CONTENT layout params in which case it will have zero
-                // bounds if there is no other content with semantics. But we need to always send the
-                // root view info as there are some other apps (e.g. Google Assistant) that depend
-                // on accessibility info
-                nodes[virtualViewId] = SemanticsNodeWithAdjustedBounds(currentNode, region.bounds)
-            }
-        }
-    }
-
-    findAllSemanticNodesRecursive(root, Region())
-    return nodes
-}
-
-/**
  * This class is here to ensure that the classes that use this API will get verified and can be
  * AOT compiled. It is expected that this class will soft-fail verification, but the classes
  * which use this method will pass.
diff --git a/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/SemanticsUtils.android.kt b/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/SemanticsUtils.android.kt
index 15478ad..2637624 100644
--- a/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/SemanticsUtils.android.kt
+++ b/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/SemanticsUtils.android.kt
@@ -22,6 +22,8 @@
 import androidx.collection.MutableIntSet
 import androidx.collection.mutableIntObjectMapOf
 import androidx.collection.mutableIntSetOf
+import androidx.compose.ui.ExperimentalComposeUiApi
+import androidx.compose.ui.geometry.Rect
 import androidx.compose.ui.node.LayoutNode
 import androidx.compose.ui.node.OwnerScope
 import androidx.compose.ui.semantics.Role
@@ -30,6 +32,7 @@
 import androidx.compose.ui.semantics.SemanticsConfiguration
 import androidx.compose.ui.semantics.SemanticsNode
 import androidx.compose.ui.semantics.SemanticsOwner
+import androidx.compose.ui.semantics.SemanticsProperties
 import androidx.compose.ui.semantics.getOrNull
 import androidx.compose.ui.text.TextLayoutResult
 import androidx.compose.ui.util.fastForEach
@@ -102,6 +105,25 @@
         else -> null
     }
 
+internal fun SemanticsNode.isImportantForAccessibility() =
+    isVisible &&
+        (unmergedConfig.isMergingSemanticsOfDescendants ||
+        unmergedConfig.containsImportantForAccessibility())
+
+@OptIn(ExperimentalComposeUiApi::class)
+internal val SemanticsNode.isVisible: Boolean
+    get() = !isTransparent && !unmergedConfig.contains(SemanticsProperties.InvisibleToUser)
+
+internal val DefaultFakeNodeBounds = Rect(0f, 0f, 10f, 10f)
+
+/**
+ * Semantics node with adjusted bounds for the uncovered(by siblings) part.
+ */
+internal class SemanticsNodeWithAdjustedBounds(
+    val semanticsNode: SemanticsNode,
+    val adjustedBounds: android.graphics.Rect
+)
+
 /**
  * This function retrieves the View corresponding to a semanticsId, if it exists.
  */
diff --git a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/semantics/SemanticsConfiguration.kt b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/semantics/SemanticsConfiguration.kt
index 000dd66..5ebaf46 100644
--- a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/semantics/SemanticsConfiguration.kt
+++ b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/semantics/SemanticsConfiguration.kt
@@ -16,6 +16,7 @@
 
 package androidx.compose.ui.semantics
 
+import androidx.compose.ui.ExperimentalComposeUiApi
 import androidx.compose.ui.platform.simpleIdentityToString
 
 /**
@@ -70,6 +71,11 @@
         }
     }
 
+    @ExperimentalComposeUiApi
+    override fun <T> unset(key: SemanticsPropertyKey<T>) {
+       props.remove(key)
+    }
+
     operator fun <T> contains(key: SemanticsPropertyKey<T>): Boolean {
         return props.containsKey(key)
     }
diff --git a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/semantics/SemanticsProperties.kt b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/semantics/SemanticsProperties.kt
index e235912..de10d8c 100644
--- a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/semantics/SemanticsProperties.kt
+++ b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/semantics/SemanticsProperties.kt
@@ -98,16 +98,24 @@
     /**
      * @see SemanticsPropertyReceiver.isContainer
      */
-    @Deprecated("Use `isTraversalGroup` instead.",
-        replaceWith = ReplaceWith("IsTraversalGroup"),
-    )
+    @Deprecated("Use `isTraversalGroup` and `isOpaque` instead.")
     val IsContainer: SemanticsPropertyKey<Boolean>
         get() = IsTraversalGroup
 
     /**
      * @see SemanticsPropertyReceiver.isTraversalGroup
      */
-    val IsTraversalGroup = AccessibilityKey<Boolean>("IsTraversalGroup")
+    val IsTraversalGroup = SemanticsPropertyKey<Boolean>("IsTraversalGroup")
+
+    /**
+     * @see SemanticsPropertyReceiver.isOpaque
+     */
+    val IsOpaque = AccessibilityKey<Unit>(
+        name = "IsOpaque",
+        mergePolicy = { parentValue, _ ->
+            parentValue
+        }
+    )
 
     /**
      * @see SemanticsPropertyReceiver.invisibleToUser
@@ -123,7 +131,7 @@
     /**
      * @see SemanticsPropertyReceiver.traversalIndex
      */
-    val TraversalIndex = AccessibilityKey<Float>(
+    val TraversalIndex = SemanticsPropertyKey<Float>(
         name = "TraversalIndex",
         mergePolicy = { parentValue, _ ->
             // Never merge traversal indices
@@ -792,6 +800,43 @@
  */
 interface SemanticsPropertyReceiver {
     operator fun <T> set(key: SemanticsPropertyKey<T>, value: T)
+
+    /**
+     * Unset an individual property.
+     *
+     * Note: this can only unset properties originally on the same modifier chain, not properties
+     * merged from children (for those, use [clearAndSetSemantics] instead). And because the
+     * semantics system processes modifier chains back-to-front, the unset must be ordered earlier
+     * on the modifier chain if it's in a separate `semantics {}` block.
+
+     * 1. Examples of correct uses (resulting in empty semantics):
+     *
+     *   ```
+     *   Modifier.semantics { heading(); unset(SemanticsProperties.Heading) }
+     *   Modifier.semantics { unset(SemanticsProperties.Heading) }.semantics { heading() }
+     *   ```
+     *
+     * 2. Examples of ineffective, no-op uses (where the heading remains instead of being unset):
+     *
+     *   ```
+     *   Modifier.semantics { unset(SemanticsProperties.Heading); heading() } // order
+     *   Modifier.semantics { heading() }.semantics { unset(SemanticsProperties.Heading) } // order
+     *   Box(Modifier.semantics(mergeDescendants = true) { unset(SemanticsProperties.Heading) }) {
+     *       Box(Modifier.semantics { heading() }) // not originally on the same modifier chain`
+     *   }
+     *
+     * 3. Examples of complex cases where there is more than one set:
+     *
+     *   ```
+     *   // Result is empty semantics:
+     *   Modifier.semantics { unset(SemanticsProperties.TestTag) }.testTag("b").testTag("a")
+     *
+     *   // Result is testTag = "b":`
+     *   Modifier.testTag("b").semantics { unset(SemanticsProperties.TestTag) }.testTag("a")
+     *   ```
+     */
+    @ExperimentalComposeUiApi
+    fun <T> unset(key: SemanticsPropertyKey<T>)
 }
 
 /**
@@ -884,20 +929,46 @@
  *
  * @see SemanticsProperties.IsContainer
  */
-@Deprecated("Use `isTraversalGroup` instead.",
-    replaceWith = ReplaceWith("isTraversalGroup"),
-)
-var SemanticsPropertyReceiver.isContainer by SemanticsProperties.IsTraversalGroup
+@Deprecated("Use `isTraversalGroup` and `isOpaque` instead.")
+@get:Deprecated("Use `isTraversalGroup` and `isOpaque` instead.")
+@set:Deprecated("Use `isTraversalGroup` and `isOpaque` instead.")
+@OptIn(ExperimentalComposeUiApi::class)
+var SemanticsPropertyReceiver.isContainer: Boolean
+    get() = throwSemanticsGetNotSupported()
+    set(bool) {
+        isTraversalGroup = bool
+        if (bool) {
+            this[SemanticsProperties.IsOpaque] = Unit
+        } else {
+            unset(SemanticsProperties.IsOpaque)
+        }
+    }
 
 /**
- * Whether this semantics node is a traversal group. This is defined as a node whose function
- * is to serve as a boundary or border in organizing its children.
+ * Whether this semantics node is a traversal group.
+ *
+ * See https://developer.android.com/jetpack/compose/accessibility#modify-traversal-order
  *
  * @see SemanticsProperties.IsTraversalGroup
  */
 var SemanticsPropertyReceiver.isTraversalGroup by SemanticsProperties.IsTraversalGroup
 
 /**
+ * Non-mergeable property used to mark that whether a node is semantically opaque.
+ *
+ * In other words, whether nodes fully covered by it ought to be pruned from the a11y tree.  (Note
+ * that most semantic properties other than testTag also have this effect, so it should be rarely
+ * needed.)
+ *
+ * If true, then a11y nodes behind will be pruned unless this node's graphics alpha is 0.
+ *
+ * @see SemanticsProperties.IsOpaque
+ */
+fun SemanticsPropertyReceiver.isOpaque() {
+    this[SemanticsProperties.IsOpaque] = Unit
+}
+
+/**
  * Whether this node is specially known to be invisible to the user.
  *
  * For example, if the node is currently occluded by a dark semitransparent
diff --git a/docs-public/build.gradle b/docs-public/build.gradle
index 76665cd1..6abd071 100644
--- a/docs-public/build.gradle
+++ b/docs-public/build.gradle
@@ -15,10 +15,10 @@
 }
 
 dependencies {
-    docs("androidx.activity:activity:1.9.0-alpha01")
-    docs("androidx.activity:activity-compose:1.9.0-alpha01")
-    samples("androidx.activity:activity-compose-samples:1.9.0-alpha01")
-    docs("androidx.activity:activity-ktx:1.9.0-alpha01")
+    docs("androidx.activity:activity:1.9.0-alpha02")
+    docs("androidx.activity:activity-compose:1.9.0-alpha02")
+    samples("androidx.activity:activity-compose-samples:1.9.0-alpha02")
+    docs("androidx.activity:activity-ktx:1.9.0-alpha02")
     // ads-identifier is deprecated
     docsWithoutApiSince("androidx.ads:ads-identifier:1.0.0-alpha05")
     docsWithoutApiSince("androidx.ads:ads-identifier-common:1.0.0-alpha05")
@@ -39,58 +39,59 @@
     docs("androidx.asynclayoutinflater:asynclayoutinflater:1.1.0-alpha01")
     docs("androidx.asynclayoutinflater:asynclayoutinflater-appcompat:1.1.0-alpha01")
     docs("androidx.autofill:autofill:1.3.0-alpha01")
-    docs("androidx.benchmark:benchmark-common:1.2.2")
-    docs("androidx.benchmark:benchmark-junit4:1.2.2")
-    docs("androidx.benchmark:benchmark-macro:1.2.2")
-    docs("androidx.benchmark:benchmark-macro-junit4:1.2.2")
+    docs("androidx.benchmark:benchmark-common:1.2.3")
+    docs("androidx.benchmark:benchmark-junit4:1.2.3")
+    docs("androidx.benchmark:benchmark-macro:1.2.3")
+    docs("androidx.benchmark:benchmark-macro-junit4:1.2.3")
     docs("androidx.biometric:biometric:1.2.0-alpha05")
     docs("androidx.biometric:biometric-ktx:1.2.0-alpha05")
     samples("androidx.biometric:biometric-ktx-samples:1.2.0-alpha05")
     docs("androidx.bluetooth:bluetooth:1.0.0-alpha02")
     docs("androidx.bluetooth:bluetooth-testing:1.0.0-alpha02")
     docs("androidx.browser:browser:1.8.0-beta01")
-    docs("androidx.camera:camera-camera2:1.4.0-alpha03")
-    docs("androidx.camera:camera-core:1.4.0-alpha03")
-    docs("androidx.camera:camera-effects:1.0.0-alpha01")
-    docs("androidx.camera:camera-extensions:1.4.0-alpha03")
+    docs("androidx.camera:camera-camera2:1.4.0-alpha04")
+    docs("androidx.camera:camera-core:1.4.0-alpha04")
+    docs("androidx.camera:camera-effects:1.4.0-alpha04")
+    docs("androidx.camera:camera-extensions:1.4.0-alpha04")
     stubs(fileTree(dir: "../camera/camera-extensions-stub", include: ["camera-extensions-stub.jar"]))
-    docs("androidx.camera:camera-lifecycle:1.4.0-alpha03")
-    docs("androidx.camera:camera-mlkit-vision:1.4.0-alpha03")
-    docs("androidx.camera:camera-video:1.4.0-alpha03")
-    docs("androidx.camera:camera-view:1.4.0-alpha03")
-    docs("androidx.camera:camera-viewfinder:1.4.0-alpha03")
+    docs("androidx.camera:camera-lifecycle:1.4.0-alpha04")
+    docs("androidx.camera:camera-mlkit-vision:1.4.0-alpha04")
+    docs("androidx.camera:camera-video:1.4.0-alpha04")
+    docs("androidx.camera:camera-view:1.4.0-alpha04")
+    docs("androidx.camera:camera-viewfinder:1.4.0-alpha04")
     docs("androidx.camera:camera-viewfinder-compose:1.4.0-alpha03")
-    docs("androidx.camera:camera-viewfinder-core:1.4.0-alpha03")
+    docs("androidx.camera:camera-viewfinder-core:1.4.0-alpha04")
+    samples("androidx.camera:camera-viewfinder-core-samples:1.4.0-alpha04")
     docs("androidx.car.app:app:1.4.0-rc02")
     docs("androidx.car.app:app-automotive:1.4.0-rc02")
     docs("androidx.car.app:app-projected:1.4.0-rc02")
     docs("androidx.car.app:app-testing:1.4.0-rc02")
     docs("androidx.cardview:cardview:1.0.0")
-    kmpDocs("androidx.collection:collection:1.4.0-rc01")
+    kmpDocs("androidx.collection:collection:1.4.0")
     docs("androidx.collection:collection-ktx:1.4.0-rc01")
-    kmpDocs("androidx.compose.animation:animation:1.6.0-rc01")
-    kmpDocs("androidx.compose.animation:animation-core:1.6.0-rc01")
-    kmpDocs("androidx.compose.animation:animation-graphics:1.6.0-rc01")
-    samples("androidx.compose.animation:animation-samples:1.6.0-rc01")
-    samples("androidx.compose.animation:animation-core-samples:1.6.0-rc01")
-    samples("androidx.compose.animation:animation-graphics-samples:1.6.0-rc01")
-    kmpDocs("androidx.compose.foundation:foundation:1.6.0-rc01")
-    kmpDocs("androidx.compose.foundation:foundation-layout:1.6.0-rc01")
-    samples("androidx.compose.foundation:foundation-layout-samples:1.6.0-rc01")
-    samples("androidx.compose.foundation:foundation-samples:1.6.0-rc01")
-    kmpDocs("androidx.compose.material3:material3:1.2.0-beta02")
-    kmpDocs("androidx.compose.material3:material3-adaptive:1.0.0-alpha04")
+    kmpDocs("androidx.compose.animation:animation:1.7.0-alpha01")
+    kmpDocs("androidx.compose.animation:animation-core:1.7.0-alpha01")
+    kmpDocs("androidx.compose.animation:animation-graphics:1.7.0-alpha01")
+    samples("androidx.compose.animation:animation-samples:1.7.0-alpha01")
+    samples("androidx.compose.animation:animation-core-samples:1.7.0-alpha01")
+    samples("androidx.compose.animation:animation-graphics-samples:1.7.0-alpha01")
+    kmpDocs("androidx.compose.foundation:foundation:1.7.0-alpha01")
+    kmpDocs("androidx.compose.foundation:foundation-layout:1.7.0-alpha01")
+    samples("androidx.compose.foundation:foundation-layout-samples:1.7.0-alpha01")
+    samples("androidx.compose.foundation:foundation-samples:1.7.0-alpha01")
+    kmpDocs("androidx.compose.material3:material3:1.2.0-rc01")
+    kmpDocs("androidx.compose.material3:material3-adaptive:1.0.0-alpha05")
     kmpDocs("androidx.compose.material3:material3-adaptive-navigation-suite:1.0.0-alpha02")
-    samples("androidx.compose.material3:material3-adaptive-navigation-suite-samples:1.2.0-beta02")
-    samples("androidx.compose.material3:material3-adaptive-samples:1.2.0-beta02")
-    samples("androidx.compose.material3:material3-samples:1.2.0-beta02")
-    kmpDocs("androidx.compose.material3:material3-window-size-class:1.2.0-beta02")
-    samples("androidx.compose.material3:material3-window-size-class-samples:1.2.0-beta02")
-    kmpDocs("androidx.compose.material:material:1.6.0-rc01")
-    kmpDocs("androidx.compose.material:material-icons-core:1.6.0-rc01")
-    samples("androidx.compose.material:material-icons-core-samples:1.6.0-rc01")
-    kmpDocs("androidx.compose.material:material-ripple:1.6.0-rc01")
-    samples("androidx.compose.material:material-samples:1.6.0-rc01")
+    samples("androidx.compose.material3:material3-adaptive-navigation-suite-samples:1.2.0-rc01")
+    samples("androidx.compose.material3:material3-adaptive-samples:1.2.0-rc01")
+    samples("androidx.compose.material3:material3-samples:1.2.0-rc01")
+    kmpDocs("androidx.compose.material3:material3-window-size-class:1.2.0-rc01")
+    samples("androidx.compose.material3:material3-window-size-class-samples:1.2.0-rc01")
+    kmpDocs("androidx.compose.material:material:1.7.0-alpha01")
+    kmpDocs("androidx.compose.material:material-icons-core:1.7.0-alpha01")
+    samples("androidx.compose.material:material-icons-core-samples:1.7.0-alpha01")
+    kmpDocs("androidx.compose.material:material-ripple:1.7.0-alpha01")
+    samples("androidx.compose.material:material-samples:1.7.0-alpha01")
     kmpDocs("androidx.compose.runtime:runtime:1.7.0-alpha01")
     docs("androidx.compose.runtime:runtime-livedata:1.7.0-alpha01")
     samples("androidx.compose.runtime:runtime-livedata-samples:1.7.0-alpha01")
@@ -102,25 +103,25 @@
     samples("androidx.compose.runtime:runtime-saveable-samples:1.7.0-alpha01")
     samples("androidx.compose.runtime:runtime-samples:1.7.0-alpha01")
     docs("androidx.compose.runtime:runtime-tracing:1.0.0-beta01")
-    kmpDocs("androidx.compose.ui:ui:1.6.0-rc01")
-    kmpDocs("androidx.compose.ui:ui-geometry:1.6.0-rc01")
-    kmpDocs("androidx.compose.ui:ui-graphics:1.6.0-rc01")
-    samples("androidx.compose.ui:ui-graphics-samples:1.6.0-rc01")
-    kmpDocs("androidx.compose.ui:ui-test:1.6.0-rc01")
-    kmpDocs("androidx.compose.ui:ui-test-junit4:1.6.0-rc01")
-    samples("androidx.compose.ui:ui-test-samples:1.6.0-rc01")
-    kmpDocs("androidx.compose.ui:ui-text:1.6.0-rc01")
-    docs("androidx.compose.ui:ui-text-google-fonts:1.6.0-rc01")
-    samples("androidx.compose.ui:ui-text-samples:1.6.0-rc01")
-    kmpDocs("androidx.compose.ui:ui-tooling:1.6.0-rc01")
-    kmpDocs("androidx.compose.ui:ui-tooling-data:1.6.0-rc01")
-    kmpDocs("androidx.compose.ui:ui-tooling-preview:1.6.0-rc01")
-    kmpDocs("androidx.compose.ui:ui-unit:1.6.0-rc01")
-    samples("androidx.compose.ui:ui-unit-samples:1.6.0-rc01")
-    kmpDocs("androidx.compose.ui:ui-util:1.6.0-rc01")
-    docs("androidx.compose.ui:ui-viewbinding:1.6.0-rc01")
-    samples("androidx.compose.ui:ui-viewbinding-samples:1.6.0-rc01")
-    samples("androidx.compose.ui:ui-samples:1.6.0-rc01")
+    kmpDocs("androidx.compose.ui:ui:1.7.0-alpha01")
+    kmpDocs("androidx.compose.ui:ui-geometry:1.7.0-alpha01")
+    kmpDocs("androidx.compose.ui:ui-graphics:1.7.0-alpha01")
+    samples("androidx.compose.ui:ui-graphics-samples:1.7.0-alpha01")
+    kmpDocs("androidx.compose.ui:ui-test:1.7.0-alpha01")
+    kmpDocs("androidx.compose.ui:ui-test-junit4:1.7.0-alpha01")
+    samples("androidx.compose.ui:ui-test-samples:1.7.0-alpha01")
+    kmpDocs("androidx.compose.ui:ui-text:1.7.0-alpha01")
+    docs("androidx.compose.ui:ui-text-google-fonts:1.7.0-alpha01")
+    samples("androidx.compose.ui:ui-text-samples:1.7.0-alpha01")
+    kmpDocs("androidx.compose.ui:ui-tooling:1.7.0-alpha01")
+    kmpDocs("androidx.compose.ui:ui-tooling-data:1.7.0-alpha01")
+    kmpDocs("androidx.compose.ui:ui-tooling-preview:1.7.0-alpha01")
+    kmpDocs("androidx.compose.ui:ui-unit:1.7.0-alpha01")
+    samples("androidx.compose.ui:ui-unit-samples:1.7.0-alpha01")
+    kmpDocs("androidx.compose.ui:ui-util:1.7.0-alpha01")
+    docs("androidx.compose.ui:ui-viewbinding:1.7.0-alpha01")
+    samples("androidx.compose.ui:ui-viewbinding-samples:1.7.0-alpha01")
+    samples("androidx.compose.ui:ui-samples:1.7.0-alpha01")
     docs("androidx.concurrent:concurrent-futures:1.2.0-alpha02")
     docs("androidx.concurrent:concurrent-futures-ktx:1.2.0-alpha02")
     docs("androidx.constraintlayout:constraintlayout:2.2.0-alpha13")
@@ -128,13 +129,13 @@
     docs("androidx.constraintlayout:constraintlayout-core:1.1.0-alpha13")
     docs("androidx.contentpager:contentpager:1.0.0")
     docs("androidx.coordinatorlayout:coordinatorlayout:1.3.0-alpha02")
-    docs("androidx.core:core:1.13.0-alpha03")
+    docs("androidx.core:core:1.13.0-alpha04")
     // TODO(b/294531403): Turn on apiSince for core-animation when it releases as alpha
     docsWithoutApiSince("androidx.core:core-animation:1.0.0-rc01")
     docsWithoutApiSince("androidx.core:core-animation-testing:1.0.0-rc01")
     docs("androidx.core:core-google-shortcuts:1.2.0-alpha01")
     docs("androidx.core:core-i18n:1.0.0-alpha01")
-    docs("androidx.core:core-ktx:1.13.0-alpha03")
+    docs("androidx.core:core-ktx:1.13.0-alpha04")
     docs("androidx.core:core-location-altitude:1.0.0-alpha01")
     docs("androidx.core:core-performance:1.0.0")
     docs("androidx.core:core-performance-play-services:1.0.0")
@@ -144,9 +145,9 @@
     docs("androidx.core:core-role:1.2.0-alpha01")
     docs("androidx.core:core-splashscreen:1.1.0-alpha02")
     docs("androidx.core:core-telecom:1.0.0-alpha02")
-    docs("androidx.core:core-testing:1.13.0-alpha03")
-    docs("androidx.core.uwb:uwb:1.0.0-alpha07")
-    docs("androidx.core.uwb:uwb-rxjava3:1.0.0-alpha07")
+    docs("androidx.core:core-testing:1.13.0-alpha04")
+    docs("androidx.core.uwb:uwb:1.0.0-alpha08")
+    docs("androidx.core.uwb:uwb-rxjava3:1.0.0-alpha08")
     docs("androidx.credentials:credentials:1.3.0-alpha01")
     docs("androidx.credentials:credentials-fido:1.0.0-alpha01")
     docs("androidx.credentials:credentials-play-services-auth:1.3.0-alpha01")
@@ -180,9 +181,10 @@
     docs("androidx.enterprise:enterprise-feedback:1.1.0")
     docs("androidx.enterprise:enterprise-feedback-testing:1.1.0")
     docs("androidx.exifinterface:exifinterface:1.3.6")
-    docs("androidx.fragment:fragment:1.7.0-alpha08")
-    docs("androidx.fragment:fragment-ktx:1.7.0-alpha08")
-    docs("androidx.fragment:fragment-testing:1.7.0-alpha08")
+    docs("androidx.fragment:fragment:1.7.0-alpha09")
+    docs("androidx.fragment:fragment-compose:1.7.0-alpha09")
+    docs("androidx.fragment:fragment-ktx:1.7.0-alpha09")
+    docs("androidx.fragment:fragment-testing:1.7.0-alpha09")
     docs("androidx.glance:glance:1.0.0")
     docs("androidx.glance:glance-appwidget:1.0.0")
     samples("androidx.glance:glance-appwidget-samples:1.0.0")
@@ -202,12 +204,12 @@
     samples("androidx.health.connect:connect-client-samples:1.1.0-alpha07")
     docs("androidx.health:health-services-client:1.1.0-alpha02")
     docs("androidx.heifwriter:heifwriter:1.1.0-alpha02")
-    docs("androidx.hilt:hilt-common:1.2.0-alpha01")
-    docs("androidx.hilt:hilt-navigation:1.2.0-alpha01")
-    docs("androidx.hilt:hilt-navigation-compose:1.2.0-alpha01")
-    samples("androidx.hilt:hilt-navigation-compose-samples:1.2.0-alpha01")
-    docs("androidx.hilt:hilt-navigation-fragment:1.2.0-alpha01")
-    docs("androidx.hilt:hilt-work:1.2.0-alpha01")
+    docs("androidx.hilt:hilt-common:1.2.0-beta01")
+    docs("androidx.hilt:hilt-navigation:1.2.0-beta01")
+    docs("androidx.hilt:hilt-navigation-compose:1.2.0-beta01")
+    samples("androidx.hilt:hilt-navigation-compose-samples:1.2.0-beta01")
+    docs("androidx.hilt:hilt-navigation-fragment:1.2.0-beta01")
+    docs("androidx.hilt:hilt-work:1.2.0-beta01")
     docs("androidx.input:input-motionprediction:1.0.0-beta03")
     docs("androidx.interpolator:interpolator:1.0.0")
     docs("androidx.javascriptengine:javascriptengine:1.0.0-beta01")
@@ -216,27 +218,27 @@
     docs("androidx.leanback:leanback-paging:1.1.0-alpha11")
     docs("androidx.leanback:leanback-preference:1.2.0-alpha04")
     docs("androidx.leanback:leanback-tab:1.1.0-beta01")
-    docs("androidx.lifecycle:lifecycle-common:2.7.0")
-    docs("androidx.lifecycle:lifecycle-common-java8:2.7.0")
+    docs("androidx.lifecycle:lifecycle-common:2.8.0-alpha01")
+    docs("androidx.lifecycle:lifecycle-common-java8:2.8.0-alpha01")
     docs("androidx.lifecycle:lifecycle-extensions:2.2.0")
-    docs("androidx.lifecycle:lifecycle-livedata:2.7.0")
-    docs("androidx.lifecycle:lifecycle-livedata-core:2.7.0")
-    docs("androidx.lifecycle:lifecycle-livedata-core-ktx:2.7.0")
-    docs("androidx.lifecycle:lifecycle-livedata-ktx:2.7.0")
-    docs("androidx.lifecycle:lifecycle-process:2.7.0")
-    docs("androidx.lifecycle:lifecycle-reactivestreams:2.7.0")
-    docs("androidx.lifecycle:lifecycle-reactivestreams-ktx:2.7.0")
-    docs("androidx.lifecycle:lifecycle-runtime:2.7.0")
-    docs("androidx.lifecycle:lifecycle-runtime-compose:2.7.0")
-    samples("androidx.lifecycle:lifecycle-runtime-compose-samples:2.7.0")
-    docs("androidx.lifecycle:lifecycle-runtime-ktx:2.7.0")
-    docs("androidx.lifecycle:lifecycle-runtime-testing:2.7.0")
-    docs("androidx.lifecycle:lifecycle-service:2.7.0")
-    docs("androidx.lifecycle:lifecycle-viewmodel:2.7.0")
-    docs("androidx.lifecycle:lifecycle-viewmodel-compose:2.7.0")
-    samples("androidx.lifecycle:lifecycle-viewmodel-compose-samples:2.7.0")
-    docs("androidx.lifecycle:lifecycle-viewmodel-ktx:2.7.0")
-    docs("androidx.lifecycle:lifecycle-viewmodel-savedstate:2.7.0")
+    docs("androidx.lifecycle:lifecycle-livedata:2.8.0-alpha01")
+    docs("androidx.lifecycle:lifecycle-livedata-core:2.8.0-alpha01")
+    docs("androidx.lifecycle:lifecycle-livedata-core-ktx:2.8.0-alpha01")
+    docs("androidx.lifecycle:lifecycle-livedata-ktx:2.8.0-alpha01")
+    docs("androidx.lifecycle:lifecycle-process:2.8.0-alpha01")
+    docs("androidx.lifecycle:lifecycle-reactivestreams:2.8.0-alpha01")
+    docs("androidx.lifecycle:lifecycle-reactivestreams-ktx:2.8.0-alpha01")
+    docs("androidx.lifecycle:lifecycle-runtime:2.8.0-alpha01")
+    docs("androidx.lifecycle:lifecycle-runtime-compose:2.8.0-alpha01")
+    samples("androidx.lifecycle:lifecycle-runtime-compose-samples:2.8.0-alpha01")
+    docs("androidx.lifecycle:lifecycle-runtime-ktx:2.8.0-alpha01")
+    docs("androidx.lifecycle:lifecycle-runtime-testing:2.8.0-alpha01")
+    docs("androidx.lifecycle:lifecycle-service:2.8.0-alpha01")
+    docs("androidx.lifecycle:lifecycle-viewmodel:2.8.0-alpha01")
+    docs("androidx.lifecycle:lifecycle-viewmodel-compose:2.8.0-alpha01")
+    samples("androidx.lifecycle:lifecycle-viewmodel-compose-samples:2.8.0-alpha01")
+    docs("androidx.lifecycle:lifecycle-viewmodel-ktx:2.8.0-alpha01")
+    docs("androidx.lifecycle:lifecycle-viewmodel-savedstate:2.8.0-alpha01")
     docs("androidx.loader:loader:1.1.0")
     // localbroadcastmanager is deprecated
     docsWithoutApiSince("androidx.localbroadcastmanager:localbroadcastmanager:1.1.0")
@@ -274,19 +276,19 @@
     docs("androidx.mediarouter:mediarouter:1.7.0-alpha01")
     docs("androidx.mediarouter:mediarouter-testing:1.7.0-alpha01")
     docs("androidx.metrics:metrics-performance:1.0.0-beta01")
-    docs("androidx.navigation:navigation-common:2.7.6")
-    docs("androidx.navigation:navigation-common-ktx:2.7.6")
-    docs("androidx.navigation:navigation-compose:2.7.6")
-    samples("androidx.navigation:navigation-compose-samples:2.7.6")
-    docs("androidx.navigation:navigation-dynamic-features-fragment:2.7.6")
-    docs("androidx.navigation:navigation-dynamic-features-runtime:2.7.6")
-    docs("androidx.navigation:navigation-fragment:2.7.6")
-    docs("androidx.navigation:navigation-fragment-ktx:2.7.6")
-    docs("androidx.navigation:navigation-runtime:2.7.6")
-    docs("androidx.navigation:navigation-runtime-ktx:2.7.6")
-    docs("androidx.navigation:navigation-testing:2.7.6")
-    docs("androidx.navigation:navigation-ui:2.7.6")
-    docs("androidx.navigation:navigation-ui-ktx:2.7.6")
+    docs("androidx.navigation:navigation-common:2.8.0-alpha01")
+    docs("androidx.navigation:navigation-common-ktx:2.8.0-alpha01")
+    docs("androidx.navigation:navigation-compose:2.8.0-alpha01")
+    samples("androidx.navigation:navigation-compose-samples:2.8.0-alpha01")
+    docs("androidx.navigation:navigation-dynamic-features-fragment:2.8.0-alpha01")
+    docs("androidx.navigation:navigation-dynamic-features-runtime:2.8.0-alpha01")
+    docs("androidx.navigation:navigation-fragment:2.8.0-alpha01")
+    docs("androidx.navigation:navigation-fragment-ktx:2.8.0-alpha01")
+    docs("androidx.navigation:navigation-runtime:2.8.0-alpha01")
+    docs("androidx.navigation:navigation-runtime-ktx:2.8.0-alpha01")
+    docs("androidx.navigation:navigation-testing:2.8.0-alpha01")
+    docs("androidx.navigation:navigation-ui:2.8.0-alpha01")
+    docs("androidx.navigation:navigation-ui-ktx:2.8.0-alpha01")
     docs("androidx.paging:paging-common:3.3.0-alpha01")
     docs("androidx.paging:paging-common-ktx:3.3.0-alpha01")
     kmpDocs("androidx.paging:paging-compose:3.3.0-alpha01")
@@ -308,11 +310,11 @@
     docs("androidx.privacysandbox.activity:activity-client:1.0.0-alpha01")
     docs("androidx.privacysandbox.activity:activity-core:1.0.0-alpha01")
     docs("androidx.privacysandbox.activity:activity-provider:1.0.0-alpha01")
-    docs("androidx.privacysandbox.ads:ads-adservices:1.1.0-beta03")
-    docs("androidx.privacysandbox.ads:ads-adservices-java:1.1.0-beta03")
-    docs("androidx.privacysandbox.sdkruntime:sdkruntime-client:1.0.0-alpha11")
-    docs("androidx.privacysandbox.sdkruntime:sdkruntime-core:1.0.0-alpha11")
-    docs("androidx.privacysandbox.sdkruntime:sdkruntime-provider:1.0.0-alpha11")
+    docs("androidx.privacysandbox.ads:ads-adservices:1.1.0-beta04")
+    docs("androidx.privacysandbox.ads:ads-adservices-java:1.1.0-beta04")
+    docs("androidx.privacysandbox.sdkruntime:sdkruntime-client:1.0.0-alpha12")
+    docs("androidx.privacysandbox.sdkruntime:sdkruntime-core:1.0.0-alpha12")
+    docs("androidx.privacysandbox.sdkruntime:sdkruntime-provider:1.0.0-alpha12")
     docs("androidx.privacysandbox.tools:tools:1.0.0-alpha06")
     docs("androidx.privacysandbox.ui:ui-client:1.0.0-alpha07")
     docs("androidx.privacysandbox.ui:ui-core:1.0.0-alpha07")
@@ -394,44 +396,44 @@
     docs("androidx.versionedparcelable:versionedparcelable:1.2.0")
     docs("androidx.viewpager2:viewpager2:1.1.0-beta02")
     docs("androidx.viewpager:viewpager:1.1.0-alpha01")
-    docs("androidx.wear.compose:compose-foundation:1.3.0-rc01")
-    samples("androidx.wear.compose:compose-foundation-samples:1.3.0-rc01")
-    docs("androidx.wear.compose:compose-material:1.3.0-rc01")
-    docs("androidx.wear.compose:compose-material-core:1.3.0-rc01")
-    samples("androidx.wear.compose:compose-material-samples:1.3.0-rc01")
+    docs("androidx.wear.compose:compose-foundation:1.4.0-alpha01")
+    samples("androidx.wear.compose:compose-foundation-samples:1.4.0-alpha01")
+    docs("androidx.wear.compose:compose-material:1.4.0-alpha01")
+    docs("androidx.wear.compose:compose-material-core:1.4.0-alpha01")
+    samples("androidx.wear.compose:compose-material-samples:1.4.0-alpha01")
     docs("androidx.wear.compose:compose-material3:1.0.0-alpha16")
     samples("androidx.wear.compose:compose-material3-samples:1.3.0-rc01")
-    docs("androidx.wear.compose:compose-navigation:1.3.0-rc01")
-    samples("androidx.wear.compose:compose-navigation-samples:1.3.0-rc01")
-    docs("androidx.wear.compose:compose-ui-tooling:1.3.0-rc01")
-    docs("androidx.wear.protolayout:protolayout:1.1.0-beta01")
-    docs("androidx.wear.protolayout:protolayout-expression:1.1.0-beta01")
-    docs("androidx.wear.protolayout:protolayout-expression-pipeline:1.1.0-beta01")
-    docs("androidx.wear.protolayout:protolayout-material:1.1.0-beta01")
-    docs("androidx.wear.protolayout:protolayout-material-core:1.1.0-beta01")
-    docs("androidx.wear.protolayout:protolayout-renderer:1.1.0-beta01")
-    docs("androidx.wear.tiles:tiles:1.3.0-beta01")
-    docs("androidx.wear.tiles:tiles-material:1.3.0-beta01")
-    docs("androidx.wear.tiles:tiles-renderer:1.3.0-beta01")
-    docs("androidx.wear.tiles:tiles-testing:1.3.0-beta01")
-    docs("androidx.wear.tiles:tiles-tooling:1.3.0-beta01")
-    docs("androidx.wear.tiles:tiles-tooling-preview:1.3.0-beta01")
-    docs("androidx.wear.watchface:watchface:1.2.0")
-    docs("androidx.wear.watchface:watchface-client:1.2.0")
-    docs("androidx.wear.watchface:watchface-client-guava:1.2.0")
-    docs("androidx.wear.watchface:watchface-complications:1.2.0")
-    docs("androidx.wear.watchface:watchface-complications-data:1.2.0")
-    docs("androidx.wear.watchface:watchface-complications-data-source:1.2.0")
-    docs("androidx.wear.watchface:watchface-complications-data-source-ktx:1.2.0")
-    samples("androidx.wear.watchface:watchface-complications-permission-dialogs-sample:1.2.0")
-    docs("androidx.wear.watchface:watchface-complications-rendering:1.2.0")
-    docs("androidx.wear.watchface:watchface-data:1.2.0")
-    docs("androidx.wear.watchface:watchface-editor:1.2.0")
-    docs("androidx.wear.watchface:watchface-editor-guava:1.2.0")
-    samples("androidx.wear.watchface:watchface-editor-samples:1.2.0")
-    docs("androidx.wear.watchface:watchface-guava:1.2.0")
-    samples("androidx.wear.watchface:watchface-samples:1.2.0")
-    docs("androidx.wear.watchface:watchface-style:1.2.0")
+    docs("androidx.wear.compose:compose-navigation:1.4.0-alpha01")
+    samples("androidx.wear.compose:compose-navigation-samples:1.4.0-alpha01")
+    docs("androidx.wear.compose:compose-ui-tooling:1.4.0-alpha01")
+    docs("androidx.wear.protolayout:protolayout:1.1.0-rc01")
+    docs("androidx.wear.protolayout:protolayout-expression:1.1.0-rc01")
+    docs("androidx.wear.protolayout:protolayout-expression-pipeline:1.1.0-rc01")
+    docs("androidx.wear.protolayout:protolayout-material:1.1.0-rc01")
+    docs("androidx.wear.protolayout:protolayout-material-core:1.1.0-rc01")
+    docs("androidx.wear.protolayout:protolayout-renderer:1.1.0-rc01")
+    docs("androidx.wear.tiles:tiles:1.3.0-rc01")
+    docs("androidx.wear.tiles:tiles-material:1.3.0-rc01")
+    docs("androidx.wear.tiles:tiles-renderer:1.3.0-rc01")
+    docs("androidx.wear.tiles:tiles-testing:1.3.0-rc01")
+    docs("androidx.wear.tiles:tiles-tooling:1.3.0-rc01")
+    docs("androidx.wear.tiles:tiles-tooling-preview:1.3.0-rc01")
+    docs("androidx.wear.watchface:watchface:1.2.1")
+    docs("androidx.wear.watchface:watchface-client:1.2.1")
+    docs("androidx.wear.watchface:watchface-client-guava:1.2.1")
+    docs("androidx.wear.watchface:watchface-complications:1.2.1")
+    docs("androidx.wear.watchface:watchface-complications-data:1.2.1")
+    docs("androidx.wear.watchface:watchface-complications-data-source:1.2.1")
+    docs("androidx.wear.watchface:watchface-complications-data-source-ktx:1.2.1")
+    samples("androidx.wear.watchface:watchface-complications-permission-dialogs-sample:1.2.1")
+    docs("androidx.wear.watchface:watchface-complications-rendering:1.2.1")
+    docs("androidx.wear.watchface:watchface-data:1.2.1")
+    docs("androidx.wear.watchface:watchface-editor:1.2.1")
+    docs("androidx.wear.watchface:watchface-editor-guava:1.2.1")
+    samples("androidx.wear.watchface:watchface-editor-samples:1.2.1")
+    docs("androidx.wear.watchface:watchface-guava:1.2.1")
+    samples("androidx.wear.watchface:watchface-samples:1.2.1")
+    docs("androidx.wear.watchface:watchface-style:1.2.1")
     docs("androidx.wear:wear:1.4.0-alpha01")
     stubs(fileTree(dir: "../wear/wear_stubs/", include: ["com.google.android.wearable-stubs.jar"]))
     docs("androidx.wear:wear-input:1.2.0-alpha02")
@@ -443,7 +445,7 @@
     docs("androidx.wear:wear-remote-interactions:1.1.0-alpha02")
     samples("androidx.wear:wear-remote-interactions-samples:1.1.0-alpha02")
     docs("androidx.wear:wear-tooling-preview:1.0.0")
-    docs("androidx.webkit:webkit:1.10.0-rc01")
+    docs("androidx.webkit:webkit:1.10.0")
     docs("androidx.window.extensions.core:core:1.0.0")
     docs("androidx.window:window:1.3.0-alpha01")
     stubs(fileTree(dir: "../window/stubs/", include: ["window-sidecar-release-0.1.0-alpha01.aar"]))
@@ -454,13 +456,13 @@
     docs("androidx.window:window-rxjava3:1.3.0-alpha01")
     samples("androidx.window:window-samples:1.3.0-alpha01")
     docs("androidx.window:window-testing:1.3.0-alpha01")
-    docs("androidx.work:work-gcm:2.9.0")
-    docs("androidx.work:work-multiprocess:2.9.0")
-    docs("androidx.work:work-runtime:2.9.0")
-    docs("androidx.work:work-runtime-ktx:2.9.0")
-    docs("androidx.work:work-rxjava2:2.9.0")
-    docs("androidx.work:work-rxjava3:2.9.0")
-    docs("androidx.work:work-testing:2.9.0")
+    docs("androidx.work:work-gcm:2.10.0-alpha01")
+    docs("androidx.work:work-multiprocess:2.10.0-alpha01")
+    docs("androidx.work:work-runtime:2.10.0-alpha01")
+    docs("androidx.work:work-runtime-ktx:2.10.0-alpha01")
+    docs("androidx.work:work-rxjava2:2.10.0-alpha01")
+    docs("androidx.work:work-rxjava3:2.10.0-alpha01")
+    docs("androidx.work:work-testing:2.10.0-alpha01")
 
     // Force upgrade to jsoup 1.16.2 (b/309773103)
     stubs("org.jsoup:jsoup:1.16.2")
diff --git a/emoji2/emoji2-emojipicker/build.gradle b/emoji2/emoji2-emojipicker/build.gradle
index e59722e..bb83bfe 100644
--- a/emoji2/emoji2-emojipicker/build.gradle
+++ b/emoji2/emoji2-emojipicker/build.gradle
@@ -34,6 +34,7 @@
     implementation(libs.kotlinStdlib)
     implementation(libs.kotlinCoroutinesAndroid)
     implementation(libs.kotlinCoroutinesGuava)
+    implementation("androidx.appcompat:appcompat:1.6.1")
     implementation("androidx.core:core-ktx:1.9.0")
     implementation("androidx.emoji2:emoji2:1.2.0")
     implementation("androidx.recyclerview:recyclerview:1.2.1")
diff --git a/emoji2/emoji2-emojipicker/src/main/java/androidx/emoji2/emojipicker/EmojiPickerPopupView.kt b/emoji2/emoji2-emojipicker/src/main/java/androidx/emoji2/emojipicker/EmojiPickerPopupView.kt
index dd90bdf..3c1f944 100644
--- a/emoji2/emoji2-emojipicker/src/main/java/androidx/emoji2/emojipicker/EmojiPickerPopupView.kt
+++ b/emoji2/emoji2-emojipicker/src/main/java/androidx/emoji2/emojipicker/EmojiPickerPopupView.kt
@@ -20,11 +20,13 @@
 import android.graphics.Canvas
 import android.graphics.Paint
 import android.util.AttributeSet
+import android.view.Gravity
 import android.view.View
 import android.view.ViewGroup
 import android.view.accessibility.AccessibilityEvent
 import android.widget.FrameLayout
-import android.widget.LinearLayout;
+import android.widget.LinearLayout
+import androidx.appcompat.widget.AppCompatImageView
 import androidx.core.content.ContextCompat
 
 /** Popup view for emoji picker to show emoji variants. */
@@ -38,13 +40,21 @@
 ) :
     FrameLayout(context, attrs, defStyleAttr) {
     private val popupView: LinearLayout
-    private val layoutTemplate: LayoutTemplate
+    private var layoutTemplate: LayoutTemplate
+    private var emojiFacingLeft = true
 
     init {
         popupView = inflate(context, R.layout.variant_popup, /* root= */ null)
             .findViewById<LinearLayout>(R.id.variant_popup)
-
         layoutTemplate = getLayoutTemplate(variants)
+        if (layoutTemplate.layout == Layout.BIDIRECTIONAL) {
+            addBidirectionalLayoutHeader(popupView)
+        }
+        addRowsToPopupView()
+        addView(popupView)
+    }
+
+    private fun addRowsToPopupView() {
         for (row in layoutTemplate.template) {
             val rowLayout = LinearLayout(context).apply {
                 orientation = LinearLayout.HORIZONTAL
@@ -84,7 +94,6 @@
             }
             popupView.addView(rowLayout)
         }
-        addView(popupView)
     }
 
     fun getPopupViewWidth(): Int {
@@ -93,7 +102,9 @@
     }
 
     fun getPopupViewHeight(): Int {
-        return layoutTemplate.numberOfRows * targetEmojiView.height +
+        val numberOfRows = if (layoutTemplate.layout == Layout.BIDIRECTIONAL)
+            layoutTemplate.numberOfRows + 1 else layoutTemplate.numberOfRows
+        return numberOfRows * targetEmojiView.height +
             popupView.paddingTop + popupView.paddingBottom
     }
 
@@ -103,19 +114,28 @@
                 if (SQUARE_LAYOUT_EMOJI_NO_SKIN_TONE.contains(variants[0]))
                     Layout.SQUARE
                 else Layout.SQUARE_WITH_SKIN_TONE_CIRCLE
-            else Layout.FLAT
+            else if (variants.size == BIDIRECTIONAL_VARIANTS_COUNT)
+                Layout.BIDIRECTIONAL
+            else
+                Layout.FLAT
         var template = when (layout) {
             Layout.SQUARE -> SQUARE_LAYOUT_TEMPLATE
             Layout.SQUARE_WITH_SKIN_TONE_CIRCLE -> SQUARE_LAYOUT_WITH_SKIN_TONES_TEMPLATE
             Layout.FLAT -> arrayOf(variants.indices.map { it + 1 }.toIntArray())
+            Layout.BIDIRECTIONAL ->
+                if (emojiFacingLeft)
+                    arrayOf((variants.indices.filter { it % 12 < 6 }.map { it + 1 }).toIntArray())
+                else
+                    arrayOf((variants.indices.filter { it % 12 >= 6 }.map { it + 1 }).toIntArray())
         }
         val column = when (layout) {
             Layout.SQUARE, Layout.SQUARE_WITH_SKIN_TONE_CIRCLE -> template[0].size
-            Layout.FLAT -> minOf(6, template[0].size)
+            Layout.FLAT, Layout.BIDIRECTIONAL -> minOf(6, template[0].size)
         }
         val row = when (layout) {
             Layout.SQUARE, Layout.SQUARE_WITH_SKIN_TONE_CIRCLE -> template.size
             Layout.FLAT -> variants.size / column + if (variants.size % column == 0) 0 else 1
+            Layout.BIDIRECTIONAL -> variants.size / 2 / column
         }
 
         // Rewrite template when the number of row mismatch
@@ -132,17 +152,42 @@
             }
             template = overrideTemplate
         }
-        return LayoutTemplate(template, row, column)
+        return LayoutTemplate(layout, template, row, column)
     }
 
     private data class LayoutTemplate(
+        var layout: Layout,
         val template: Array<IntArray>,
         val numberOfRows: Int,
         val numberOfColumns: Int
     )
 
+    private fun addBidirectionalLayoutHeader(popupView: LinearLayout) {
+        val row = LinearLayout(context).apply {
+            orientation = LinearLayout.HORIZONTAL
+            gravity = Gravity.CENTER
+            layoutParams = LinearLayout.LayoutParams(
+                LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
+        }
+        inflate(context, R.layout.emoji_picker_popup_bidirectional, row)
+            .findViewById<AppCompatImageView>(R.id.emoji_picker_popup_bidirectional_icon)
+            .apply {
+                layoutParams = LinearLayout.LayoutParams(
+                    targetEmojiView.width, targetEmojiView.height)
+            }
+        popupView.addView(row)
+        val imageView =
+            row.findViewById<AppCompatImageView>(R.id.emoji_picker_popup_bidirectional_icon)
+        imageView.setOnClickListener {
+            emojiFacingLeft = !emojiFacingLeft
+            layoutTemplate = getLayoutTemplate(variants)
+            popupView.removeViews( /* start= */1, layoutTemplate.numberOfRows)
+            addRowsToPopupView()
+        }
+    }
+
     companion object {
-        private enum class Layout { FLAT, SQUARE, SQUARE_WITH_SKIN_TONE_CIRCLE }
+        private enum class Layout { FLAT, SQUARE, SQUARE_WITH_SKIN_TONE_CIRCLE, BIDIRECTIONAL }
 
         /**
          * The number of variants expected when using a square layout strategy. Square layouts are
@@ -150,6 +195,14 @@
          */
         private const val SQUARE_LAYOUT_VARIANT_COUNT = 26
 
+        /**
+         * The number of variants expected when using a bidirectional layout strategy. Bidirectional
+         * layouts are comprised of bidirectional icon and a 3x6 grid with left direction emojis as
+         * default. After clicking the bidirectional icon, it switches to a bidirectional icon and a 3x6
+         * grid with right direction emojis.
+         */
+        private const val BIDIRECTIONAL_VARIANTS_COUNT = 36
+
         // Set of emojis that use the square layout without skin tone swatches.
         private val SQUARE_LAYOUT_EMOJI_NO_SKIN_TONE = setOf("👪")
 
diff --git a/emoji2/emoji2-emojipicker/src/main/res/drawable/ripple_image_view.xml b/emoji2/emoji2-emojipicker/src/main/res/drawable/ripple_image_view.xml
new file mode 100644
index 0000000..4c0c3a4
--- /dev/null
+++ b/emoji2/emoji2-emojipicker/src/main/res/drawable/ripple_image_view.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.
+  -->
+
+<ripple xmlns:android="http://schemas.android.com/apk/res/android"
+    android:color="?android:colorControlHighlight">
+    <item android:id="@android:id/mask">
+        <shape android:shape="rectangle">
+            <solid android:color="@color/white"/>
+            <corners android:radius="12dp"/>
+        </shape>
+    </item>
+    <item>
+        <selector>
+            <item android:state_selected="true">
+                <shape android:shape="rectangle">
+                    <solid android:color="?android:colorControlHighlight" />
+                    <corners android:radius="12dp"/>
+                </shape>
+            </item>
+        </selector>
+    </item>
+</ripple>
diff --git a/emoji2/emoji2-emojipicker/src/main/res/drawable/swap_horiz_vd_theme_24.xml b/emoji2/emoji2-emojipicker/src/main/res/drawable/swap_horiz_vd_theme_24.xml
new file mode 100644
index 0000000..e3684d4
--- /dev/null
+++ b/emoji2/emoji2-emojipicker/src/main/res/drawable/swap_horiz_vd_theme_24.xml
@@ -0,0 +1,26 @@
+<!--
+  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.
+  -->
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="24dp"
+    android:height="24dp"
+    android:viewportWidth="24"
+    android:viewportHeight="24"
+    android:tint="?attr/colorAccent">
+    <path
+        android:fillColor="@android:color/white"
+        android:pathData="M6.99,11L3,15l3.99,4v-3H14v-2H6.99v-3zM21,9l-3.99,-4v3H10v2h7.01v3L21,9z"/>
+</vector>
diff --git a/emoji2/emoji2-emojipicker/src/main/res/layout/emoji_picker_popup_bidirectional.xml b/emoji2/emoji2-emojipicker/src/main/res/layout/emoji_picker_popup_bidirectional.xml
new file mode 100644
index 0000000..be0c3df
--- /dev/null
+++ b/emoji2/emoji2-emojipicker/src/main/res/layout/emoji_picker_popup_bidirectional.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.
+  -->
+<androidx.appcompat.widget.AppCompatImageView
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/emoji_picker_popup_bidirectional_icon"
+    android:layout_width="0dp"
+    android:layout_height="0dp"
+    android:src="@drawable/swap_horiz_vd_theme_24"
+    android:layout_gravity="center"
+    android:contentDescription="@string/emoji_bidirectional_switcher_content_desc"
+    android:background="@drawable/ripple_image_view"
+    android:importantForAccessibility="yes" />
diff --git a/emoji2/emoji2-emojipicker/src/main/res/layout/header_icon_holder.xml b/emoji2/emoji2-emojipicker/src/main/res/layout/header_icon_holder.xml
index 1635260..dd4ba74 100644
--- a/emoji2/emoji2-emojipicker/src/main/res/layout/header_icon_holder.xml
+++ b/emoji2/emoji2-emojipicker/src/main/res/layout/header_icon_holder.xml
@@ -16,6 +16,7 @@
   -->
 
 <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
     android:layout_width="@dimen/emoji_picker_header_icon_holder_width"
     android:layout_height="match_parent"
     android:background="?android:attr/selectableItemBackground"
@@ -25,8 +26,8 @@
         android:layout_width="@dimen/emoji_picker_header_icon_width"
         android:layout_height="@dimen/emoji_picker_header_icon_height"
         android:gravity="center"
-        android:tint="@drawable/icon_tint_selector"
-        android:layout_gravity="center"/>
+        android:layout_gravity="center"
+        app:tint="@drawable/icon_tint_selector" />
     <View
         android:id="@+id/emoji_picker_header_underline"
         android:layout_width="@dimen/emoji_picker_header_icon_underline_width"
diff --git a/emoji2/emoji2-emojipicker/src/main/res/raw/emoji_category_animals_nature.csv b/emoji2/emoji2-emojipicker/src/main/res/raw/emoji_category_animals_nature.csv
index c88986d..40a3994 100644
--- a/emoji2/emoji2-emojipicker/src/main/res/raw/emoji_category_animals_nature.csv
+++ b/emoji2/emoji2-emojipicker/src/main/res/raw/emoji_category_animals_nature.csv
@@ -52,11 +52,11 @@


 💧
+☁️
+🌨️
 🌧️
 🌩️
 ⛈️
-🌨️
-☁️
 🌦️
 🌥️

@@ -184,6 +184,7 @@
 🪿
 🦩
 🦚
+🐦‍🔥
 🦃
 🐧
 🦭
diff --git a/emoji2/emoji2-emojipicker/src/main/res/raw/emoji_category_emotions.csv b/emoji2/emoji2-emojipicker/src/main/res/raw/emoji_category_emotions.csv
index 0a5d0d4..176daa6 100644
--- a/emoji2/emoji2-emojipicker/src/main/res/raw/emoji_category_emotions.csv
+++ b/emoji2/emoji2-emojipicker/src/main/res/raw/emoji_category_emotions.csv
@@ -24,9 +24,9 @@
 😊
 ☺️
 😌
+🙂‍↕️
+🙂‍↔️
 😏
-😴
-😪
 🤤
 😋
 😛
@@ -37,11 +37,11 @@
 😔
 🥺
 😬
-🫥
 😑
 😐
 😶
 😶‍🌫️
+🫥
 🤐
 🫡
 🤔
@@ -90,6 +90,8 @@
 🥵
 🤢
 🤮
+😴
+😪
 🤧
 🤒
 🤕
@@ -105,31 +107,20 @@
 😈
 👿
 👻
+💀
+☠️
+👹
+👺
 🎃
 💩
 🤖
 👽
 👾
-🌛
-🌜
 🌚
 🌝
 🌞
-☠️
-👹
-👺
-🔥
-💯
-💫
-⭐
-🌟
-✨
-💥
-💨
-💦
-💤
-🕳️
-🎉
+🌛
+🌜
 🙈
 🙉
 🙊
@@ -142,6 +133,18 @@
 🙀
 😿
 😾
+💫
+⭐
+🌟
+✨
+💥
+💨
+💦
+💤
+🕳️
+🔥
+💯
+🎉
 ❤️
 🧡
 💛
@@ -181,7 +184,6 @@
 🦠
 🦷
 🦴
-💀
 👀
 👁️
 👄
@@ -202,7 +204,6 @@
 🙌,🙌,🙌🏻,🙌🏼,🙌🏽,🙌🏾,🙌🏿
 👐,👐,👐🏻,👐🏼,👐🏽,👐🏾,👐🏿
 🤲,🤲,🤲🏻,🤲🏼,🤲🏽,🤲🏾,🤲🏿
-🤝,🤝,🤝🏻,🫱🏻‍🫲🏼,🫱🏻‍🫲🏽,🫱🏻‍🫲🏾,🫱🏻‍🫲🏿,🫱🏼‍🫲🏻,🤝🏼,🫱🏼‍🫲🏽,🫱🏼‍🫲🏾,🫱🏼‍🫲🏿,🫱🏽‍🫲🏻,🫱🏽‍🫲🏼,🤝🏽,🫱🏽‍🫲🏾,🫱🏽‍🫲🏿,🫱🏾‍🫲🏻,🫱🏾‍🫲🏼,🫱🏾‍🫲🏽,🤝🏾,🫱🏾‍🫲🏿,🫱🏿‍🫲🏻,🫱🏿‍🫲🏼,🫱🏿‍🫲🏽,🫱🏿‍🫲🏾,🤝🏿
 🤜,🤜,🤜🏻,🤜🏼,🤜🏽,🤜🏾,🤜🏿
 🤛,🤛,🤛🏻,🤛🏼,🤛🏽,🤛🏾,🤛🏿
 ✊,✊,✊🏻,✊🏼,✊🏽,✊🏾,✊🏿
@@ -238,3 +239,4 @@
 🤳,🤳,🤳🏻,🤳🏼,🤳🏽,🤳🏾,🤳🏿
 🙏,🙏,🙏🏻,🙏🏼,🙏🏽,🙏🏾,🙏🏿
 💅,💅,💅🏻,💅🏼,💅🏽,💅🏾,💅🏿
+🤝,🤝,🤝🏻,🫱🏻‍🫲🏼,🫱🏻‍🫲🏽,🫱🏻‍🫲🏾,🫱🏻‍🫲🏿,🫱🏼‍🫲🏻,🤝🏼,🫱🏼‍🫲🏽,🫱🏼‍🫲🏾,🫱🏼‍🫲🏿,🫱🏽‍🫲🏻,🫱🏽‍🫲🏼,🤝🏽,🫱🏽‍🫲🏾,🫱🏽‍🫲🏿,🫱🏾‍🫲🏻,🫱🏾‍🫲🏼,🫱🏾‍🫲🏽,🤝🏾,🫱🏾‍🫲🏿,🫱🏿‍🫲🏻,🫱🏿‍🫲🏼,🫱🏿‍🫲🏽,🫱🏿‍🫲🏾,🤝🏿
diff --git a/emoji2/emoji2-emojipicker/src/main/res/raw/emoji_category_food_drink.csv b/emoji2/emoji2-emojipicker/src/main/res/raw/emoji_category_food_drink.csv
index 59e6561..8a15f1e4 100644
--- a/emoji2/emoji2-emojipicker/src/main/res/raw/emoji_category_food_drink.csv
+++ b/emoji2/emoji2-emojipicker/src/main/res/raw/emoji_category_food_drink.csv
@@ -8,6 +8,7 @@
 🍍
 🍌
 🍋
+🍋‍🟩
 🍈
 🍏
 🍐
@@ -20,7 +21,6 @@
 🌶️
 🫚
 🥕
-🍠
 🧅
 🌽
 🥦
@@ -29,9 +29,11 @@
 🫛
 🫑
 🥑
+🍠
 🍆
 🧄
 🥔
+🍄‍🟫
 🫘
 🌰
 🥜
diff --git a/emoji2/emoji2-emojipicker/src/main/res/raw/emoji_category_objects.csv b/emoji2/emoji2-emojipicker/src/main/res/raw/emoji_category_objects.csv
index fd77bf0..32c4a4f 100644
--- a/emoji2/emoji2-emojipicker/src/main/res/raw/emoji_category_objects.csv
+++ b/emoji2/emoji2-emojipicker/src/main/res/raw/emoji_category_objects.csv
@@ -137,6 +137,7 @@
 🛠️
 ⛏️
 ⚙️
+⛓️‍💥
 🔗
 ⛓️
 📎
@@ -236,6 +237,9 @@
 📯
 📢
 📣
+🔈
+🔉
+🔊
 🔍
 🔎
 🔮
diff --git a/emoji2/emoji2-emojipicker/src/main/res/raw/emoji_category_people_gender_inclusive.csv b/emoji2/emoji2-emojipicker/src/main/res/raw/emoji_category_people_gender_inclusive.csv
index 6927525..ec86a37 100644
--- a/emoji2/emoji2-emojipicker/src/main/res/raw/emoji_category_people_gender_inclusive.csv
+++ b/emoji2/emoji2-emojipicker/src/main/res/raw/emoji_category_people_gender_inclusive.csv
@@ -14,20 +14,20 @@
 🛀,🛀,🛀🏻,🛀🏼,🛀🏽,🛀🏾,🛀🏿
 🛌,🛌,🛌🏻,🛌🏼,🛌🏽,🛌🏾,🛌🏿
 🧘,🧘,🧘🏻,🧘🏼,🧘🏽,🧘🏾,🧘🏿,🧘‍♀️,🧘🏻‍♀️,🧘🏼‍♀️,🧘🏽‍♀️,🧘🏾‍♀️,🧘🏿‍♀️,🧘‍♂️,🧘🏻‍♂️,🧘🏼‍♂️,🧘🏽‍♂️,🧘🏾‍♂️,🧘🏿‍♂️
-🧑‍🦯,🧑‍🦯,🧑🏻‍🦯,🧑🏼‍🦯,🧑🏽‍🦯,🧑🏾‍🦯,🧑🏿‍🦯,👩‍🦯,👩🏻‍🦯,👩🏼‍🦯,👩🏽‍🦯,👩🏾‍🦯,👩🏿‍🦯,👨‍🦯,👨🏻‍🦯,👨🏼‍🦯,👨🏽‍🦯,👨🏾‍🦯,👨🏿‍🦯
-🧑‍🦼,🧑‍🦼,🧑🏻‍🦼,🧑🏼‍🦼,🧑🏽‍🦼,🧑🏾‍🦼,🧑🏿‍🦼,👩‍🦼,👩🏻‍🦼,👩🏼‍🦼,👩🏽‍🦼,👩🏾‍🦼,👩🏿‍🦼,👨‍🦼,👨🏻‍🦼,👨🏼‍🦼,👨🏽‍🦼,👨🏾‍🦼,👨🏿‍🦼
-🧑‍🦽,🧑‍🦽,🧑🏻‍🦽,🧑🏼‍🦽,🧑🏽‍🦽,🧑🏾‍🦽,🧑🏿‍🦽,👩‍🦽,👩🏻‍🦽,👩🏼‍🦽,👩🏽‍🦽,👩🏾‍🦽,👩🏿‍🦽,👨‍🦽,👨🏻‍🦽,👨🏼‍🦽,👨🏽‍🦽,👨🏾‍🦽,👨🏿‍🦽
-🧎,🧎,🧎🏻,🧎🏼,🧎🏽,🧎🏾,🧎🏿,🧎‍♀️,🧎🏻‍♀️,🧎🏼‍♀️,🧎🏽‍♀️,🧎🏾‍♀️,🧎🏿‍♀️,🧎‍♂️,🧎🏻‍♂️,🧎🏼‍♂️,🧎🏽‍♂️,🧎🏾‍♂️,🧎🏿‍♂️
 🧍,🧍,🧍🏻,🧍🏼,🧍🏽,🧍🏾,🧍🏿,🧍‍♀️,🧍🏻‍♀️,🧍🏼‍♀️,🧍🏽‍♀️,🧍🏾‍♀️,🧍🏿‍♀️,🧍‍♂️,🧍🏻‍♂️,🧍🏼‍♂️,🧍🏽‍♂️,🧍🏾‍♂️,🧍🏿‍♂️
-🚶,🚶,🚶🏻,🚶🏼,🚶🏽,🚶🏾,🚶🏿,🚶‍♀️,🚶🏻‍♀️,🚶🏼‍♀️,🚶🏽‍♀️,🚶🏾‍♀️,🚶🏿‍♀️,🚶‍♂️,🚶🏻‍♂️,🚶🏼‍♂️,🚶🏽‍♂️,🚶🏾‍♂️,🚶🏿‍♂️
-🏃,🏃,🏃🏻,🏃🏼,🏃🏽,🏃🏾,🏃🏿,🏃‍♀️,🏃🏻‍♀️,🏃🏼‍♀️,🏃🏽‍♀️,🏃🏾‍♀️,🏃🏿‍♀️,🏃‍♂️,🏃🏻‍♂️,🏃🏼‍♂️,🏃🏽‍♂️,🏃🏾‍♂️,🏃🏿‍♂️
 🤸,🤸,🤸🏻,🤸🏼,🤸🏽,🤸🏾,🤸🏿,🤸‍♀️,🤸🏻‍♀️,🤸🏼‍♀️,🤸🏽‍♀️,🤸🏾‍♀️,🤸🏿‍♀️,🤸‍♂️,🤸🏻‍♂️,🤸🏼‍♂️,🤸🏽‍♂️,🤸🏾‍♂️,🤸🏿‍♂️
-🏋️,🏋️,🏋🏻,🏋🏼,🏋🏽,🏋🏾,🏋🏿,🏋️‍♀️,🏋🏻‍♀️,🏋🏼‍♀️,🏋🏽‍♀️,🏋🏾‍♀️,🏋🏿‍♀️,🏋️‍♂️,🏋🏻‍♂️,🏋🏼‍♂️,🏋🏽‍♂️,🏋🏾‍♂️,🏋🏿‍♂️
+🧎,🧎,🧎🏻,🧎🏼,🧎🏽,🧎🏾,🧎🏿,🧎‍➡️,🧎🏻‍➡️,🧎🏼‍➡️,🧎🏽‍➡️,🧎🏾‍➡️,🧎🏿‍➡️,🧎‍♀️,🧎🏻‍♀️,🧎🏼‍♀️,🧎🏽‍♀️,🧎🏾‍♀️,🧎🏿‍♀️,🧎‍♀️‍➡️,🧎🏻‍♀️‍➡️,🧎🏼‍♀️‍➡️,🧎🏽‍♀️‍➡️,🧎🏾‍♀️‍➡️,🧎🏿‍♀️‍➡️,🧎‍♂️,🧎🏻‍♂️,🧎🏼‍♂️,🧎🏽‍♂️,🧎🏾‍♂️,🧎🏿‍♂️,🧎‍♂️‍➡️,🧎🏻‍♂️‍➡️,🧎🏼‍♂️‍➡️,🧎🏽‍♂️‍➡️,🧎🏾‍♂️‍➡️,🧎🏿‍♂️‍➡️
+🧑‍🦼,🧑‍🦼,🧑🏻‍🦼,🧑🏼‍🦼,🧑🏽‍🦼,🧑🏾‍🦼,🧑🏿‍🦼,🧑‍🦼‍➡️,🧑🏻‍🦼‍➡️,🧑🏼‍🦼‍➡️,🧑🏽‍🦼‍➡️,🧑🏾‍🦼‍➡️,🧑🏿‍🦼‍➡️,👩‍🦼,👩🏻‍🦼,👩🏼‍🦼,👩🏽‍🦼,👩🏾‍🦼,👩🏿‍🦼,👩‍🦼‍➡️,👩🏻‍🦼‍➡️,👩🏼‍🦼‍➡️,👩🏽‍🦼‍➡️,👩🏾‍🦼‍➡️,👩🏿‍🦼‍➡️,👨‍🦼,👨🏻‍🦼,👨🏼‍🦼,👨🏽‍🦼,👨🏾‍🦼,👨🏿‍🦼,👨‍🦼‍➡️,👨🏻‍🦼‍➡️,👨🏼‍🦼‍➡️,👨🏽‍🦼‍➡️,👨🏾‍🦼‍➡️,👨🏿‍🦼‍➡️
+🧑‍🦽,🧑‍🦽,🧑🏻‍🦽,🧑🏼‍🦽,🧑🏽‍🦽,🧑🏾‍🦽,🧑🏿‍🦽,🧑‍🦽‍➡️,🧑🏻‍🦽‍➡️,🧑🏼‍🦽‍➡️,🧑🏽‍🦽‍➡️,🧑🏾‍🦽‍➡️,🧑🏿‍🦽‍➡️,👩‍🦽,👩🏻‍🦽,👩🏼‍🦽,👩🏽‍🦽,👩🏾‍🦽,👩🏿‍🦽,👩‍🦽‍➡️,👩🏻‍🦽‍➡️,👩🏼‍🦽‍➡️,👩🏽‍🦽‍➡️,👩🏾‍🦽‍➡️,👩🏿‍🦽‍➡️,👨‍🦽,👨🏻‍🦽,👨🏼‍🦽,👨🏽‍🦽,👨🏾‍🦽,👨🏿‍🦽,👨‍🦽‍➡️,👨🏻‍🦽‍➡️,👨🏼‍🦽‍➡️,👨🏽‍🦽‍➡️,👨🏾‍🦽‍➡️,👨🏿‍🦽‍➡️
+🧑‍🦯,🧑‍🦯,🧑🏻‍🦯,🧑🏼‍🦯,🧑🏽‍🦯,🧑🏾‍🦯,🧑🏿‍🦯,🧑‍🦯‍➡️,🧑🏻‍🦯‍➡️,🧑🏼‍🦯‍➡️,🧑🏽‍🦯‍➡️,🧑🏾‍🦯‍➡️,🧑🏿‍🦯‍➡️,👩‍🦯,👩🏻‍🦯,👩🏼‍🦯,👩🏽‍🦯,👩🏾‍🦯,👩🏿‍🦯,👩‍🦯‍➡️,👩🏻‍🦯‍➡️,👩🏼‍🦯‍➡️,👩🏽‍🦯‍➡️,👩🏾‍🦯‍➡️,👩🏿‍🦯‍➡️,👨‍🦯,👨🏻‍🦯,👨🏼‍🦯,👨🏽‍🦯,👨🏾‍🦯,👨🏿‍🦯,👨‍🦯‍➡️,👨🏻‍🦯‍➡️,👨🏼‍🦯‍➡️,👨🏽‍🦯‍➡️,👨🏾‍🦯‍➡️,👨🏿‍🦯‍➡️
+🚶,🚶,🚶🏻,🚶🏼,🚶🏽,🚶🏾,🚶🏿,🚶‍➡️,🚶🏻‍➡️,🚶🏼‍➡️,🚶🏽‍➡️,🚶🏾‍➡️,🚶🏿‍➡️,🚶‍♀️,🚶🏻‍♀️,🚶🏼‍♀️,🚶🏽‍♀️,🚶🏾‍♀️,🚶🏿‍♀️,🚶‍♀️‍➡️,🚶🏻‍♀️‍➡️,🚶🏼‍♀️‍➡️,🚶🏽‍♀️‍➡️,🚶🏾‍♀️‍➡️,🚶🏿‍♀️‍➡️,🚶‍♂️,🚶🏻‍♂️,🚶🏼‍♂️,🚶🏽‍♂️,🚶🏾‍♂️,🚶🏿‍♂️,🚶‍♂️‍➡️,🚶🏻‍♂️‍➡️,🚶🏼‍♂️‍➡️,🚶🏽‍♂️‍➡️,🚶🏾‍♂️‍➡️,🚶🏿‍♂️‍➡️
+🏃,🏃,🏃🏻,🏃🏼,🏃🏽,🏃🏾,🏃🏿,🏃‍➡️,🏃🏻‍➡️,🏃🏼‍➡️,🏃🏽‍➡️,🏃🏾‍➡️,🏃🏿‍➡️,🏃‍♀️,🏃🏻‍♀️,🏃🏼‍♀️,🏃🏽‍♀️,🏃🏾‍♀️,🏃🏿‍♀️,🏃‍♀️‍➡️,🏃🏻‍♀️‍➡️,🏃🏼‍♀️‍➡️,🏃🏽‍♀️‍➡️,🏃🏾‍♀️‍➡️,🏃🏿‍♀️‍➡️,🏃‍♂️,🏃🏻‍♂️,🏃🏼‍♂️,🏃🏽‍♂️,🏃🏾‍♂️,🏃🏿‍♂️,🏃‍♂️‍➡️,🏃🏻‍♂️‍➡️,🏃🏼‍♂️‍➡️,🏃🏽‍♂️‍➡️,🏃🏾‍♂️‍➡️,🏃🏿‍♂️‍➡️
 ⛹️,⛹️,⛹🏻,⛹🏼,⛹🏽,⛹🏾,⛹🏿,⛹️‍♀️,⛹🏻‍♀️,⛹🏼‍♀️,⛹🏽‍♀️,⛹🏾‍♀️,⛹🏿‍♀️,⛹️‍♂️,⛹🏻‍♂️,⛹🏼‍♂️,⛹🏽‍♂️,⛹🏾‍♂️,⛹🏿‍♂️
 🤾,🤾,🤾🏻,🤾🏼,🤾🏽,🤾🏾,🤾🏿,🤾‍♀️,🤾🏻‍♀️,🤾🏼‍♀️,🤾🏽‍♀️,🤾🏾‍♀️,🤾🏿‍♀️,🤾‍♂️,🤾🏻‍♂️,🤾🏼‍♂️,🤾🏽‍♂️,🤾🏾‍♂️,🤾🏿‍♂️
 🚴,🚴,🚴🏻,🚴🏼,🚴🏽,🚴🏾,🚴🏿,🚴‍♀️,🚴🏻‍♀️,🚴🏼‍♀️,🚴🏽‍♀️,🚴🏾‍♀️,🚴🏿‍♀️,🚴‍♂️,🚴🏻‍♂️,🚴🏼‍♂️,🚴🏽‍♂️,🚴🏾‍♂️,🚴🏿‍♂️
 🚵,🚵,🚵🏻,🚵🏼,🚵🏽,🚵🏾,🚵🏿,🚵‍♀️,🚵🏻‍♀️,🚵🏼‍♀️,🚵🏽‍♀️,🚵🏾‍♀️,🚵🏿‍♀️,🚵‍♂️,🚵🏻‍♂️,🚵🏼‍♂️,🚵🏽‍♂️,🚵🏾‍♂️,🚵🏿‍♂️
 🧗,🧗,🧗🏻,🧗🏼,🧗🏽,🧗🏾,🧗🏿,🧗‍♀️,🧗🏻‍♀️,🧗🏼‍♀️,🧗🏽‍♀️,🧗🏾‍♀️,🧗🏿‍♀️,🧗‍♂️,🧗🏻‍♂️,🧗🏼‍♂️,🧗🏽‍♂️,🧗🏾‍♂️,🧗🏿‍♂️
+🏋️,🏋️,🏋🏻,🏋🏼,🏋🏽,🏋🏾,🏋🏿,🏋️‍♀️,🏋🏻‍♀️,🏋🏼‍♀️,🏋🏽‍♀️,🏋🏾‍♀️,🏋🏿‍♀️,🏋️‍♂️,🏋🏻‍♂️,🏋🏼‍♂️,🏋🏽‍♂️,🏋🏾‍♂️,🏋🏿‍♂️
 🤼,🤼,🤼‍♀️,🤼‍♂️
 🤹,🤹,🤹🏻,🤹🏼,🤹🏽,🤹🏾,🤹🏿,🤹‍♀️,🤹🏻‍♀️,🤹🏼‍♀️,🤹🏽‍♀️,🤹🏾‍♀️,🤹🏿‍♀️,🤹‍♂️,🤹🏻‍♂️,🤹🏼‍♂️,🤹🏽‍♂️,🤹🏾‍♂️,🤹🏿‍♂️
 🏌️,🏌️,🏌🏻,🏌🏼,🏌🏽,🏌🏾,🏌🏿,🏌️‍♀️,🏌🏻‍♀️,🏌🏼‍♀️,🏌🏽‍♀️,🏌🏾‍♀️,🏌🏿‍♀️,🏌️‍♂️,🏌🏻‍♂️,🏌🏼‍♂️,🏌🏽‍♂️,🏌🏾‍♂️,🏌🏿‍♂️
@@ -108,4 +108,3 @@
 🫄,🫄,🫄🏻,🫄🏼,🫄🏽,🫄🏾,🫄🏿,🤰,🤰🏻,🤰🏼,🤰🏽,🤰🏾,🤰🏿,🫃,🫃🏻,🫃🏼,🫃🏽,🫃🏾,🫃🏿
 🤱,🤱,🤱🏻,🤱🏼,🤱🏽,🤱🏾,🤱🏿
 🧑‍🍼,🧑‍🍼,🧑🏻‍🍼,🧑🏼‍🍼,🧑🏽‍🍼,🧑🏾‍🍼,🧑🏿‍🍼,👩‍🍼,👩🏻‍🍼,👩🏼‍🍼,👩🏽‍🍼,👩🏾‍🍼,👩🏿‍🍼,👨‍🍼,👨🏻‍🍼,👨🏼‍🍼,👨🏽‍🍼,👨🏾‍🍼,👨🏿‍🍼
-👪,👪,👨‍👩‍👦,👨‍👩‍👧,👨‍👩‍👧‍👦,👨‍👩‍👦‍👦,👨‍👩‍👧‍👧,👨‍👨‍👦,👨‍👨‍👧,👨‍👨‍👧‍👦,👨‍👨‍👦‍👦,👨‍👨‍👧‍👧,👨‍👦,👨‍👧,👨‍👧‍👦,👨‍👦‍👦,👨‍👧‍👧,👩‍👩‍👦,👩‍👩‍👧,👩‍👩‍👧‍👦,👩‍👩‍👦‍👦,👩‍👩‍👧‍👧,👩‍👦,👩‍👧,👩‍👧‍👦,👩‍👦‍👦,👩‍👧‍👧
diff --git a/emoji2/emoji2-emojipicker/src/main/res/raw/emoji_category_symbols.csv b/emoji2/emoji2-emojipicker/src/main/res/raw/emoji_category_symbols.csv
index 34789a03..d917e27 100644
--- a/emoji2/emoji2-emojipicker/src/main/res/raw/emoji_category_symbols.csv
+++ b/emoji2/emoji2-emojipicker/src/main/res/raw/emoji_category_symbols.csv
@@ -53,8 +53,8 @@
 💬
 🗨️

-❗

+❗

 ⁉️
 ‼️
@@ -126,12 +126,6 @@
 🛜
 📳
 📲
-🔈
-🔉
-🔊
-🎼
-🎵
-🎶
 ☢️
 ☣️
 ⚠️
@@ -201,10 +195,10 @@
 8️⃣
 9️⃣
 🔟
+🌐
 💠
 🔷
 🔹
-🌐
 🏧
 Ⓜ️
 🚾
@@ -236,7 +230,14 @@
 🕎
 ♾️
 🆔
+🧑‍🧑‍🧒
+🧑‍🧑‍🧒‍🧒
+🧑‍🧒
+🧑‍🧒‍🧒
 ⚕️
+🎼
+🎵
+🎶
 ✖️


diff --git a/emoji2/emoji2-emojipicker/src/main/res/values/colors.xml b/emoji2/emoji2-emojipicker/src/main/res/values/colors.xml
index fb08439..b21b035 100644
--- a/emoji2/emoji2-emojipicker/src/main/res/values/colors.xml
+++ b/emoji2/emoji2-emojipicker/src/main/res/values/colors.xml
@@ -21,4 +21,6 @@
     <color name="medium_skin_tone">#91674d</color>
     <color name="medium_dark_skin_tone">#875334</color>
     <color name="dark_skin_tone">#4a2f27</color>
+
+    <color name="white">#ffffff</color>
 </resources>
diff --git a/emoji2/emoji2-emojipicker/src/main/res/values/strings.xml b/emoji2/emoji2-emojipicker/src/main/res/values/strings.xml
index c883441..5c12114 100644
--- a/emoji2/emoji2-emojipicker/src/main/res/values/strings.xml
+++ b/emoji2/emoji2-emojipicker/src/main/res/values/strings.xml
@@ -40,4 +40,7 @@
     <string name="emoji_empty_non_recent_category">No emojis available</string>
     <!-- Shown in emoji keyboard when Recent emoji is empty. -->
     <string name="emoji_empty_recent_category">You haven\'t used any emojis yet</string>
-</resources>
\ No newline at end of file
+
+    <!-- The accessibility content description of the emoji bidirectional switcher. [CHAR_LIMIT=100] -->
+    <string name="emoji_bidirectional_switcher_content_desc">emoji bidirectional switcher</string>
+</resources>
diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml
index 4d327d2..4d9b026 100644
--- a/gradle/libs.versions.toml
+++ b/gradle/libs.versions.toml
@@ -47,7 +47,7 @@
 kotlinCompileTesting = "1.4.9"
 kotlinCoroutines = "1.7.3"
 kotlinSerialization = "1.3.3"
-ksp = "1.9.21-1.0.15"
+ksp = "1.9.22-1.0.17"
 ktfmt = "0.45"
 ktlint = "0.49.1"
 leakcanary = "2.13"
diff --git a/kruth/kruth/src/commonTest/kotlin/androidx/kruth/FactTest.kt b/kruth/kruth/src/commonTest/kotlin/androidx/kruth/FactTest.kt
index 5703d64..72d0aa7 100644
--- a/kruth/kruth/src/commonTest/kotlin/androidx/kruth/FactTest.kt
+++ b/kruth/kruth/src/commonTest/kotlin/androidx/kruth/FactTest.kt
@@ -39,8 +39,7 @@
                 emptyList(),
                 listOf(fact("foo", "bar"))
             )
-        )
-            .isEqualTo("foo: bar")
+        ).isEqualTo("foo: bar")
     }
 
     @Test
@@ -50,8 +49,7 @@
                 emptyList(),
                 listOf(fact("foo", "bar"), fact("longer name", "other value"))
             )
-        )
-            .isEqualTo("foo        : bar\nlonger name: other value")
+        ).isEqualTo("foo        : bar\nlonger name: other value")
     }
 
     @Test
@@ -61,8 +59,7 @@
                 emptyList(),
                 listOf(simpleFact("foo"))
             )
-        )
-            .isEqualTo("foo")
+        ).isEqualTo("foo")
     }
 
     @Test
@@ -72,8 +69,7 @@
                 emptyList(),
                 listOf(fact("hello", "there"), simpleFact("foo"))
             )
-        )
-            .isEqualTo("hello: there\nfoo")
+        ).isEqualTo("hello: there\nfoo")
     }
 
     @Test
@@ -83,8 +79,7 @@
                 emptyList(),
                 listOf(fact("foo", "bar\nbaz"))
             )
-        )
-            .isEqualTo("foo:\n    bar\n    baz")
+        ).isEqualTo("foo:\n    bar\n    baz")
     }
 
     @Test
@@ -94,8 +89,7 @@
                 emptyList(),
                 listOf(fact("hello", "there\neveryone"), simpleFact("xyz"))
             )
-        )
-            .isEqualTo("hello:\n    there\n    everyone\nxyz")
+        ).isEqualTo("hello:\n    there\n    everyone\nxyz")
     }
 
     @Test
@@ -105,20 +99,16 @@
                 listOf("hello"),
                 listOf(fact("foo", "bar"))
             )
-        )
-            .isEqualTo("hello\nfoo: bar")
+        ).isEqualTo("hello\nfoo: bar")
     }
 
     @Test
     fun failWithActual_simpleFact() {
-        val subject =
-            object : Subject<Int>(
-                actual = 0,
-            ) {
-                fun fail() {
-                    failWithActual(simpleFact("Expected something else"))
-                }
+        val subject = object : Subject<Int>(actual = 0) {
+            fun fail() {
+                failWithActual(simpleFact("Expected something else"))
             }
+        }
 
         assertFailsWithMessage(
             """
@@ -130,17 +120,14 @@
 
     @Test
     fun failWithActual_multipleFacts() {
-        val subject =
-            object : Subject<Int>(
-                actual = 0,
-            ) {
-                fun fail() {
-                    failWithActual(
-                        simpleFact("Expected something else"),
-                        fact("expected", "1"),
-                    )
-                }
+        val subject = object : Subject<Int>(actual = 0) {
+            fun fail() {
+                failWithActual(
+                    simpleFact("Expected something else"),
+                    fact("expected", "1"),
+                )
             }
+        }
 
         assertFailsWithMessage(
             """
@@ -153,14 +140,11 @@
 
     @Test
     fun failWithoutActual_simpleFact() {
-        val subject =
-            object : Subject<Int>(
-                actual = 0,
-            ) {
-                fun fail() {
-                    failWithoutActual(simpleFact("Expected something else"))
-                }
+        val subject = object : Subject<Int>(actual = 0) {
+            fun fail() {
+                failWithoutActual(simpleFact("Expected something else"))
             }
+        }
 
         assertFailsWithMessage(
             """
@@ -172,9 +156,7 @@
     @Test
     fun failWithoutActual_multipleFacts() {
         val subject =
-            object : Subject<Int>(
-                actual = 0,
-            ) {
+            object : Subject<Int>(actual = 0) {
                 fun fail() {
                     failWithoutActual(
                         simpleFact("Expected something else"),
diff --git a/mediarouter/mediarouter/api/current.ignore b/mediarouter/mediarouter/api/current.ignore
deleted file mode 100644
index f409924..0000000
--- a/mediarouter/mediarouter/api/current.ignore
+++ /dev/null
@@ -1,3 +0,0 @@
-// Baseline format: 1.0
-ChangedSuperclass: androidx.mediarouter.app.MediaRouteButton:
-    Class androidx.mediarouter.app.MediaRouteButton superclass changed from android.view.View to androidx.appcompat.widget.AppCompatImageView
diff --git a/mediarouter/mediarouter/api/current.txt b/mediarouter/mediarouter/api/current.txt
index 94137ad..e67bdb6 100644
--- a/mediarouter/mediarouter/api/current.txt
+++ b/mediarouter/mediarouter/api/current.txt
@@ -14,7 +14,7 @@
     method public void setRouteSelector(androidx.mediarouter.media.MediaRouteSelector);
   }
 
-  public class MediaRouteButton extends androidx.appcompat.widget.AppCompatImageView {
+  public class MediaRouteButton extends android.view.View {
     ctor public MediaRouteButton(android.content.Context);
     ctor public MediaRouteButton(android.content.Context, android.util.AttributeSet?);
     ctor public MediaRouteButton(android.content.Context, android.util.AttributeSet?, int);
diff --git a/mediarouter/mediarouter/api/restricted_current.ignore b/mediarouter/mediarouter/api/restricted_current.ignore
deleted file mode 100644
index f409924..0000000
--- a/mediarouter/mediarouter/api/restricted_current.ignore
+++ /dev/null
@@ -1,3 +0,0 @@
-// Baseline format: 1.0
-ChangedSuperclass: androidx.mediarouter.app.MediaRouteButton:
-    Class androidx.mediarouter.app.MediaRouteButton superclass changed from android.view.View to androidx.appcompat.widget.AppCompatImageView
diff --git a/mediarouter/mediarouter/api/restricted_current.txt b/mediarouter/mediarouter/api/restricted_current.txt
index 94137ad..e67bdb6 100644
--- a/mediarouter/mediarouter/api/restricted_current.txt
+++ b/mediarouter/mediarouter/api/restricted_current.txt
@@ -14,7 +14,7 @@
     method public void setRouteSelector(androidx.mediarouter.media.MediaRouteSelector);
   }
 
-  public class MediaRouteButton extends androidx.appcompat.widget.AppCompatImageView {
+  public class MediaRouteButton extends android.view.View {
     ctor public MediaRouteButton(android.content.Context);
     ctor public MediaRouteButton(android.content.Context, android.util.AttributeSet?);
     ctor public MediaRouteButton(android.content.Context, android.util.AttributeSet?, int);
diff --git a/mediarouter/mediarouter/src/main/java/androidx/mediarouter/app/MediaRouteButton.java b/mediarouter/mediarouter/src/main/java/androidx/mediarouter/app/MediaRouteButton.java
index d1aa391..fb1942a 100644
--- a/mediarouter/mediarouter/src/main/java/androidx/mediarouter/app/MediaRouteButton.java
+++ b/mediarouter/mediarouter/src/main/java/androidx/mediarouter/app/MediaRouteButton.java
@@ -21,6 +21,7 @@
 import android.content.ContextWrapper;
 import android.content.res.ColorStateList;
 import android.content.res.TypedArray;
+import android.graphics.Canvas;
 import android.graphics.drawable.AnimationDrawable;
 import android.graphics.drawable.Drawable;
 import android.text.TextUtils;
@@ -33,7 +34,6 @@
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 import androidx.appcompat.content.res.AppCompatResources;
-import androidx.appcompat.widget.AppCompatImageView;
 import androidx.appcompat.widget.TooltipCompat;
 import androidx.core.graphics.drawable.DrawableCompat;
 import androidx.core.view.ViewCompat;
@@ -72,7 +72,7 @@
  *
  * @see MediaRouteActionProvider
  */
-public class MediaRouteButton extends AppCompatImageView {
+public class MediaRouteButton extends View {
     private static final String TAG = "MediaRouteButton";
 
     private static final String CHOOSER_FRAGMENT_TAG =
@@ -109,6 +109,8 @@
     private int mConnectionState;
 
     private ColorStateList mButtonTint;
+    private int mMinWidth;
+    private int mMinHeight;
 
     private boolean mCheatSheetEnabled;
 
@@ -155,6 +157,10 @@
                 (isRemote ? selectedRoute.getConnectionState() : CONNECTION_STATE_DISCONNECTED);
 
         mButtonTint = a.getColorStateList(R.styleable.MediaRouteButton_mediaRouteButtonTint);
+        mMinWidth = a.getDimensionPixelSize(
+                R.styleable.MediaRouteButton_android_minWidth, 0);
+        mMinHeight = a.getDimensionPixelSize(
+                R.styleable.MediaRouteButton_android_minHeight, 0);
 
         int remoteIndicatorStaticResId = a.getResourceId(
                 R.styleable.MediaRouteButton_externalRouteEnabledDrawableStatic, 0);
@@ -403,7 +409,7 @@
 
     @Override
     @NonNull
-    public int[] onCreateDrawableState(int extraSpace) {
+    protected int[] onCreateDrawableState(int extraSpace) {
         final int[] drawableState = super.onCreateDrawableState(extraSpace + 1);
 
         // Technically we should be handling this more completely, but these
@@ -454,7 +460,7 @@
                     }
                 }
             }
-            setImageDrawable(mRemoteIndicator);
+            invalidate();
         }
         mLastConnectionState = mConnectionState;
     }
@@ -529,6 +535,70 @@
         super.onDetachedFromWindow();
     }
 
+    @Override
+    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+        final int widthSize = MeasureSpec.getSize(widthMeasureSpec);
+        final int heightSize = MeasureSpec.getSize(heightMeasureSpec);
+        final int widthMode = MeasureSpec.getMode(widthMeasureSpec);
+        final int heightMode = MeasureSpec.getMode(heightMeasureSpec);
+
+        final int width = Math.max(mMinWidth, mRemoteIndicator != null ?
+                mRemoteIndicator.getIntrinsicWidth() + getPaddingLeft() + getPaddingRight() : 0);
+        final int height = Math.max(mMinHeight, mRemoteIndicator != null ?
+                mRemoteIndicator.getIntrinsicHeight() + getPaddingTop() + getPaddingBottom() : 0);
+
+        int measuredWidth;
+        switch (widthMode) {
+            case MeasureSpec.EXACTLY:
+                measuredWidth = widthSize;
+                break;
+            case MeasureSpec.AT_MOST:
+                measuredWidth = Math.min(widthSize, width);
+                break;
+            default:
+            case MeasureSpec.UNSPECIFIED:
+                measuredWidth = width;
+                break;
+        }
+
+        int measuredHeight;
+        switch (heightMode) {
+            case MeasureSpec.EXACTLY:
+                measuredHeight = heightSize;
+                break;
+            case MeasureSpec.AT_MOST:
+                measuredHeight = Math.min(heightSize, height);
+                break;
+            default:
+            case MeasureSpec.UNSPECIFIED:
+                measuredHeight = height;
+                break;
+        }
+
+        setMeasuredDimension(measuredWidth, measuredHeight);
+    }
+
+    @Override
+    protected void onDraw(@NonNull Canvas canvas) {
+        super.onDraw(canvas);
+
+        if (mRemoteIndicator != null) {
+            final int left = getPaddingLeft();
+            final int right = getWidth() - getPaddingRight();
+            final int top = getPaddingTop();
+            final int bottom = getHeight() - getPaddingBottom();
+
+            final int drawWidth = mRemoteIndicator.getIntrinsicWidth();
+            final int drawHeight = mRemoteIndicator.getIntrinsicHeight();
+            final int drawLeft = left + (right - left - drawWidth) / 2;
+            final int drawTop = top + (bottom - top - drawHeight) / 2;
+
+            mRemoteIndicator.setBounds(drawLeft, drawTop,
+                    drawLeft + drawWidth, drawTop + drawHeight);
+            mRemoteIndicator.draw(canvas);
+        }
+    }
+
     private void loadRemoteIndicatorIfNeeded() {
         if (mRemoteIndicatorResIdToLoad > 0) {
             if (mRemoteIndicatorLoader != null) {
diff --git a/mediarouter/mediarouter/src/main/res/values/attrs.xml b/mediarouter/mediarouter/src/main/res/values/attrs.xml
index 2299490..f25789e 100644
--- a/mediarouter/mediarouter/src/main/res/values/attrs.xml
+++ b/mediarouter/mediarouter/src/main/res/values/attrs.xml
@@ -29,6 +29,8 @@
         <!-- Tint to apply to the media route button -->
         <attr name="mediaRouteButtonTint" format="color" />
 
+        <attr name="android:minWidth" />
+        <attr name="android:minHeight" />
     </declare-styleable>
 
     <attr name="mediaRouteButtonStyle" format="reference" />
diff --git a/navigation/navigation-compose/api/current.txt b/navigation/navigation-compose/api/current.txt
index b8f2e78..008c5b8 100644
--- a/navigation/navigation-compose/api/current.txt
+++ b/navigation/navigation-compose/api/current.txt
@@ -6,6 +6,7 @@
     method public androidx.navigation.compose.ComposeNavigator.Destination createDestination();
     method public kotlinx.coroutines.flow.StateFlow<java.util.List<androidx.navigation.NavBackStackEntry>> getBackStack();
     method public void onTransitionComplete(androidx.navigation.NavBackStackEntry entry);
+    method public void prepareForTransition(androidx.navigation.NavBackStackEntry entry);
     property public final kotlinx.coroutines.flow.StateFlow<java.util.List<androidx.navigation.NavBackStackEntry>> backStack;
   }
 
diff --git a/navigation/navigation-compose/api/restricted_current.txt b/navigation/navigation-compose/api/restricted_current.txt
index b8f2e78..008c5b8 100644
--- a/navigation/navigation-compose/api/restricted_current.txt
+++ b/navigation/navigation-compose/api/restricted_current.txt
@@ -6,6 +6,7 @@
     method public androidx.navigation.compose.ComposeNavigator.Destination createDestination();
     method public kotlinx.coroutines.flow.StateFlow<java.util.List<androidx.navigation.NavBackStackEntry>> getBackStack();
     method public void onTransitionComplete(androidx.navigation.NavBackStackEntry entry);
+    method public void prepareForTransition(androidx.navigation.NavBackStackEntry entry);
     property public final kotlinx.coroutines.flow.StateFlow<java.util.List<androidx.navigation.NavBackStackEntry>> backStack;
   }
 
diff --git a/navigation/navigation-compose/build.gradle b/navigation/navigation-compose/build.gradle
index 7c62b79..3641c95 100644
--- a/navigation/navigation-compose/build.gradle
+++ b/navigation/navigation-compose/build.gradle
@@ -14,13 +14,6 @@
  * limitations under the License.
  */
 
-/**
- * This file was created using the `create_project.py` script located in the
- * `<AndroidX root>/development/project-creator` directory.
- *
- * Please use that script when creating a new project, rather than copying an existing project and
- * modifying its settings.
- */
 import androidx.build.Publish
 import androidx.build.RunApiTasks
 
@@ -35,7 +28,7 @@
 
     implementation(libs.kotlinStdlib)
     implementation(project(":compose:foundation:foundation-layout"))
-    api("androidx.activity:activity-compose:1.7.0")
+    api("androidx.activity:activity-compose:1.8.0")
     api(project(":compose:animation:animation"))
     api(project(":compose:runtime:runtime"))
     api(project(":compose:runtime:runtime-saveable"))
diff --git a/navigation/navigation-compose/src/androidTest/java/androidx/navigation/compose/NavHostScreenShotTest.kt b/navigation/navigation-compose/src/androidTest/java/androidx/navigation/compose/NavHostScreenShotTest.kt
index a392ff8e..1fcbd3e 100644
--- a/navigation/navigation-compose/src/androidTest/java/androidx/navigation/compose/NavHostScreenShotTest.kt
+++ b/navigation/navigation-compose/src/androidTest/java/androidx/navigation/compose/NavHostScreenShotTest.kt
@@ -17,6 +17,10 @@
 package androidx.navigation.compose
 
 import android.os.Build
+import android.window.BackEvent
+import androidx.activity.BackEventCompat
+import androidx.activity.OnBackPressedDispatcher
+import androidx.activity.compose.LocalOnBackPressedDispatcherOwner
 import androidx.annotation.RequiresApi
 import androidx.compose.animation.slideInHorizontally
 import androidx.compose.animation.slideOutHorizontally
@@ -33,10 +37,13 @@
 import androidx.compose.ui.test.onNodeWithText
 import androidx.compose.ui.test.onParent
 import androidx.compose.ui.unit.dp
+import androidx.lifecycle.Lifecycle
 import androidx.navigation.NavHostController
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.LargeTest
+import androidx.test.filters.SdkSuppress
 import androidx.test.screenshot.AndroidXScreenshotTestRule
+import com.google.common.truth.Truth.assertThat
 import org.junit.Rule
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -104,6 +111,69 @@
                 "testNavHostAnimationsZIndex"
             )
     }
+
+    @RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+    @Test
+    fun testNavHostPredictiveBackAnimations() {
+        lateinit var navController: NavHostController
+        lateinit var backPressedDispatcher: OnBackPressedDispatcher
+        composeTestRule.setContent {
+            navController = rememberNavController()
+            backPressedDispatcher =
+                LocalOnBackPressedDispatcherOwner.current!!.onBackPressedDispatcher
+            NavHost(
+                navController = navController,
+                startDestination = FIRST,
+                route = "start",
+                enterTransition = { slideInHorizontally { it / 2 } },
+                exitTransition = { slideOutHorizontally { - it / 2 } }
+            ) {
+                composable(FIRST) { BasicText(FIRST) }
+                composable(SECOND) {
+                    Box(
+                        Modifier
+                            .fillMaxSize()
+                            .background(Color.Blue)) {
+                        BasicText(SECOND, Modifier.size(50.dp))
+                    }
+                }
+            }
+        }
+
+        composeTestRule.runOnIdle {
+            navController.navigate(SECOND)
+        }
+
+        composeTestRule.runOnIdle {
+            backPressedDispatcher.dispatchOnBackStarted(
+                BackEventCompat(0.1F, 0.1F, 0.1F, BackEvent.EDGE_LEFT)
+            )
+            assertThat(navController.currentBackStackEntry?.lifecycle?.currentState)
+                .isEqualTo(Lifecycle.State.STARTED)
+            assertThat(navController.previousBackStackEntry?.lifecycle?.currentState)
+                .isEqualTo(Lifecycle.State.STARTED)
+            backPressedDispatcher.dispatchOnBackProgressed(
+                BackEventCompat(0.1F, 0.1F, 0.5F, BackEvent.EDGE_LEFT)
+            )
+        }
+
+        composeTestRule.waitForIdle()
+
+        composeTestRule.runOnIdle {
+            backPressedDispatcher.dispatchOnBackProgressed(
+                BackEventCompat(0.1F, 0.1F, 0.5F, BackEvent.EDGE_LEFT)
+            )
+        }
+
+        composeTestRule.waitForIdle()
+
+        composeTestRule.onNodeWithText(SECOND).onParent()
+            .captureToImage().assertAgainstGolden(
+                screenshotRule,
+                "testNavHostPredictiveBackAnimations"
+            )
+    }
 }
 
 private const val FIRST = "first"
diff --git a/navigation/navigation-compose/src/main/java/androidx/navigation/compose/ComposeNavigator.kt b/navigation/navigation-compose/src/main/java/androidx/navigation/compose/ComposeNavigator.kt
index d087489..50cdf30 100644
--- a/navigation/navigation-compose/src/main/java/androidx/navigation/compose/ComposeNavigator.kt
+++ b/navigation/navigation-compose/src/main/java/androidx/navigation/compose/ComposeNavigator.kt
@@ -69,6 +69,16 @@
     }
 
     /**
+     * Function to prepare the entry for transition.
+     *
+     * This should be called when the entry needs to move the [Lifecycle.State] in preparation for
+     * a transition such as when using predictive back.
+     */
+    public fun prepareForTransition(entry: NavBackStackEntry) {
+        state.prepareForTransition(entry)
+    }
+
+    /**
      * Callback to mark a navigation in transition as complete.
      *
      * This should be called in conjunction with [navigate] and [popBackStack] as those
diff --git a/navigation/navigation-compose/src/main/java/androidx/navigation/compose/NavHost.kt b/navigation/navigation-compose/src/main/java/androidx/navigation/compose/NavHost.kt
index 86d317a..0109a42 100644
--- a/navigation/navigation-compose/src/main/java/androidx/navigation/compose/NavHost.kt
+++ b/navigation/navigation-compose/src/main/java/androidx/navigation/compose/NavHost.kt
@@ -17,12 +17,14 @@
 package androidx.navigation.compose
 
 import android.annotation.SuppressLint
-import androidx.activity.compose.BackHandler
+import androidx.activity.compose.PredictiveBackHandler
 import androidx.compose.animation.AnimatedContent
 import androidx.compose.animation.AnimatedContentTransitionScope
 import androidx.compose.animation.ContentTransform
 import androidx.compose.animation.EnterTransition
 import androidx.compose.animation.ExitTransition
+import androidx.compose.animation.core.SeekableTransitionState
+import androidx.compose.animation.core.rememberTransition
 import androidx.compose.animation.core.tween
 import androidx.compose.animation.core.updateTransition
 import androidx.compose.animation.fadeIn
@@ -34,8 +36,11 @@
 import androidx.compose.runtime.collectAsState
 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.saveable.rememberSaveableStateHolder
+import androidx.compose.runtime.setValue
 import androidx.compose.ui.Alignment
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.platform.LocalLifecycleOwner
@@ -49,6 +54,7 @@
 import androidx.navigation.Navigator
 import androidx.navigation.createGraph
 import androidx.navigation.get
+import kotlin.coroutines.cancellation.CancellationException
 
 /**
  * Provides in place in the Compose hierarchy for self contained navigation to occur.
@@ -213,8 +219,24 @@
 
     val currentBackStack by composeNavigator.backStack.collectAsState()
 
-    BackHandler(currentBackStack.size > 1) {
-        navController.popBackStack()
+    var progress by remember { mutableFloatStateOf(0f) }
+    var inPredictiveBack by remember { mutableStateOf(false) }
+    PredictiveBackHandler(currentBackStack.size > 1) { backEvent ->
+        inPredictiveBack = true
+        progress = 0f
+        val currentBackStackEntry = currentBackStack.lastOrNull()
+        composeNavigator.prepareForTransition(currentBackStackEntry!!)
+        val previousEntry = currentBackStack[currentBackStack.size - 2]
+        composeNavigator.prepareForTransition(previousEntry)
+        try {
+            backEvent.collect {
+                progress = it.progress
+            }
+            inPredictiveBack = false
+            composeNavigator.popBackStack(currentBackStackEntry, false)
+        } catch (e: CancellationException) {
+            inPredictiveBack = false
+        }
     }
 
     DisposableEffect(lifecycleOwner) {
@@ -244,7 +266,7 @@
         val finalEnter: AnimatedContentTransitionScope<NavBackStackEntry>.() -> EnterTransition = {
             val targetDestination = targetState.destination as ComposeNavigator.Destination
 
-            if (composeNavigator.isPop.value) {
+            if (composeNavigator.isPop.value || inPredictiveBack) {
                 targetDestination.hierarchy.firstNotNullOfOrNull { destination ->
                     destination.createPopEnterTransition(this)
                 } ?: popEnterTransition.invoke(this)
@@ -258,7 +280,7 @@
         val finalExit: AnimatedContentTransitionScope<NavBackStackEntry>.() -> ExitTransition = {
             val initialDestination = initialState.destination as ComposeNavigator.Destination
 
-            if (composeNavigator.isPop.value) {
+            if (composeNavigator.isPop.value || inPredictiveBack) {
                 initialDestination.hierarchy.firstNotNullOfOrNull { destination ->
                     destination.createPopExitTransition(this)
                 } ?: popExitTransition.invoke(this)
@@ -277,7 +299,22 @@
             }
         }
 
-        val transition = updateTransition(backStackEntry, label = "entry")
+        val transition = if (inPredictiveBack) {
+            val transitionState by remember(backStackEntry) {
+                // The state returned here cannot be nullable cause it produces the input of the
+                // transitionSpec passed into the AnimatedContent and that must match the non-nullable
+                // scope exposed by the transitions on the NavHost and composable APIs.
+                mutableStateOf(SeekableTransitionState(backStackEntry))
+            }
+            LaunchedEffect(progress) {
+                val previousEntry = currentBackStack[currentBackStack.size - 2]
+                transitionState.snapTo(previousEntry, progress)
+            }
+            rememberTransition(transitionState, label = "entry")
+        } else {
+            updateTransition(backStackEntry, label = "entry")
+        }
+
         transition.AnimatedContent(
             modifier,
             transitionSpec = {
@@ -307,7 +344,13 @@
             // animating. In these cases the currentEntry will be null, and in those cases,
             // AnimatedContent will just skip attempting to transition the old entry.
             // See https://issuetracker.google.com/238686802
-            val currentEntry = visibleEntries.lastOrNull { entry -> it == entry }
+            val currentEntry = if (inPredictiveBack) {
+                // We have to do this because the previous entry does not show up in visibleEntries
+                // even if we prepare it above as part of onBackStackChangeStarted
+                 it
+            } else {
+                visibleEntries.lastOrNull { entry -> it == entry }
+            }
 
             // while in the scope of the composable, we provide the navBackStackEntry as the
             // ViewModelStoreOwner and LifecycleOwner
diff --git a/playground-common/playground.properties b/playground-common/playground.properties
index b0fde86..db858cd 100644
--- a/playground-common/playground.properties
+++ b/playground-common/playground.properties
@@ -25,6 +25,6 @@
 kotlin.code.style=official
 # Disable docs
 androidx.enableDocumentation=false
-androidx.playground.snapshotBuildId=11307821
+androidx.playground.snapshotBuildId=11349412
 androidx.playground.metalavaBuildId=11328314
 androidx.studio.type=playground
\ No newline at end of file
diff --git a/tv/tv-material/api/current.txt b/tv/tv-material/api/current.txt
index 64ec25f..736293f 100644
--- a/tv/tv-material/api/current.txt
+++ b/tv/tv-material/api/current.txt
@@ -970,7 +970,7 @@
   @SuppressCompatibility @androidx.compose.runtime.Immutable @androidx.tv.material3.ExperimentalTvMaterial3Api public final class ToggleableSurfaceShape {
   }
 
-  @SuppressCompatibility @androidx.compose.runtime.Immutable @androidx.tv.material3.ExperimentalTvMaterial3Api public final class Typography {
+  @androidx.compose.runtime.Immutable public final class Typography {
     ctor public Typography(optional androidx.compose.ui.text.TextStyle displayLarge, optional androidx.compose.ui.text.TextStyle displayMedium, optional androidx.compose.ui.text.TextStyle displaySmall, optional androidx.compose.ui.text.TextStyle headlineLarge, optional androidx.compose.ui.text.TextStyle headlineMedium, optional androidx.compose.ui.text.TextStyle headlineSmall, optional androidx.compose.ui.text.TextStyle titleLarge, optional androidx.compose.ui.text.TextStyle titleMedium, optional androidx.compose.ui.text.TextStyle titleSmall, optional androidx.compose.ui.text.TextStyle bodyLarge, optional androidx.compose.ui.text.TextStyle bodyMedium, optional androidx.compose.ui.text.TextStyle bodySmall, optional androidx.compose.ui.text.TextStyle labelLarge, optional androidx.compose.ui.text.TextStyle labelMedium, optional androidx.compose.ui.text.TextStyle labelSmall);
     method public androidx.tv.material3.Typography copy(optional androidx.compose.ui.text.TextStyle displayLarge, optional androidx.compose.ui.text.TextStyle displayMedium, optional androidx.compose.ui.text.TextStyle displaySmall, optional androidx.compose.ui.text.TextStyle headlineLarge, optional androidx.compose.ui.text.TextStyle headlineMedium, optional androidx.compose.ui.text.TextStyle headlineSmall, optional androidx.compose.ui.text.TextStyle titleLarge, optional androidx.compose.ui.text.TextStyle titleMedium, optional androidx.compose.ui.text.TextStyle titleSmall, optional androidx.compose.ui.text.TextStyle bodyLarge, optional androidx.compose.ui.text.TextStyle bodyMedium, optional androidx.compose.ui.text.TextStyle bodySmall, optional androidx.compose.ui.text.TextStyle labelLarge, optional androidx.compose.ui.text.TextStyle labelMedium, optional androidx.compose.ui.text.TextStyle labelSmall);
     method public androidx.compose.ui.text.TextStyle getBodyLarge();
diff --git a/tv/tv-material/api/restricted_current.txt b/tv/tv-material/api/restricted_current.txt
index 64ec25f..736293f 100644
--- a/tv/tv-material/api/restricted_current.txt
+++ b/tv/tv-material/api/restricted_current.txt
@@ -970,7 +970,7 @@
   @SuppressCompatibility @androidx.compose.runtime.Immutable @androidx.tv.material3.ExperimentalTvMaterial3Api public final class ToggleableSurfaceShape {
   }
 
-  @SuppressCompatibility @androidx.compose.runtime.Immutable @androidx.tv.material3.ExperimentalTvMaterial3Api public final class Typography {
+  @androidx.compose.runtime.Immutable public final class Typography {
     ctor public Typography(optional androidx.compose.ui.text.TextStyle displayLarge, optional androidx.compose.ui.text.TextStyle displayMedium, optional androidx.compose.ui.text.TextStyle displaySmall, optional androidx.compose.ui.text.TextStyle headlineLarge, optional androidx.compose.ui.text.TextStyle headlineMedium, optional androidx.compose.ui.text.TextStyle headlineSmall, optional androidx.compose.ui.text.TextStyle titleLarge, optional androidx.compose.ui.text.TextStyle titleMedium, optional androidx.compose.ui.text.TextStyle titleSmall, optional androidx.compose.ui.text.TextStyle bodyLarge, optional androidx.compose.ui.text.TextStyle bodyMedium, optional androidx.compose.ui.text.TextStyle bodySmall, optional androidx.compose.ui.text.TextStyle labelLarge, optional androidx.compose.ui.text.TextStyle labelMedium, optional androidx.compose.ui.text.TextStyle labelSmall);
     method public androidx.tv.material3.Typography copy(optional androidx.compose.ui.text.TextStyle displayLarge, optional androidx.compose.ui.text.TextStyle displayMedium, optional androidx.compose.ui.text.TextStyle displaySmall, optional androidx.compose.ui.text.TextStyle headlineLarge, optional androidx.compose.ui.text.TextStyle headlineMedium, optional androidx.compose.ui.text.TextStyle headlineSmall, optional androidx.compose.ui.text.TextStyle titleLarge, optional androidx.compose.ui.text.TextStyle titleMedium, optional androidx.compose.ui.text.TextStyle titleSmall, optional androidx.compose.ui.text.TextStyle bodyLarge, optional androidx.compose.ui.text.TextStyle bodyMedium, optional androidx.compose.ui.text.TextStyle bodySmall, optional androidx.compose.ui.text.TextStyle labelLarge, optional androidx.compose.ui.text.TextStyle labelMedium, optional androidx.compose.ui.text.TextStyle labelSmall);
     method public androidx.compose.ui.text.TextStyle getBodyLarge();
diff --git a/tv/tv-material/src/main/java/androidx/tv/material3/TabRow.kt b/tv/tv-material/src/main/java/androidx/tv/material3/TabRow.kt
index f68edbc..322f2aa 100644
--- a/tv/tv-material/src/main/java/androidx/tv/material3/TabRow.kt
+++ b/tv/tv-material/src/main/java/androidx/tv/material3/TabRow.kt
@@ -46,6 +46,7 @@
 import androidx.compose.ui.unit.Constraints
 import androidx.compose.ui.unit.Density
 import androidx.compose.ui.unit.DpRect
+import androidx.compose.ui.unit.IntOffset
 import androidx.compose.ui.unit.dp
 import androidx.compose.ui.unit.height
 import androidx.compose.ui.unit.width
@@ -242,7 +243,7 @@
             modifier
                 .fillMaxWidth()
                 .wrapContentSize(Alignment.BottomStart)
-                .offset(x = leftOffset, y = topOffset)
+                .offset { IntOffset(x = leftOffset.roundToPx(), y = topOffset.roundToPx()) }
                 .width(width)
                 .height(height)
                 .background(color = pillColor, shape = RoundedCornerShape(50))
@@ -300,7 +301,7 @@
             modifier
                 .fillMaxWidth()
                 .wrapContentSize(Alignment.BottomStart)
-                .offset(x = leftOffset)
+                .offset { IntOffset(x = leftOffset.roundToPx(), y = 0) }
                 .width(width)
                 .height(indicatorHeight)
                 .background(color = underlineColor)
diff --git a/tv/tv-material/src/main/java/androidx/tv/material3/Typography.kt b/tv/tv-material/src/main/java/androidx/tv/material3/Typography.kt
index d1fd31f..014694b 100644
--- a/tv/tv-material/src/main/java/androidx/tv/material3/Typography.kt
+++ b/tv/tv-material/src/main/java/androidx/tv/material3/Typography.kt
@@ -75,7 +75,6 @@
  * @property labelSmall labelSmall is one of the smallest font sizes. It is used sparingly to
  * annotate imagery or to introduce a headline.
  */
-@ExperimentalTvMaterial3Api
 @Immutable
 class Typography(
     val displayLarge: TextStyle = TypographyTokens.DisplayLarge,
@@ -186,7 +185,6 @@
 /**
  * Helper function for component typography tokens.
  */
-@OptIn(ExperimentalTvMaterial3Api::class)
 internal fun Typography.fromToken(value: TypographyKeyTokens): TextStyle {
     return when (value) {
         TypographyKeyTokens.DisplayLarge -> displayLarge
@@ -207,5 +205,4 @@
     }
 }
 
-@OptIn(ExperimentalTvMaterial3Api::class)
 internal val LocalTypography = staticCompositionLocalOf { Typography() }
diff --git a/wear/protolayout/protolayout-material/src/main/java/androidx/wear/protolayout/material/Text.java b/wear/protolayout/protolayout-material/src/main/java/androidx/wear/protolayout/material/Text.java
index dd110c0..264f3a0 100644
--- a/wear/protolayout/protolayout-material/src/main/java/androidx/wear/protolayout/material/Text.java
+++ b/wear/protolayout/protolayout-material/src/main/java/androidx/wear/protolayout/material/Text.java
@@ -93,7 +93,9 @@
 
         @NonNull
         @OptIn(markerClass = ProtoLayoutExperimental.class)
-        @SuppressWarnings("deprecation")
+        @SuppressWarnings(
+                "deprecation") // Default value from initial release is TEXT_OVERFLOW_ELLIPSIZE_END
+        // so we can't change it as it would be a breaking change for developers.
         private final LayoutElementBuilders.Text.Builder mElementBuilder =
                 new LayoutElementBuilders.Text.Builder()
                         .setMaxLines(1)
diff --git a/wear/protolayout/protolayout-renderer/src/main/java/androidx/wear/protolayout/renderer/inflater/ProtoLayoutInflater.java b/wear/protolayout/protolayout-renderer/src/main/java/androidx/wear/protolayout/renderer/inflater/ProtoLayoutInflater.java
index 6eec325..0b982b4 100644
--- a/wear/protolayout/protolayout-renderer/src/main/java/androidx/wear/protolayout/renderer/inflater/ProtoLayoutInflater.java
+++ b/wear/protolayout/protolayout-renderer/src/main/java/androidx/wear/protolayout/renderer/inflater/ProtoLayoutInflater.java
@@ -92,7 +92,6 @@
 import androidx.core.view.AccessibilityDelegateCompat;
 import androidx.core.view.ViewCompat;
 import androidx.core.view.accessibility.AccessibilityNodeInfoCompat;
-import androidx.wear.protolayout.renderer.common.SeekableAnimatedVectorDrawable;
 import androidx.wear.protolayout.expression.pipeline.AnimationsHelper;
 import androidx.wear.protolayout.expression.proto.AnimationParameterProto.AnimationSpec;
 import androidx.wear.protolayout.expression.proto.DynamicProto.DynamicFloat;
@@ -181,6 +180,7 @@
 import androidx.wear.protolayout.renderer.common.ProtoLayoutDiffer;
 import androidx.wear.protolayout.renderer.common.ProtoLayoutDiffer.LayoutDiff;
 import androidx.wear.protolayout.renderer.common.ProtoLayoutDiffer.TreeNodeWithChange;
+import androidx.wear.protolayout.renderer.common.SeekableAnimatedVectorDrawable;
 import androidx.wear.protolayout.renderer.dynamicdata.ProtoLayoutDynamicDataPipeline;
 import androidx.wear.protolayout.renderer.inflater.RenderedMetadata.LayoutInfo;
 import androidx.wear.protolayout.renderer.inflater.RenderedMetadata.LinearLayoutProperties;
@@ -2596,12 +2596,10 @@
                     isAutoSizeAllowed);
         }
 
-        boolean excludeFontPadding = false;
-
-        if (text.hasAndroidTextStyle()) {
-            excludeFontPadding = text.getAndroidTextStyle().getExcludeFontPadding();
-        }
-        applyExcludeFontPadding(textView, excludeFontPadding);
+        // AndroidTextStyle proto is existing only for newer builders and older renderer mix to also
+        // have excluded font padding. Here, it's being ignored, and default value (excluded font
+        // padding) is used.
+        applyExcludeFontPadding(textView);
 
         if (text.hasLineHeight()) {
             float lineHeightPx = toPx(text.getLineHeight());
@@ -2716,19 +2714,13 @@
     }
 
     /**
-     * Sets whether the padding is included or not. If font padding is not included, sets the
-     * correct padding to the TextView to avoid clipping taller languages.
+     * Sets font padding to be excluded and applies correct padding to the TextView to avoid
+     * clipping taller languages.
      */
-    private void applyExcludeFontPadding(TextView textView, boolean excludeFontPadding) {
-        // Reversed value, since TextView sets padding to be included, while our protos are for
-        // excluding it.
-        textView.setIncludeFontPadding(!excludeFontPadding);
+    private void applyExcludeFontPadding(TextView textView) {
+        textView.setIncludeFontPadding(false);
 
-        // We need to update padding in the TextView if font's padding is not used, to avoid
-        // clipping of taller languages.
-        if (!excludeFontPadding) {
-            return;
-        }
+        // We need to update padding in the TextView to avoid clipping of taller languages.
 
         float ascent = textView.getPaint().getFontMetrics().ascent;
         float descent = textView.getPaint().getFontMetrics().descent;
@@ -3526,8 +3518,6 @@
 
         boolean isAnySpanClickable = false;
 
-        boolean excludeFontPadding = false;
-
         for (Span element : spannable.getSpansList()) {
             switch (element.getInnerCase()) {
                 case IMAGE:
@@ -3547,10 +3537,6 @@
                         isAnySpanClickable = true;
                     }
 
-                    if (protoText.hasAndroidTextStyle()
-                            && protoText.getAndroidTextStyle().getExcludeFontPadding()) {
-                        excludeFontPadding = true;
-                    }
                     break;
                 case INNER_NOT_SET:
                     Log.w(TAG, "Unknown Span child type.");
@@ -3593,7 +3579,10 @@
 
         tv.setText(builder);
 
-        applyExcludeFontPadding(tv, excludeFontPadding);
+        // AndroidTextStyle proto is existing only for newer builders and older renderer mix to also
+        // have excluded font padding. Here, it's being ignored, and default value (excluded font
+        // padding) is used.
+        applyExcludeFontPadding(tv);
 
         if (isAnySpanClickable) {
             // For any ClickableSpans to work, the MovementMethod must be set to LinkMovementMethod.
diff --git a/wear/protolayout/protolayout/src/main/java/androidx/wear/protolayout/LayoutElementBuilders.java b/wear/protolayout/protolayout/src/main/java/androidx/wear/protolayout/LayoutElementBuilders.java
index 3c142e4..c01734fa 100644
--- a/wear/protolayout/protolayout/src/main/java/androidx/wear/protolayout/LayoutElementBuilders.java
+++ b/wear/protolayout/protolayout/src/main/java/androidx/wear/protolayout/LayoutElementBuilders.java
@@ -1123,98 +1123,6 @@
         }
     }
 
-    /**
-     * An Android platform specific text style configuration options for styling and compatibility.
-     */
-    @RequiresSchemaVersion(major = 1, minor = 200)
-    @ProtoLayoutExperimental
-    @RestrictTo(Scope.LIBRARY_GROUP)
-    public static final class AndroidTextStyle {
-        private final LayoutElementProto.AndroidTextStyle mImpl;
-        @Nullable private final Fingerprint mFingerprint;
-
-        AndroidTextStyle(
-                LayoutElementProto.AndroidTextStyle impl, @Nullable Fingerprint fingerprint) {
-            this.mImpl = impl;
-            this.mFingerprint = fingerprint;
-        }
-
-        /**
-         * Gets whether the {@link Text} excludes padding specified by the font, i.e. extra top and
-         * bottom padding above the normal ascent and descent. The default is false.
-         */
-        public boolean getExcludeFontPadding() {
-            return mImpl.getExcludeFontPadding();
-        }
-
-        /** Get the fingerprint for this object, or null if unknown. */
-        @RestrictTo(Scope.LIBRARY_GROUP)
-        @Nullable
-        public Fingerprint getFingerprint() {
-            return mFingerprint;
-        }
-
-        /** Creates a new wrapper instance from the proto. */
-        @RestrictTo(Scope.LIBRARY_GROUP)
-        @NonNull
-        public static AndroidTextStyle fromProto(
-                @NonNull LayoutElementProto.AndroidTextStyle proto,
-                @Nullable Fingerprint fingerprint) {
-            return new AndroidTextStyle(proto, fingerprint);
-        }
-
-        @NonNull
-        static AndroidTextStyle fromProto(@NonNull LayoutElementProto.AndroidTextStyle proto) {
-            return fromProto(proto, null);
-        }
-
-        /** Returns the internal proto instance. */
-        @RestrictTo(Scope.LIBRARY_GROUP)
-        @NonNull
-        public LayoutElementProto.AndroidTextStyle toProto() {
-            return mImpl;
-        }
-
-        @Override
-        @NonNull
-        public String toString() {
-            return "AndroidTextStyle{" + "excludeFontPadding=" + getExcludeFontPadding() + "}";
-        }
-
-        /** Builder for {@link AndroidTextStyle} */
-        public static final class Builder {
-            private final LayoutElementProto.AndroidTextStyle.Builder mImpl =
-                    LayoutElementProto.AndroidTextStyle.newBuilder();
-            private final Fingerprint mFingerprint = new Fingerprint(408674745);
-
-            /** Creates an instance of {@link Builder}. */
-            public Builder() {
-                // Setting this to true before setter is called, so that default behaviour is to
-                // exclude padding.
-                mImpl.setExcludeFontPadding(true);
-            }
-
-            /**
-             * Sets whether the {@link Text} excludes padding specified by the font, i.e. extra top
-             * and bottom padding above the normal ascent and descent. The default is false.
-             */
-            @RequiresSchemaVersion(major = 1, minor = 200)
-            @SuppressLint("MissingGetterMatchingBuilder")
-            @NonNull
-            public Builder setExcludeFontPadding(boolean excludeFontPadding) {
-                mImpl.setExcludeFontPadding(excludeFontPadding);
-                mFingerprint.recordPropertyUpdate(1, Boolean.hashCode(excludeFontPadding));
-                return this;
-            }
-
-            /** Builds an instance from accumulated values. */
-            @NonNull
-            public AndroidTextStyle build() {
-                return new AndroidTextStyle(mImpl.build(), mFingerprint);
-            }
-        }
-    }
-
     /** A text string. */
     @RequiresSchemaVersion(major = 1, minor = 0)
     public static final class Text implements LayoutElement {
diff --git a/wear/protolayout/protolayout/src/test/java/androidx/wear/protolayout/LayoutElementBuildersTest.java b/wear/protolayout/protolayout/src/test/java/androidx/wear/protolayout/LayoutElementBuildersTest.java
index f3574fe..6a416f2 100644
--- a/wear/protolayout/protolayout/src/test/java/androidx/wear/protolayout/LayoutElementBuildersTest.java
+++ b/wear/protolayout/protolayout/src/test/java/androidx/wear/protolayout/LayoutElementBuildersTest.java
@@ -237,6 +237,18 @@
     }
 
     @Test
+    public void text_defaultExcludeFontPadding() {
+        String staticValue = "Text";
+        // We don't set anything related to the font padding to test that default value is true.
+        LayoutElementBuilders.Text text =
+                new LayoutElementBuilders.Text.Builder()
+                        .setText(new TypeBuilders.StringProp.Builder(staticValue).build())
+                        .build();
+
+        assertThat(text.toProto().getAndroidTextStyle().getExcludeFontPadding()).isTrue();
+    }
+
+    @Test
     public void testTextSetText() {
         LayoutElementBuilders.Text text =
                 new LayoutElementBuilders.Text.Builder()
diff --git a/work/work-multiprocess/src/androidTest/java/androidx/work/multiprocess/TrackingRemoteWorkerFactory.kt b/work/work-multiprocess/src/androidTest/java/androidx/work/multiprocess/TrackingRemoteWorkerFactory.kt
index 90ac5a7..1e60e5b 100644
--- a/work/work-multiprocess/src/androidTest/java/androidx/work/multiprocess/TrackingRemoteWorkerFactory.kt
+++ b/work/work-multiprocess/src/androidTest/java/androidx/work/multiprocess/TrackingRemoteWorkerFactory.kt
@@ -45,7 +45,7 @@
             appContext,
             workerClassName,
             workerParameters
-        )!!.also {
+        ).also {
             val oldWorkers = createdWorkers.value[it.id]
             val workers = if (oldWorkers == null)
                 Workers(localProxy = it)
diff --git a/work/work-multiprocess/src/main/java/androidx/work/multiprocess/RemoteWorkerWrapper.kt b/work/work-multiprocess/src/main/java/androidx/work/multiprocess/RemoteWorkerWrapper.kt
index 0697869..f12aef9 100644
--- a/work/work-multiprocess/src/main/java/androidx/work/multiprocess/RemoteWorkerWrapper.kt
+++ b/work/work-multiprocess/src/main/java/androidx/work/multiprocess/RemoteWorkerWrapper.kt
@@ -21,6 +21,7 @@
 import androidx.work.ListenableWorker
 import androidx.work.Logger
 import androidx.work.WorkInfo
+import androidx.work.WorkerExceptionInfo
 import androidx.work.WorkerParameters
 import androidx.work.impl.utils.futures.SettableFuture
 import androidx.work.impl.utils.taskexecutor.TaskExecutor
@@ -51,12 +52,22 @@
     taskExecutor.mainThreadExecutor.execute {
         try {
             if (future.isCancelled) return@execute
-            val worker = configuration.workerFactory
-                .createWorkerWithDefaultFallback(context, workerClassName, workerParameters)
-            if (worker == null) {
-                val message = "Unable to create an instance of $workerClassName"
-                Logger.get().error(ListenableWorkerImpl.TAG, message)
-                future.setException(IllegalStateException(message))
+            val worker = try {
+                configuration.workerFactory
+                    .createWorkerWithDefaultFallback(context, workerClassName, workerParameters)
+            } catch (throwable: Throwable) {
+                future.setException(throwable)
+                try {
+                    configuration.workerInitializationExceptionHandler?.let {
+                        taskExecutor.executeOnTaskThread {
+                            it.accept(WorkerExceptionInfo(
+                                workerClassName, workerParameters, throwable))
+                        }
+                    }
+                } catch (exception: Exception) {
+                    val message = "Exception handler threw an exception: $exception"
+                    Logger.get().error(ListenableWorkerImpl.TAG, message)
+                }
                 return@execute
             }
             if (worker !is RemoteListenableWorker) {
diff --git a/work/work-runtime/api/current.txt b/work/work-runtime/api/current.txt
index 5ccb6ba..6d1f114 100644
--- a/work/work-runtime/api/current.txt
+++ b/work/work-runtime/api/current.txt
@@ -29,7 +29,9 @@
     method public androidx.work.RunnableScheduler getRunnableScheduler();
     method public androidx.core.util.Consumer<java.lang.Throwable>? getSchedulingExceptionHandler();
     method public java.util.concurrent.Executor getTaskExecutor();
+    method public androidx.core.util.Consumer<androidx.work.WorkerExceptionInfo>? getWorkerExecutionExceptionHandler();
     method public androidx.work.WorkerFactory getWorkerFactory();
+    method public androidx.core.util.Consumer<androidx.work.WorkerExceptionInfo>? getWorkerInitializationExceptionHandler();
     property public final androidx.work.Clock clock;
     property public final int contentUriTriggerWorkersLimit;
     property public final String? defaultProcessName;
@@ -41,7 +43,9 @@
     property public final androidx.work.RunnableScheduler runnableScheduler;
     property public final androidx.core.util.Consumer<java.lang.Throwable>? schedulingExceptionHandler;
     property public final java.util.concurrent.Executor taskExecutor;
+    property public final androidx.core.util.Consumer<androidx.work.WorkerExceptionInfo>? workerExecutionExceptionHandler;
     property public final androidx.work.WorkerFactory workerFactory;
+    property public final androidx.core.util.Consumer<androidx.work.WorkerExceptionInfo>? workerInitializationExceptionHandler;
     field public static final androidx.work.Configuration.Companion Companion;
     field public static final int MIN_SCHEDULER_LIMIT = 20; // 0x14
   }
@@ -61,7 +65,9 @@
     method public androidx.work.Configuration.Builder setRunnableScheduler(androidx.work.RunnableScheduler runnableScheduler);
     method public androidx.work.Configuration.Builder setSchedulingExceptionHandler(androidx.core.util.Consumer<java.lang.Throwable> schedulingExceptionHandler);
     method public androidx.work.Configuration.Builder setTaskExecutor(java.util.concurrent.Executor taskExecutor);
+    method public androidx.work.Configuration.Builder setWorkerExecutionExceptionHandler(androidx.core.util.Consumer<androidx.work.WorkerExceptionInfo> workerExceptionHandler);
     method public androidx.work.Configuration.Builder setWorkerFactory(androidx.work.WorkerFactory workerFactory);
+    method public androidx.work.Configuration.Builder setWorkerInitializationExceptionHandler(androidx.core.util.Consumer<androidx.work.WorkerExceptionInfo> workerExceptionHandler);
   }
 
   public static final class Configuration.Companion {
@@ -590,6 +596,16 @@
     method public final com.google.common.util.concurrent.ListenableFuture<androidx.work.ListenableWorker.Result> startWork();
   }
 
+  public final class WorkerExceptionInfo {
+    ctor public WorkerExceptionInfo(String workerClassName, androidx.work.WorkerParameters workerParameters, Throwable throwable);
+    method public Throwable getThrowable();
+    method public String getWorkerClassName();
+    method public androidx.work.WorkerParameters getWorkerParameters();
+    property public final Throwable throwable;
+    property public final String workerClassName;
+    property public final androidx.work.WorkerParameters workerParameters;
+  }
+
   public abstract class WorkerFactory {
     ctor public WorkerFactory();
     method public abstract androidx.work.ListenableWorker? createWorker(android.content.Context appContext, String workerClassName, androidx.work.WorkerParameters workerParameters);
diff --git a/work/work-runtime/api/restricted_current.txt b/work/work-runtime/api/restricted_current.txt
index 5ccb6ba..6d1f114 100644
--- a/work/work-runtime/api/restricted_current.txt
+++ b/work/work-runtime/api/restricted_current.txt
@@ -29,7 +29,9 @@
     method public androidx.work.RunnableScheduler getRunnableScheduler();
     method public androidx.core.util.Consumer<java.lang.Throwable>? getSchedulingExceptionHandler();
     method public java.util.concurrent.Executor getTaskExecutor();
+    method public androidx.core.util.Consumer<androidx.work.WorkerExceptionInfo>? getWorkerExecutionExceptionHandler();
     method public androidx.work.WorkerFactory getWorkerFactory();
+    method public androidx.core.util.Consumer<androidx.work.WorkerExceptionInfo>? getWorkerInitializationExceptionHandler();
     property public final androidx.work.Clock clock;
     property public final int contentUriTriggerWorkersLimit;
     property public final String? defaultProcessName;
@@ -41,7 +43,9 @@
     property public final androidx.work.RunnableScheduler runnableScheduler;
     property public final androidx.core.util.Consumer<java.lang.Throwable>? schedulingExceptionHandler;
     property public final java.util.concurrent.Executor taskExecutor;
+    property public final androidx.core.util.Consumer<androidx.work.WorkerExceptionInfo>? workerExecutionExceptionHandler;
     property public final androidx.work.WorkerFactory workerFactory;
+    property public final androidx.core.util.Consumer<androidx.work.WorkerExceptionInfo>? workerInitializationExceptionHandler;
     field public static final androidx.work.Configuration.Companion Companion;
     field public static final int MIN_SCHEDULER_LIMIT = 20; // 0x14
   }
@@ -61,7 +65,9 @@
     method public androidx.work.Configuration.Builder setRunnableScheduler(androidx.work.RunnableScheduler runnableScheduler);
     method public androidx.work.Configuration.Builder setSchedulingExceptionHandler(androidx.core.util.Consumer<java.lang.Throwable> schedulingExceptionHandler);
     method public androidx.work.Configuration.Builder setTaskExecutor(java.util.concurrent.Executor taskExecutor);
+    method public androidx.work.Configuration.Builder setWorkerExecutionExceptionHandler(androidx.core.util.Consumer<androidx.work.WorkerExceptionInfo> workerExceptionHandler);
     method public androidx.work.Configuration.Builder setWorkerFactory(androidx.work.WorkerFactory workerFactory);
+    method public androidx.work.Configuration.Builder setWorkerInitializationExceptionHandler(androidx.core.util.Consumer<androidx.work.WorkerExceptionInfo> workerExceptionHandler);
   }
 
   public static final class Configuration.Companion {
@@ -590,6 +596,16 @@
     method public final com.google.common.util.concurrent.ListenableFuture<androidx.work.ListenableWorker.Result> startWork();
   }
 
+  public final class WorkerExceptionInfo {
+    ctor public WorkerExceptionInfo(String workerClassName, androidx.work.WorkerParameters workerParameters, Throwable throwable);
+    method public Throwable getThrowable();
+    method public String getWorkerClassName();
+    method public androidx.work.WorkerParameters getWorkerParameters();
+    property public final Throwable throwable;
+    property public final String workerClassName;
+    property public final androidx.work.WorkerParameters workerParameters;
+  }
+
   public abstract class WorkerFactory {
     ctor public WorkerFactory();
     method public abstract androidx.work.ListenableWorker? createWorker(android.content.Context appContext, String workerClassName, androidx.work.WorkerParameters workerParameters);
diff --git a/work/work-runtime/src/androidTest/java/androidx/work/DefaultWorkerFactoryTest.java b/work/work-runtime/src/androidTest/java/androidx/work/DefaultWorkerFactoryTest.java
index b587138..20c26d7 100644
--- a/work/work-runtime/src/androidTest/java/androidx/work/DefaultWorkerFactoryTest.java
+++ b/work/work-runtime/src/androidTest/java/androidx/work/DefaultWorkerFactoryTest.java
@@ -16,9 +16,10 @@
 
 package androidx.work;
 
+import static org.hamcrest.CoreMatchers.containsString;
+import static org.hamcrest.CoreMatchers.instanceOf;
 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 static org.mockito.Mockito.mock;
 
@@ -87,23 +88,29 @@
     public void testCreateWorker_throwsException() {
         OneTimeWorkRequest work = new OneTimeWorkRequest.Builder(TestWorker.class).build();
         insertWork(work);
-
         Executor executor = new SynchronousExecutor();
-        ListenableWorker worker = mDefaultWorkerFactory.createWorkerWithDefaultFallback(
-                mContext.getApplicationContext(),
-                DefaultWorkerFactoryTest.class.getName(),
-                new WorkerParameters(
-                        work.getId(),
-                        Data.EMPTY,
-                        work.getTags(),
-                        new WorkerParameters.RuntimeExtras(),
-                        1,
-                        0,
-                        executor,
-                        new WorkManagerTaskExecutor(executor),
-                        mDefaultWorkerFactory,
-                        mProgressUpdater,
-                        mForegroundUpdater));
-        assertThat(worker, is(nullValue()));
+        try {
+            mDefaultWorkerFactory.createWorkerWithDefaultFallback(
+                    mContext.getApplicationContext(),
+                    DefaultWorkerFactoryTest.class.getName(),
+                    new WorkerParameters(
+                            work.getId(),
+                            Data.EMPTY,
+                            work.getTags(),
+                            new WorkerParameters.RuntimeExtras(),
+                            1,
+                            0,
+                            executor,
+                            new WorkManagerTaskExecutor(executor),
+                            mDefaultWorkerFactory,
+                            mProgressUpdater,
+                            mForegroundUpdater));
+            throw new AssertionError("Expected to fail");
+        } catch (Throwable throwable) {
+            assertThat(throwable, is(instanceOf(ClassCastException.class)));
+            assertThat(throwable.getMessage(), containsString(
+                    "androidx.work.DefaultWorkerFactoryTest cannot be cast "
+                            + "to androidx.work.ListenableWorker"));
+        }
     }
 }
diff --git a/work/work-runtime/src/androidTest/java/androidx/work/impl/WorkerWrapperTest.java b/work/work-runtime/src/androidTest/java/androidx/work/impl/WorkerWrapperTest.java
index 3528171..122f140 100644
--- a/work/work-runtime/src/androidTest/java/androidx/work/impl/WorkerWrapperTest.java
+++ b/work/work-runtime/src/androidTest/java/androidx/work/impl/WorkerWrapperTest.java
@@ -26,6 +26,7 @@
 import static androidx.work.WorkInfo.State.SUCCEEDED;
 
 import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.CoreMatchers.instanceOf;
 import static org.hamcrest.CoreMatchers.is;
 import static org.hamcrest.CoreMatchers.notNullValue;
 import static org.hamcrest.MatcherAssert.assertThat;
@@ -46,6 +47,7 @@
 
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
+import androidx.core.util.Consumer;
 import androidx.test.core.app.ApplicationProvider;
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.LargeTest;
@@ -66,6 +68,8 @@
 import androidx.work.WorkInfo;
 import androidx.work.WorkRequest;
 import androidx.work.Worker;
+import androidx.work.WorkerExceptionInfo;
+import androidx.work.WorkerFactory;
 import androidx.work.WorkerParameters;
 import androidx.work.impl.foreground.ForegroundProcessor;
 import androidx.work.impl.model.Dependency;
@@ -79,6 +83,7 @@
 import androidx.work.impl.utils.taskexecutor.TaskExecutor;
 import androidx.work.worker.ChainedArgumentWorker;
 import androidx.work.worker.EchoingWorker;
+import androidx.work.worker.ExceptionInConstructionWorker;
 import androidx.work.worker.ExceptionWorker;
 import androidx.work.worker.FailureWorker;
 import androidx.work.worker.InterruptionAwareWorker;
@@ -96,6 +101,7 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
+import java.lang.reflect.InvocationTargetException;
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.List;
@@ -120,14 +126,18 @@
     private ForegroundUpdater mMockForegroundUpdater;
     private Executor mSynchronousExecutor = new SynchronousExecutor();
     private final ExecutorService mExecutorService = Executors.newSingleThreadExecutor();
+    private TestWorkerExceptionHandler mWorkerExceptionHandler;
 
     @Before
     public void setUp() {
         mContext = ApplicationProvider.getApplicationContext();
+        mWorkerExceptionHandler = new TestWorkerExceptionHandler();
         mConfiguration = new Configuration.Builder()
                 .setExecutor(new SynchronousExecutor())
                 .setMinimumLoggingLevel(Log.VERBOSE)
                 .setClock(mTestClock)
+                .setWorkerInitializationExceptionHandler(mWorkerExceptionHandler)
+                .setWorkerExecutionExceptionHandler(mWorkerExceptionHandler)
                 .build();
         mWorkTaskExecutor = new InstantWorkTaskExecutor();
         mWorkSpecDao = mDatabase.workSpecDao();
@@ -1181,16 +1191,87 @@
     @Test
     @SmallTest
     public void testWorkerThatThrowsAnException() {
-        OneTimeWorkRequest work =
-                new OneTimeWorkRequest.Builder(ExceptionWorker.class).build();
+        OneTimeWorkRequest work = new OneTimeWorkRequest.Builder(ExceptionWorker.class)
+                .setInputData(new Data.Builder().putString("foo", "bar").build()).build();
         insertWork(work);
         WorkerWrapper workerWrapper = createBuilder(work.getStringId()).build();
         FutureListener listener = createAndAddFutureListener(workerWrapper);
         workerWrapper.run();
         assertThat(listener.mResult, is(false));
         assertThat(mWorkSpecDao.getState(work.getStringId()), is(FAILED));
+        assertThat(mWorkerExceptionHandler.mWorkerClassName,
+                is("androidx.work.worker.ExceptionWorker"));
+        assertThat(mWorkerExceptionHandler.mWorkerParameters.getInputData().getString("foo"),
+                is("bar"));
+        assertThat(mWorkerExceptionHandler.mThrowable, instanceOf(IllegalStateException.class));
+        assertThat(mWorkerExceptionHandler.mThrowable.getMessage(), is(
+                "Thrown in doWork Exception"));
     }
 
+    @Test
+    @SmallTest
+    public void testWorkerThatThrowsAnExceptionInConstruction() {
+        OneTimeWorkRequest work =
+                new OneTimeWorkRequest.Builder(ExceptionInConstructionWorker.class)
+                .setInputData(new Data.Builder().putString("foo", "bar").build()).build();
+        insertWork(work);
+        WorkerWrapper workerWrapper = createBuilder(work.getStringId()).build();
+        FutureListener listener = createAndAddFutureListener(workerWrapper);
+        workerWrapper.run();
+        assertThat(listener.mResult, is(false));
+        assertThat(mWorkSpecDao.getState(work.getStringId()), is(FAILED));
+        assertThat(mWorkerExceptionHandler.mWorkerClassName,
+                is("androidx.work.worker.ExceptionInConstructionWorker"));
+        assertThat(mWorkerExceptionHandler.mWorkerParameters.getInputData().getString("foo"),
+                is("bar"));
+        assertThat(mWorkerExceptionHandler.mThrowable,
+                is(instanceOf(InvocationTargetException.class)));
+        Throwable e = ((InvocationTargetException) mWorkerExceptionHandler.mThrowable)
+                .getTargetException();
+        assertThat(e, instanceOf(IllegalStateException.class));
+        assertThat(e.getMessage(), is("Thrown in constructor Exception"));
+    }
+
+    @Test
+    @SmallTest
+    public void testExceptionInWorkerFactory() {
+        OneTimeWorkRequest work =
+                new OneTimeWorkRequest.Builder(TestWorker.class)
+                        .setInputData(new Data.Builder().putString("foo", "bar").build()).build();
+        insertWork(work);
+        WorkerFactory factory = new WorkerFactory() {
+            @Nullable
+            @Override
+            public ListenableWorker createWorker(@NonNull Context appContext,
+                    @NonNull String workerClassName, @NonNull WorkerParameters workerParameters) {
+                throw new IllegalStateException("Thrown in WorkerFactory Exception");
+            }
+        };
+        Configuration configuration = new Configuration.Builder(mConfiguration)
+                .setWorkerFactory(factory)
+                .build();
+        WorkerWrapper workerWrapper = new WorkerWrapper.Builder(
+                mContext,
+                configuration,
+                mWorkTaskExecutor,
+                mMockForegroundProcessor,
+                mDatabase,
+                mWorkSpecDao.getWorkSpec(work.getStringId()),
+                mDatabase.workTagDao().getWorkSpecIdsWithTag(work.getStringId())
+        ).build();
+        FutureListener listener = createAndAddFutureListener(workerWrapper);
+        workerWrapper.run();
+        assertThat(listener.mResult, is(false));
+        assertThat(mWorkSpecDao.getState(work.getStringId()), is(FAILED));
+        assertThat(mWorkerExceptionHandler.mWorkerClassName,
+                is("androidx.work.worker.TestWorker"));
+        assertThat(mWorkerExceptionHandler.mWorkerParameters.getInputData().getString("foo"),
+                is("bar"));
+        assertThat(mWorkerExceptionHandler.mThrowable,
+                is(instanceOf(IllegalStateException.class)));
+        assertThat(mWorkerExceptionHandler.mThrowable.getMessage(),
+                is("Thrown in WorkerFactory Exception"));
+    }
 
     @SuppressLint("NewApi")
     @Test
@@ -1328,4 +1409,17 @@
             }
         }
     }
+
+    private static class TestWorkerExceptionHandler implements Consumer<WorkerExceptionInfo> {
+        String mWorkerClassName;
+        WorkerParameters mWorkerParameters;
+        Throwable mThrowable;
+
+        @Override
+        public void accept(WorkerExceptionInfo params) {
+            this.mWorkerClassName = params.getWorkerClassName();
+            this.mWorkerParameters = params.getWorkerParameters();
+            this.mThrowable = params.getThrowable();
+        }
+    };
 }
diff --git a/work/work-runtime/src/androidTest/java/androidx/work/impl/testutils/TrackingWorkerFactory.kt b/work/work-runtime/src/androidTest/java/androidx/work/impl/testutils/TrackingWorkerFactory.kt
index ff18431..b63bdca2 100644
--- a/work/work-runtime/src/androidTest/java/androidx/work/impl/testutils/TrackingWorkerFactory.kt
+++ b/work/work-runtime/src/androidTest/java/androidx/work/impl/testutils/TrackingWorkerFactory.kt
@@ -46,7 +46,7 @@
             appContext,
             workerClassName,
             workerParameters
-        )!!.also {
+        ).also {
             createdWorkers.value = createdWorkers.value + (it.id to it)
         }
     }
diff --git a/work/work-runtime/src/androidTest/java/androidx/work/worker/ExceptionInConstructionWorker.kt b/work/work-runtime/src/androidTest/java/androidx/work/worker/ExceptionInConstructionWorker.kt
new file mode 100644
index 0000000..8bbe655
--- /dev/null
+++ b/work/work-runtime/src/androidTest/java/androidx/work/worker/ExceptionInConstructionWorker.kt
@@ -0,0 +1,32 @@
+/*
+ * 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.work.worker;
+
+import android.content.Context;
+import androidx.work.Worker;
+import androidx.work.WorkerParameters;
+
+class ExceptionInConstructionWorker(
+    context: Context,
+    workerParams: WorkerParameters
+) : Worker(context, workerParams) {
+    init {
+        throw IllegalStateException("Thrown in constructor Exception");
+    }
+
+    override fun doWork(): Result = Result.success()
+}
diff --git a/work/work-runtime/src/androidTest/java/androidx/work/worker/ExceptionWorker.java b/work/work-runtime/src/androidTest/java/androidx/work/worker/ExceptionWorker.java
index 72327f3..34271b0 100644
--- a/work/work-runtime/src/androidTest/java/androidx/work/worker/ExceptionWorker.java
+++ b/work/work-runtime/src/androidTest/java/androidx/work/worker/ExceptionWorker.java
@@ -30,6 +30,6 @@
 
     @Override
     public @NonNull Result doWork() {
-        throw new IllegalStateException();
+        throw new IllegalStateException("Thrown in doWork Exception");
     }
 }
diff --git a/work/work-runtime/src/main/java/androidx/work/Configuration.kt b/work/work-runtime/src/main/java/androidx/work/Configuration.kt
index 1ce09ea..ddcbc4d 100644
--- a/work/work-runtime/src/main/java/androidx/work/Configuration.kt
+++ b/work/work-runtime/src/main/java/androidx/work/Configuration.kt
@@ -83,6 +83,18 @@
     val schedulingExceptionHandler: Consumer<Throwable>?
 
     /**
+     * The exception handler that can be used to intercept exceptions
+     * caused when trying to initialize [ListenableWorker]s.
+     */
+    val workerInitializationExceptionHandler: Consumer<WorkerExceptionInfo>?
+
+    /**
+     * The exception handler that can be used to intercept exceptions
+     * caused when trying to execute [ListenableWorker]s.
+     */
+    val workerExecutionExceptionHandler: Consumer<WorkerExceptionInfo>?
+
+    /**
      * The [String] name of the process where work should be scheduled.
      */
     val defaultProcessName: String?
@@ -159,6 +171,8 @@
         }
         initializationExceptionHandler = builder.initializationExceptionHandler
         schedulingExceptionHandler = builder.schedulingExceptionHandler
+        workerInitializationExceptionHandler = builder.workerInitializationExceptionHandler
+        workerExecutionExceptionHandler = builder.workerExecutionExceptionHandler
         defaultProcessName = builder.defaultProcessName
         contentUriTriggerWorkersLimit = builder.contentUriTriggerWorkersLimit
     }
@@ -175,6 +189,8 @@
         internal var runnableScheduler: RunnableScheduler? = null
         internal var initializationExceptionHandler: Consumer<Throwable>? = null
         internal var schedulingExceptionHandler: Consumer<Throwable>? = null
+        internal var workerInitializationExceptionHandler: Consumer<WorkerExceptionInfo>? = null
+        internal var workerExecutionExceptionHandler: Consumer<WorkerExceptionInfo>? = null
         internal var defaultProcessName: String? = null
         internal var loggingLevel: Int = Log.INFO
         internal var minJobSchedulerId: Int = INITIAL_ID
@@ -209,6 +225,9 @@
             runnableScheduler = configuration.runnableScheduler
             initializationExceptionHandler = configuration.initializationExceptionHandler
             schedulingExceptionHandler = configuration.schedulingExceptionHandler
+            workerInitializationExceptionHandler =
+                    configuration.workerInitializationExceptionHandler
+            workerExecutionExceptionHandler = configuration.workerExecutionExceptionHandler
             defaultProcessName = configuration.defaultProcessName
         }
 
@@ -409,6 +428,40 @@
         }
 
         /**
+         * Specifies a `WorkerExceptionHandler` that can be used to intercept
+         * exceptions caused when trying to initialize [ListenableWorker]s.
+         *
+         * This exception handler will be invoked on a thread bound to
+         * [Configuration.taskExecutor].
+         *
+         * @param workerExceptionHandler an instance to handle exceptions
+         * @return This [Builder] instance
+         */
+        fun setWorkerInitializationExceptionHandler(
+            workerExceptionHandler: Consumer<WorkerExceptionInfo>
+        ): Builder {
+            this.workerInitializationExceptionHandler = workerExceptionHandler
+            return this
+        }
+
+        /**
+         * Specifies a `WorkerExceptionHandler` that can be used to intercept
+         * exceptions caused when trying to execute [ListenableWorker]s.
+         *
+         * This exception handler will be invoked on a thread bound to
+         * [Configuration.taskExecutor].
+         *
+         * @param workerExceptionHandler an instance to handle exceptions
+         * @return This [Builder] instance
+         */
+        fun setWorkerExecutionExceptionHandler(
+            workerExceptionHandler: Consumer<WorkerExceptionInfo>
+        ): Builder {
+            this.workerExecutionExceptionHandler = workerExceptionHandler
+            return this
+        }
+
+        /**
          * Designates the primary process that [WorkManager] should schedule work in.
          *
          * @param processName The [String] process name.
diff --git a/work/work-runtime/src/main/java/androidx/work/WorkerExceptionInfo.kt b/work/work-runtime/src/main/java/androidx/work/WorkerExceptionInfo.kt
new file mode 100644
index 0000000..d6d37d5
--- /dev/null
+++ b/work/work-runtime/src/main/java/androidx/work/WorkerExceptionInfo.kt
@@ -0,0 +1,37 @@
+/*
+ * 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.work
+
+/**
+ * Represents exceptions occurred from initializing or executing a [ListenableWorker].
+ */
+class WorkerExceptionInfo(
+    /**
+     * The class name of the worker
+     */
+    val workerClassName: String,
+
+    /**
+     * Parameters for worker initialization
+     */
+    val workerParameters: WorkerParameters,
+
+    /**
+     * The [Throwable] thrown while initializing or executing a [ListenableWorker]
+     */
+    val throwable: Throwable
+)
diff --git a/work/work-runtime/src/main/java/androidx/work/WorkerFactory.kt b/work/work-runtime/src/main/java/androidx/work/WorkerFactory.kt
index a4baed3..973e4fa 100644
--- a/work/work-runtime/src/main/java/androidx/work/WorkerFactory.kt
+++ b/work/work-runtime/src/main/java/androidx/work/WorkerFactory.kt
@@ -29,9 +29,9 @@
      * Override this method to implement your custom worker-creation logic.  Use
      * [Configuration.Builder.setWorkerFactory] to use your custom class.
      *
-     * Throwing an [Exception] here will crash the application. If a [WorkerFactory]
-     * is unable to create an instance of the [ListenableWorker], it should return `null` so
-     * it can delegate to the default [WorkerFactory].
+     * Throwing an [Exception] here and no [ListenableWorker] will be created. If a
+     * [WorkerFactory] is unable to create an instance of the [ListenableWorker], it should
+     * return `null` so it can delegate to the default [WorkerFactory].
      *
      * Returns a new instance of the specified `workerClassName` given the arguments.  The
      * returned worker must be a newly-created instance and must not have been previously returned
@@ -61,36 +61,41 @@
      * @param workerParameters Parameters for worker initialization
      * @return A new [ListenableWorker] instance of type `workerClassName`, or
      * `null` if the worker could not be created
-     * @throws IllegalStateException when the [WorkerFactory] returns an instance
-     * of the [ListenableWorker] which is used.
+     * @throws IllegalStateException when `workerClassName` cannot be instantiated or the
+     * [WorkerFactory] returns an instance of the [ListenableWorker] which is used.
      */
     @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
     fun createWorkerWithDefaultFallback(
         appContext: Context,
         workerClassName: String,
         workerParameters: WorkerParameters
-    ): ListenableWorker? {
-        var worker = createWorker(appContext, workerClassName, workerParameters)
-
-        if (worker == null) {
-            // Fallback to reflection
-            try {
+    ): ListenableWorker {
+        fun getWorkerClass(workerClassName: String): Class<out ListenableWorker> {
+            return try {
                 Class.forName(workerClassName).asSubclass(ListenableWorker::class.java)
             } catch (throwable: Throwable) {
                 Logger.get().error(TAG, "Invalid class: $workerClassName", throwable)
-                null
-            }?.let { clazz ->
-                try {
-                    val constructor = clazz.getDeclaredConstructor(
-                        Context::class.java, WorkerParameters::class.java
-                    )
-                    worker = constructor.newInstance(appContext, workerParameters)
-                } catch (e: Throwable) {
-                    Logger.get().error(TAG, "Could not instantiate $workerClassName", e)
-                }
+                throw throwable
             }
         }
-        if (worker?.isUsed == true) {
+        fun fallbackToReflection(
+            workerClassName: String,
+            workerParameters: WorkerParameters
+        ): ListenableWorker {
+            val clazz = getWorkerClass(workerClassName)
+            return try {
+                val constructor = clazz.getDeclaredConstructor(
+                    Context::class.java, WorkerParameters::class.java
+                )
+                constructor.newInstance(appContext, workerParameters)
+            } catch (e: Throwable) {
+                Logger.get().error(TAG, "Could not instantiate $workerClassName", e)
+                throw e
+            }
+        }
+        val worker = createWorker(appContext, workerClassName, workerParameters)
+                ?: fallbackToReflection(workerClassName, workerParameters)
+        if (worker.isUsed) {
             val message = "WorkerFactory (${javaClass.name}) returned an instance of" +
                 " a ListenableWorker ($workerClassName) which has already been invoked. " +
                 "createWorker() must always return a new instance of a ListenableWorker."
diff --git a/work/work-runtime/src/main/java/androidx/work/impl/WorkerWrapper.kt b/work/work-runtime/src/main/java/androidx/work/impl/WorkerWrapper.kt
index 7fe3201..daf7ab1 100644
--- a/work/work-runtime/src/main/java/androidx/work/impl/WorkerWrapper.kt
+++ b/work/work-runtime/src/main/java/androidx/work/impl/WorkerWrapper.kt
@@ -26,6 +26,7 @@
 import androidx.work.ListenableWorker
 import androidx.work.Logger
 import androidx.work.WorkInfo
+import androidx.work.WorkerExceptionInfo
 import androidx.work.WorkerParameters
 import androidx.work.impl.background.systemalarm.RescheduleReceiver
 import androidx.work.impl.foreground.ForegroundProcessor
@@ -175,28 +176,29 @@
 
         // Not always creating a worker here, as the WorkerWrapper.Builder can set a worker override
         // in test mode.
-        if (worker == null) {
-            worker = configuration.workerFactory.createWorkerWithDefaultFallback(
-                appContext,
-                workSpec.workerClassName,
-                params
-            )
-        }
         val worker = worker
-        if (worker == null) {
-            loge(TAG) { "Could not create Worker ${workSpec.workerClassName}" }
-            setFailedAndResolve()
-            return
-        }
-        if (worker.isUsed) {
-            loge(TAG) {
-                "Received an already-used Worker ${workSpec.workerClassName}; " +
-                    "Worker Factory should return new instances"
+            ?: try {
+                configuration.workerFactory.createWorkerWithDefaultFallback(
+                    appContext,
+                    workSpec.workerClassName,
+                    params
+                )
+            } catch (e: Throwable) {
+                loge(TAG) { "Could not create Worker ${workSpec.workerClassName}" }
+                try {
+                    configuration.workerInitializationExceptionHandler?.accept(
+                        WorkerExceptionInfo(workSpec.workerClassName, params, e)
+                    )
+                } catch (exception: Exception) {
+                    loge(TAG, exception) {
+                        "Exception handler threw an exception"
+                    }
+                }
+                setFailedAndResolve()
+                return
             }
-            setFailedAndResolve()
-            return
-        }
         worker.setUsed()
+        this.worker = worker
 
         // Try to set the work to the running state.  Note that this may fail because another thread
         // may have modified the DB since we checked last at the top of this function.
@@ -251,17 +253,43 @@
                         logd(TAG) { "${workSpec.workerClassName} returned a $result." }
                         this.result = result
                     }
-                } catch (exception: CancellationException) {
-                    // Cancellations need to be treated with care here because innerFuture
-                    // cancellations will bubble up, and we need to gracefully handle that.
-                    logi(TAG, exception) { "$workDescription was cancelled" }
                 } catch (exception: InterruptedException) {
                     loge(TAG, exception) {
                         "$workDescription failed because it threw an exception/error"
                     }
-                } catch (exception: ExecutionException) {
-                    loge(TAG, exception) {
-                        "$workDescription failed because it threw an exception/error"
+                    try {
+                        configuration.workerExecutionExceptionHandler?.accept(
+                            WorkerExceptionInfo(workSpec.workerClassName, params, exception))
+                    } catch (exception: Exception) {
+                        loge(TAG, exception) {
+                            "Exception handler threw an exception"
+                        }
+                    }
+                } catch (exception: Exception) {
+                    when (exception) {
+                        is CancellationException -> {
+                            // Cancellations need to be treated with care here because innerFuture
+                            // cancellations will bubble up, and we need to gracefully handle that.
+                            logi(TAG, exception) { "$workDescription was cancelled" }
+                        }
+                        is ExecutionException -> {
+                            loge(TAG, exception) {
+                                "$workDescription failed because it threw an exception/error"
+                            }
+                        }
+                    }
+                    try {
+                        configuration.workerExecutionExceptionHandler?.accept(
+                            WorkerExceptionInfo(
+                                workSpec.workerClassName,
+                                params,
+                                exception.cause ?: exception
+                            )
+                        )
+                    } catch (exception: Exception) {
+                        loge(TAG, exception) {
+                            "Exception handler threw an exception"
+                        }
                     }
                 } finally {
                     onWorkFinished()
diff --git a/work/work-runtime/src/main/java/androidx/work/impl/workers/ConstraintTrackingWorker.kt b/work/work-runtime/src/main/java/androidx/work/impl/workers/ConstraintTrackingWorker.kt
index 6442e325..6cbc12d 100644
--- a/work/work-runtime/src/main/java/androidx/work/impl/workers/ConstraintTrackingWorker.kt
+++ b/work/work-runtime/src/main/java/androidx/work/impl/workers/ConstraintTrackingWorker.kt
@@ -23,6 +23,7 @@
 import androidx.work.Logger
 import androidx.work.WorkInfo.Companion.STOP_REASON_NOT_STOPPED
 import androidx.work.WorkInfo.Companion.STOP_REASON_UNKNOWN
+import androidx.work.WorkerExceptionInfo
 import androidx.work.WorkerParameters
 import androidx.work.await
 import androidx.work.impl.WorkManagerImpl
@@ -73,11 +74,21 @@
             return Result.retry()
         }
         logd(TAG) { "Constraints met for delegate $className" }
-        val delegate = workerFactory.createWorkerWithDefaultFallback(
-            applicationContext, className, workerParameters
-        )
-        if (delegate == null) {
+        val delegate = try {
+            workerFactory.createWorkerWithDefaultFallback(
+                applicationContext, className, workerParameters
+            )
+        } catch (e: Throwable) {
             logd(TAG) { "No worker to delegate to." }
+            try {
+                workManagerImpl.configuration.workerInitializationExceptionHandler?.accept(
+                    WorkerExceptionInfo(className, workerParameters, e)
+                )
+            } catch (exception: Exception) {
+                loge(TAG, exception) {
+                    "Exception handler threw an exception"
+                }
+            }
             return Result.failure()
         }
         val mainThreadExecutor = workerParameters.taskExecutor.mainThreadExecutor
diff --git a/work/work-testing/src/main/java/androidx/work/testing/TestListenableWorkerBuilder.java b/work/work-testing/src/main/java/androidx/work/testing/TestListenableWorkerBuilder.java
index 2e8cb04..8a65620 100644
--- a/work/work-testing/src/main/java/androidx/work/testing/TestListenableWorkerBuilder.java
+++ b/work/work-testing/src/main/java/androidx/work/testing/TestListenableWorkerBuilder.java
@@ -334,11 +334,6 @@
                         getWorkerName(),
                         parameters);
 
-        if (worker == null) {
-            throw new IllegalStateException(
-                    "Could not create an instance of ListenableWorker " + getWorkerName());
-        }
-
         // This won't do much for the case of the from(Context, WorkRequest) as we lose the
         // type. However when using from(Class<W>) it will do the right thing. The benefits
         // also carry over to Kotlin extensions.